package com.fasterxml.jackson.databind.introspect;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;

/**
 * Unit tests verifying handling of potential and actual
 * conflicts, regarding property handling.
 */
public class TestPropertyConflicts extends BaseMapTest
{
    // For [JACKSON-694]: error message for conflicting getters sub-optimal
    static class BeanWithConflict
    {
        public int getX() { return 3; }
        public boolean getx() { return false; }
    }

    // [Issue#238]
    protected static class Getters1A
    {
        protected int value = 3;
        
        public int getValue() { return value+1; }
        public boolean isValue() { return false; }
    }

    // variant where order of declarations is reversed; to try to
    // ensure declaration order won't break things
    protected static class Getters1B
    {
        public boolean isValue() { return false; }

        protected int value = 3;
        
        public int getValue() { return value+1; }
    }

    /*
    /**********************************************************
    /* Test methods
    /**********************************************************
     */
    
    // for [JACKSON-694]
    public void testFailWithDupProps() throws Exception
    {
        BeanWithConflict bean = new BeanWithConflict();
        try {
            String json = objectWriter().writeValueAsString(bean);
            fail("Should have failed due to conflicting accessor definitions; got JSON = "+json);
        } catch (JsonProcessingException e) {
            verifyException(e, "Conflicting getter definitions");
        }
    }        

    // [Issue#238]: ok to have getter, "isGetter"
    public void testRegularAndIsGetter() throws Exception
    {
        final ObjectWriter writer = objectWriter();
        
        // first, serialize without probs:
        assertEquals("{\"value\":4}", writer.writeValueAsString(new Getters1A()));
        assertEquals("{\"value\":4}", writer.writeValueAsString(new Getters1B()));

        // and similarly, deserialize
        ObjectMapper mapper = objectMapper();
        assertEquals(1, mapper.readValue("{\"value\":1}", Getters1A.class).value);
        assertEquals(2, mapper.readValue("{\"value\":2}", Getters1B.class).value);
    }
}

@@ -1041,24 +1041,729 @@
 1; %7D%0A    %7D%0A%0A
+    protected static class InferingIntrospector extends JacksonAnnotationIntrospector%0A    %7B%0A        private static final long serialVersionUID = 1L;%0A%0A        @Override%0A        public String findImplicitPropertyName(AnnotatedMember member) %7B%0A            String name = member.getName();%0A            if (name.startsWith(%22_%22)) %7B%0A                return name.substring(1);%0A            %7D%0A            return null;%0A        %7D%0A    %7D%0A%0A    static class Infernal %7B%0A        public String _name() %7B return %22foo%22; %7D%0A        public String getName() %7B return %22Bob%22; %7D%0A%0A        public void setStuff() %7B ; // ok%0A        %7D%0A%0A        public void _stuff() %7B%0A            throw new UnsupportedOperationException();%0A        %7D%0A    %7D%0A%0A
     /*%0A    /
@@ -3017,11 +3017,667 @@
 );%0A    %7D
+%0A%0A    public void testInferredNameConflictsWithGetters() throws Exception%0A    %7B%0A        ObjectMapper mapper = new ObjectMapper();%0A        mapper.setAnnotationIntrospector(new InferingIntrospector());%0A        String json = mapper.writeValueAsString(new Infernal());%0A        assertEquals(aposToQuotes(%22%7B'name':'Bob'%7D%22), json);%0A    %7D%0A    %0A    public void testInferredNameConflictsWithSetters() throws Exception%0A    %7B%0A        ObjectMapper mapper = new ObjectMapper();%0A        mapper.setAnnotationIntrospector(new InferingIntrospector());%0A        Infernal inf = mapper.readValue(aposToQuotes(%22%7B'name':'Bob'%7D%22), Infernal.class);%0A        assertNotNull(inf);%0A    %7D
 %0A%7D%0A

add a unit test for inferred/implied names