package org.joda.pa;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;

import java.lang.reflect.Method;

/**
 * Tests the class {@link FieldMetaProperty}.
 */
public class MethodMetaPropertyTest extends
        AbstractFieldNameBasedMetaPropertyTest {

    @Override
    protected <P> MetaProperty<P> createMetaProperty(
            MetaBean metaBean, String name, Class<P> typeToken,
            boolean derived, boolean buildable,
            boolean readable, boolean mutable,
            String fieldName)
            throws Exception {

        MetaBean notNullMetaBean = metaBean;
        if (notNullMetaBean == null) {
            notNullMetaBean = mock(MetaBean.class);
            doReturn(TestBean.class).when(notNullMetaBean).beanType();
        }

        Method getValue = createGetMethod(readable, fieldName);
        Method setValue = createSetMethod(mutable, fieldName, typeToken);

        return new MethodMetaProperty<>(
                notNullMetaBean, name, typeToken,
                derived, buildable,
                getValue, setValue);
    }

    private static Method createGetMethod(boolean readable, String fieldName)
            throws NoSuchMethodException {
        if (!readable) {
            return null;
        }

        String getValueName = createMethodName("get", fieldName);
        return FieldBackedTestBean.class.getMethod(getValueName);
    }

    private static <T> Method createSetMethod(
            boolean mutable, String fieldName, Class<T> valueClass)
            throws NoSuchMethodException {

        if (!mutable) {
            return null;
        }

        String setValueName = createMethodName("set", fieldName);
        return FieldBackedTestBean.class.getMethod(setValueName, valueClass);
    }

    private static String createMethodName(String prefix, String fieldName) {
        return prefix
                + fieldName.substring(0, 1).toUpperCase()
                + fieldName.substring(1);
    }

}

@@ -103,40 +103,281 @@
 ck;%0A
-%0Aimport java.lang.reflect.Method
+import static org.testng.Assert.assertEquals;%0A%0Aimport java.lang.annotation.Annotation;%0Aimport java.lang.reflect.Method;%0Aimport java.util.stream.Stream;%0A%0Aimport org.joda.pa.TestBean.GetAnnotation;%0Aimport org.joda.pa.TestBean.SetAnnotation;%0Aimport org.testng.annotations.Test
 ;%0A%0A/
@@ -429,16 +429,45 @@
 y%7D.%0A */%0A
+@SuppressWarnings(%22javadoc%22)%0A
 public c
@@ -548,24 +548,953 @@
 ertyTest %7B%0A%0A
+    @Test%0A    public final void annotations_propertyWithTwoAnnotations_reportsAnnotations()%0A            throws Exception %7B%0A        MetaProperty%3C?%3E annotatedMetaProperty = createIntegerMetaProperty();%0A%0A        Stream%3CAnnotation%3E annotations = annotatedMetaProperty.annotations();%0A%0A        // report exactly two annotations%0A        assertEquals(annotations.count(), 2);%0A%0A        // report annotations of the correct type%0A        long annotationsOnGet = annotatedMetaProperty%0A                .annotations()%0A                .filter(GetAnnotation.class::isInstance)%0A                .count();%0A        assertEquals(annotationsOnGet, 1);%0A        long annotationsOnSet = annotatedMetaProperty%0A                .annotations()%0A                .filter(SetAnnotation.class::isInstance)%0A                .count();%0A        assertEquals(annotationsOnSet, 1);%0A    %7D%0A%0A    // implementation of 'AbstractFieldNameBasedMetaPropertyTest' -------------%0A%0A
     @Overrid

Add test for 'MethodMetaProperty.annotations()'