package com.codeminer42.dismantle;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static java.lang.Double.parseDouble;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;

public class ModelTest {

    class ModelExample extends Model {

        public String birthdate;
        public Double distance;
        public String content;
        public Boolean smoker;

        public ModelExample() {
            super();
        }

        public ModelExample(Map<String, Object> rep) {
            super(rep);
        }

        @Override
        public Map<String, String> externalRepresentationKeyPaths() {
            Map<String, String> extRep = new HashMap<String, String>();
            extRep.put("birthdate", "birth_date");
            extRep.put("distance", "distance");
            extRep.put("content", "CONTENT");
            extRep.put("smoker", "user.smoker");
            return extRep;
        }

        private Object transformToBirthdate(Object obj) {
            return obj;
        }

        private Object transformToSmoker(Object obj) {
            return obj;
        }

        private Object transformToDistance(Object obj) {
            try {
                return parseDouble((String) obj);
            } catch(Exception e) {
            }
            return null;
        }

        private Object transformFromDistance(Object obj) {
            if (obj != null) {
                return obj.toString();
            }
            return null;
        }

    }

    @Test
    public void testPropertiesWithTransformMethods() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("birth_date", "2002");
        map.put("distance", "2000.0");
        ModelExample example = new ModelExample(map);
        assertThat(example.distance, is(2000.0));
        assertThat(example.birthdate, is("2002"));
    }

    @Test
    public void testPropertiesWithoutTransformMethods() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("CONTENT", "Codeminer 42");
        ModelExample example = new ModelExample(map);
        assertThat(example.content, is("Codeminer 42"));
        assertThat(example.distance, nullValue());
        assertThat(example.birthdate, nullValue());
    }

    @Test
    public void testNestedProperty() {
        Map<String, Object> map = new HashMap<String, Object>();
        Map<String, Object> nestedMap = new HashMap<String, Object>();
        nestedMap.put("smoker", true);
        map.put("user", nestedMap);

        ModelExample example = new ModelExample(map);
        assertThat(example.smoker, is(true));
    }

    @Test
    public void testExternalRepresentationWithCompleteExample() {
        ModelExample example = new ModelExample();
        example.birthdate = "2002";
        example.distance = 200.9;
        example.content = "Codeminer 42";

        Map<String, Object> rep = example.externalRepresentation();

        assertThat((String) rep.get("birth_date"), is("2002"));
        assertThat((String) rep.get("distance"), is("200.9"));
        assertThat((String) rep.get("CONTENT"), is("Codeminer 42"));
    }

    @Test
    public void testExternalRepresentationWithIncompleteExample() {
        ModelExample example = new ModelExample();
        example.birthdate = "2002";

        Map<String, Object> rep = example.externalRepresentation();

        assertThat((String) rep.get("birth_date"), is("2002"));
        assertThat((Double) rep.get("distance"), nullValue());
        assertThat((String) rep.get("CONTENT"), nullValue());
    }
}

@@ -230,39 +230,567 @@
 sert
-That;%0A%0Apublic class ModelTest %7B
+Equals;%0Aimport static org.junit.Assert.assertThat;%0A%0Apublic class ModelTest %7B%0A%0A    class AddressExample extends Model %7B%0A%0A        public String zipcode;%0A%0A        public  AddressExample() %7B%0A            super();%0A        %7D%0A%0A        public AddressExample(Map%3CString, Object%3E rep) %7B%0A            super(rep);%0A        %7D%0A%0A        @Override%0A        public Map%3CString, String%3E externalRepresentationKeyPaths() %7B%0A            Map%3CString, String%3E extRep = new HashMap%3CString, String%3E();%0A            extRep.put(%22zipcode%22, %22zipcode%22);%0A            return extRep;%0A        %7D%0A    %7D
 %0A%0A  
@@ -953,16 +953,55 @@
  smoker;
+%0A        public AddressExample address;
 %0A%0A      
@@ -1498,24 +1498,70 @@
 r.smoker%22);%0A
+            extRep.put(%22address%22, %22address%22);%0A
             
@@ -2154,24 +2154,202 @@
 %0A        %7D%0A%0A
+        private  Object transformToAddress(Object obj) %7B%0A            AddressExample address = new AddressExample((Map%3CString, Object%3E)obj);%0A            return address;%0A        %7D%0A
     %7D%0A%0A    @
@@ -4420,11 +4420,478 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void testTransformToAnotherObject() %7B%0A        Map%3CString, Object%3E map = new HashMap%3CString, Object%3E();%0A        Map%3CString, Object%3E nestedMap = new HashMap%3CString, Object%3E();%0A        nestedMap.put(%22zipcode%22, %2212345%22);%0A        map.put(%22address%22, nestedMap);%0A%0A        ModelExample example = new ModelExample(map);%0A%0A        assertThat(example.address, instanceOf(AddressExample.class));%0A        assertEquals(example.address.zipcode, %2212345%22);%0A    %7D
 %0A%7D%0A

Add a test to create a dismantle instance from a node