/*
 * Copyright 2015, Yahoo Inc.
 * Copyrights licensed under the Apache 2.0 License.
 * See the accompanying LICENSE file for terms.
 */
package com.yahoo.squidb.data;

import android.content.ContentValues;

import com.yahoo.squidb.sql.Criterion;
import com.yahoo.squidb.sql.Property;
import com.yahoo.squidb.test.DatabaseTestCase;
import com.yahoo.squidb.test.TestModel;

public class ModelTest extends DatabaseTestCase {

    public void testBasicModelFunctions() {
        TestModel model = new TestModel();

        assertFalse(model.isSaved());
        assertFalse(model.isModified());

        model.setFirstName("Sam");
        model.setLastName("Bosley");

        assertEquals("Sam", model.getFirstName());
        assertEquals("Bosley", model.getLastName());
        assertTrue(model.isModified());

        dao.persist(model);
        assertTrue(model.isSaved());
        assertFalse(model.isModified());
    }

    public void testAddedModelMethods() {
        TestModel model = new TestModel();

        model.setFirstName("Sam");
        model.setLastName("Bosley");

        assertEquals("Sam Bosley", model.getDisplayName());
        assertEquals("Mr. Sam Bosley", model.prefixedName("Mr."));
    }

    public void testClone() {
        TestModel model = new TestModel();
        model.setFirstName("Sam");
        TestModel clone = model.clone();

        assertTrue(model != clone);
        assertEquals(clone, model);
        assertEquals("Sam", clone.getFirstName());
    }

    public void testCrudMethods() {
        // insert
        TestModel model = insertBasicTestModel("Sam", "Bosley", testDate);
        assertEquals(1, dao.count(TestModel.class, Criterion.all));

        // query
        final long id = model.getId();
        TestModel fetched = dao.fetch(TestModel.class, id, TestModel.PROPERTIES);
        assertNotNull(fetched);

        // update
        model.setFirstName("Jack").setLastName("Sparrow").setBirthday(System.currentTimeMillis());
        assertTrue(dao.saveExisting(model));
        assertEquals(1, dao.count(TestModel.class, Criterion.all));

        // delete
        assertTrue(dao.delete(TestModel.class, id));
        assertEquals(0, dao.count(TestModel.class, Criterion.all));
    }

    public void testDeprecatedPropertiesNotIncluded() {
        for (Property<?> property : TestModel.PROPERTIES) {
            if (TestModel.SOME_DEPRECATED_LONG.equals(property)) {
                fail("The PROPERTIES array contained a deprecated property");
            }
        }
    }

    public void testTypesafeReadFromContentValues() {
        final ContentValues values = new ContentValues();
        values.put(TestModel.FIRST_NAME.getName(), "A");
        values.put(TestModel.LAST_NAME.getName(), "B");
        values.put(TestModel.BIRTHDAY.getName(), 1); // Putting an int where long expected
        values.put(TestModel.IS_HAPPY.getName(), 1); // Putting an int where boolean expected
        values.put(TestModel.SOME_DOUBLE.getName(), 1); // Putting an int where double expected

        TestModel fromValues = new TestModel(values);
        assertEquals("A", fromValues.getFirstName());
        assertEquals("B", fromValues.getLastName());
        assertEquals(1L, fromValues.getBirthday().longValue());
        assertTrue(fromValues.isHappy());
        assertEquals(1.0, fromValues.getSomeDouble());

        values.put(TestModel.IS_HAPPY.getName(), "ABC");
        testThrowsException(new Runnable() {
            @Override
            public void run() {
                new TestModel(values);
            }
        }, ClassCastException.class);
    }

    public void testValueCoercionAppliesToAllValues() {
        // Make sure the model is initialized with values and setValues
        ContentValues values = new ContentValues();
        values.put(TestModel.FIRST_NAME.getName(), "A");
        TestModel model = new TestModel();
        model.readPropertiesFromContentValues(values, TestModel.FIRST_NAME);
        model.setFirstName("B");

        model.getDefaultValues().put(TestModel.IS_HAPPY.getName(), 1);
        assertTrue(model.isHappy()); // Test default values
        model.getDatabaseValues().put(TestModel.IS_HAPPY.getName(), 0);
        assertFalse(model.isHappy()); // Test database values
        model.getSetValues().put(TestModel.IS_HAPPY.getName(), 1);
        assertTrue(model.isHappy()); // Test set values

        model.getDefaultValues().put(TestModel.IS_HAPPY.getName(), true); // Reset the static variable
    }
}

@@ -3033,16 +3033,111 @@
 expected
+%0A        values.put(TestModel.$_123_ABC.getName(), %221%22); // Putting a String where int expected
 %0A%0A      
@@ -3447,24 +3447,85 @@
 meDouble());
+%0A        assertEquals(1, fromValues.get$123abc().intValue());
 %0A%0A        va
@@ -3666,24 +3666,24 @@
 oid run() %7B%0A
-
             
@@ -3760,32 +3760,1399 @@
 .class);%0A    %7D%0A%0A
+    public void testTypesafeSetFromContentValues() %7B%0A        final ContentValues values = new ContentValues();%0A        values.put(TestModel.FIRST_NAME.getName(), %22A%22);%0A        values.put(TestModel.LAST_NAME.getName(), %22B%22);%0A        values.put(TestModel.BIRTHDAY.getName(), 1); // Putting an int where long expected%0A        values.put(TestModel.IS_HAPPY.getName(), 1); // Putting an int where boolean expected%0A        values.put(TestModel.SOME_DOUBLE.getName(), 1); // Putting an int where double expected%0A        values.put(TestModel.$_123_ABC.getName(), %221%22); // Putting a String where int expected%0A%0A        TestModel fromValues = new TestModel();%0A        fromValues.setPropertiesFromContentValues(values, TestModel.PROPERTIES);%0A        assertEquals(%22A%22, fromValues.getFirstName());%0A        assertEquals(%22B%22, fromValues.getLastName());%0A        assertEquals(1L, fromValues.getBirthday().longValue());%0A        assertTrue(fromValues.isHappy());%0A        assertEquals(1.0, fromValues.getSomeDouble());%0A        assertEquals(1, fromValues.get$123abc().intValue());%0A%0A        values.put(TestModel.IS_HAPPY.getName(), %22ABC%22);%0A        testThrowsException(new Runnable() %7B%0A            @Override%0A            public void run() %7B%0A                new TestModel().setPropertiesFromContentValues(values, TestModel.IS_HAPPY);%0A            %7D%0A        %7D, ClassCastException.class);%0A    %7D%0A%0A
     public void 

Add a unit test for setPropertiesFromContentValues