package com.fasterxml.jackson.failing;

import com.fasterxml.jackson.databind.BaseMapTest;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Tests Scala-style JVM naming patterns for properties.
 *
 * Scala uses identifiers that are legal JVM names, but not legal Java names:
 *
 * <ul>
 *     <li><code>prop␣</code> (trailing space) for fields</li>
 *     <li><code>prop</code> for getters</li>
 *     <li><code>prop_=</code> for setters</li>
 * </ul>
 *
 * Scala sources turn property accesses into method calls in most cases; the
 * backing field and the particulars of the method names are implementation details.
 *
 * Since I can't reproduce them in Java, I've substituted legal but uncommonly
 * used characters as placeholders.
 */
public class TestScalaLikeImplicitProperties extends BaseMapTest
{
    static class ValProperty
    {
        public final String prop‿;
        public String prop() { return prop‿; }

        public ValProperty(String prop) {
            prop‿ = prop;
        }
    }

    static class VarProperty
    {
        public String prop‿;
        public String prop() { return prop‿; }
        public void prop_⁀(String p) { prop‿ = p; }

        public VarProperty(String prop) {
            prop‿ = prop;
        }
    }

    static class GetterSetterProperty
    {
        // Different name to represent an arbitrary implementation, not necessarily local to this class.
        private String _prop_impl = "get/set";
        public String prop() { return _prop_impl; }
        public void prop_⁀(String p) { _prop_impl = p; }

        // Getter/Setters are typically not in the constructor because they are implemented
        // by the end user, not the compiler. They should be detected similar to 'bean-style'
        // getProp/setProp pairs.
    }


    public void testValProperty() throws Exception
    {
        ObjectMapper m = new ObjectMapper();

        // TODO: Activate whatever handler implements the property detection style

        assertEquals("{\"prop\":\"val\"}", m.writeValueAsString(new ValProperty("val")));
    }


    public void testVarProperty() throws Exception
    {
        ObjectMapper m = new ObjectMapper();

        // TODO: Activate whatever handler implements the property detection style

        assertEquals("{\"prop\":\"var\"}", m.writeValueAsString(new VarProperty("var")));
        VarProperty result = m.readValue("{\"prop\":\"read\"}", VarProperty.class);
        assertEquals("read", result.prop());
    }


    public void testGetterSetterProperty() throws Exception
    {
        ObjectMapper m = new ObjectMapper();

        // TODO: Activate whatever handler implements the property detection style

        assertEquals("{\"prop\":\"get/set\"}", m.writeValueAsString(new GetterSetterProperty()));
        GetterSetterProperty result = m.readValue("{\"prop\":\"read\"}", GetterSetterProperty.class);
        assertEquals("read", result.prop());
    }
}

@@ -1017,190 +1017,830 @@
  %7D%0A%0A
-    static class VarProperty%0A    %7B%0A        public String prop%E2%80%BF;%0A        public String prop() %7B return prop%E2%80%BF; %7D%0A        public void prop_%E2%81%80(String p) %7B prop%E2%80%BF = p; %7D%0A%0A        public Var
+%0A    static class ValWithBeanProperty%0A    %7B%0A        public final String prop%E2%80%BF;%0A        public String prop() %7B return prop%E2%80%BF; %7D%0A        public String getProp() %7B return prop%E2%80%BF; %7D%0A%0A        public ValWithBeanProperty(String prop) %7B%0A            prop%E2%80%BF = prop;%0A        %7D%0A    %7D%0A%0A%0A    static class VarProperty%0A    %7B%0A        public String prop%E2%80%BF;%0A        public String prop() %7B return prop%E2%80%BF; %7D%0A        public void prop_%E2%81%80(String p) %7B prop%E2%80%BF = p; %7D%0A%0A        public VarProperty(String prop) %7B%0A            prop%E2%80%BF = prop;%0A        %7D%0A    %7D%0A%0A%0A    static class VarWithBeanProperty%0A    %7B%0A        public String prop%E2%80%BF;%0A        public String prop() %7B return prop%E2%80%BF; %7D%0A        public void prop_%E2%81%80(String p) %7B prop%E2%80%BF = p; %7D%0A        public String getProp() %7B return prop%E2%80%BF; %7D%0A        public void setProp(String p) %7B prop%E2%80%BF = p; %7D%0A%0A        public VarWithBean
 Prop
@@ -2713,32 +2713,333 @@
 al%22)));%0A    %7D%0A%0A%0A
+    public void testValWithBeanProperty() throws Exception%0A    %7B%0A        ObjectMapper m = new ObjectMapper();%0A%0A        // TODO: Activate whatever handler implements the property detection style%0A%0A        assertEquals(%22%7B%5C%22prop%5C%22:%5C%22val%5C%22%7D%22, m.writeValueAsString(new ValWithBeanProperty(%22val%22)));%0A    %7D%0A%0A%0A
     public void 
@@ -3428,32 +3428,478 @@
 rop());%0A    %7D%0A%0A%0A
+    public void testVarWithBeanProperty() throws Exception%0A    %7B%0A        ObjectMapper m = new ObjectMapper();%0A%0A        // TODO: Activate whatever handler implements the property detection style%0A%0A        assertEquals(%22%7B%5C%22prop%5C%22:%5C%22var%5C%22%7D%22, m.writeValueAsString(new VarWithBeanProperty(%22var%22)));%0A        VarWithBeanProperty result = m.readValue(%22%7B%5C%22prop%5C%22:%5C%22read%5C%22%7D%22, VarWithBeanProperty.class);%0A        assertEquals(%22read%22, result.prop());%0A    %7D%0A%0A%0A
     public void 

Add BeanProperty accessors