package ma.glasnost.orika.test.community.issue131;

import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.test.MappingUtil;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class Issue131Test {

    private MapperFacade mapper;

    public static class A {
        private List<Long> content;

        public List<Long> getContent() {
            return content;
        }

        public void setContent(List<Long> content) {
            this.content = content;
        }
    }

    public interface TB<T> {
        Collection<T> getContent();

        void setContent(Collection<T> content);
    }

    public interface BStrings extends TB<String> {
    }

    public interface BLongs extends TB<Long> {
    }

    public static class ConcreteBStrings implements BStrings {
        private Collection<String> content;

        public Collection<String> getContent() {
            return content;
        }

        public void setContent(Collection<String> content) {
            this.content = content;
        }
    }

    public static class ConcreteBLongs implements BLongs {
        private Collection<Long> content;

        @Override
        public Collection<Long> getContent() {
            return content;
        }

        @Override
        public void setContent(Collection<Long> content) {
            this.content = content;
        }
    }

    @Before
    public void setup() {
        MapperFactory mapperFactory = MappingUtil.getMapperFactory();
        mapperFactory.classMap(A.class, TB.class).byDefault().register();
        mapperFactory.classMap(A.class, BStrings.class).byDefault().register();
        mapperFactory.classMap(A.class, BLongs.class).byDefault().register();
        mapperFactory.registerConcreteType(BStrings.class, ConcreteBStrings.class);
        mapperFactory.registerConcreteType(BLongs.class, ConcreteBLongs.class);

        mapper = mapperFactory.getMapperFacade();
    }

    @Test
    public void testCase() {
        A a = new A();
        a.setContent(Arrays.asList(1L, 2L, 3L));
        BLongs longs = mapper.map(a, BLongs.class);
        assertElementOfType(longs.getContent(), Long.class);

        BStrings strings = mapper.map(a, BStrings.class);
        assertElementOfType(strings.getContent(), String.class);

    }

    private static void assertElementOfType(Collection<?> collection, Class<?> expectedType) {
        for (Object e : collection) {
            Class<?> elementType = e.getClass();
            Assert.assertTrue("element '" + e + "' should be assignable to '" + expectedType + " but is of " + elementType,
                              expectedType.isAssignableFrom(elementType));
        }
    }
}

@@ -252,78 +252,465 @@
 ort 
-java.util.Arrays;%0Aimport java.util.Collection;%0Aimport java.util.List;%0A
+static org.hamcrest.MatcherAssert.assertThat;%0Aimport static org.hamcrest.Matchers.empty;%0Aimport static org.hamcrest.Matchers.is;%0Aimport static org.hamcrest.Matchers.not;%0A%0Aimport java.util.Arrays;%0Aimport java.util.Collection;%0Aimport java.util.List;%0A%0A/**%0A * Property types are not correctly resolved from generic interfaces.%0A * %3Cp%3E%0A * %0A * @see %3Ca href=%22https://github.com/orika-mapper/orika/issues/131%22%3Ehttps://github.com/orika-mapper/orika/issues%3C/a%3E%0A * %0A */
 %0Apub
@@ -2908,24 +2908,74 @@
 ctedType) %7B%0A
+        assertThat(collection, is(not(empty())));%0A
         for 

improve TestCase: add additional assertion and JavaDoc