// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.components.runtime.util;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.annotations.SimplePropertyCopier;
import com.google.appinventor.components.runtime.Component;
import com.google.appinventor.components.runtime.HandlesEventDispatching;
import com.google.common.testing.junit4.JUnitAsserts;
import junit.framework.TestCase;
/**
* @author markf@google.com (Mark Friedman)
*/
public class PropertyUtilTest extends TestCase {
public void testOneStringProperty() throws Throwable {
@SimpleObject
class TestClass implements Component {
private String prop1;
@SimpleProperty
public String Prop1() {
return prop1;
}
@SimpleProperty
public void Prop1(String prop1) {
this.prop1 = prop1;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop1("idontcare");
assertEquals("idontcare", sourceObj.Prop1());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
assertEquals(sourceObj.Prop1(), targetObj.Prop1());
}
public void testOneIntProperty() throws Throwable {
@SimpleObject
class TestClass implements Component {
private int prop1;
@SimpleProperty
public int Prop1() {
return prop1;
}
@SimpleProperty
public void Prop1(int prop1) {
this.prop1 = prop1;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop1(1234);
assertEquals(1234, sourceObj.Prop1());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
assertEquals(sourceObj.Prop1(), targetObj.Prop1());
}
public void testMultipleProperties() throws Throwable {
@SimpleObject
class TestClass implements Component {
private int prop1;
private String prop2;
@SimpleProperty
public int Prop1() {
return prop1;
}
@SimpleProperty
public void Prop1(int prop1) {
this.prop1 = prop1;
}
@SimpleProperty
public String Prop2() {
return prop2;
}
@SimpleProperty
public void Prop2(String prop2) {
this.prop2 = prop2;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop1(1234);
assertEquals(1234, sourceObj.Prop1());
sourceObj.Prop2("idontcare");
assertEquals("idontcare", sourceObj.Prop2());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
assertEquals(sourceObj.Prop1(), targetObj.Prop1());
assertEquals(sourceObj.Prop2(), targetObj.Prop2());
}
public void testOnlySimplePropertiesAreCopied() throws Throwable {
@SimpleObject
class TestClass implements Component {
private int prop;
private String nonProp;
@SimpleProperty
public int Prop() {
return prop;
}
@SimpleProperty
public void Prop(int prop) {
this.prop = prop;
}
public String NonProp() {
return nonProp;
}
public void NonProp(String nonProp) {
this.nonProp = nonProp;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop(1234);
assertEquals(1234, sourceObj.Prop());
sourceObj.NonProp("idontcare");
assertEquals("idontcare", sourceObj.NonProp());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
assertEquals(sourceObj.Prop(), targetObj.Prop());
JUnitAsserts.assertNotEqual(sourceObj.NonProp(), targetObj.NonProp());
}
public void testNoSetterDoesntCopy() throws Throwable {
@SimpleObject
class TestClass implements Component {
private int prop;
@SimpleProperty
public int Prop() {
return prop;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.prop = 1234;
assertEquals(1234, sourceObj.Prop());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
JUnitAsserts.assertNotEqual(sourceObj.Prop(), targetObj.Prop());
}
public void testSetterNotSimplePropertyDoesntCopy() throws Throwable {
@SimpleObject
class TestClass implements Component {
private int prop;
@SimpleProperty
public int Prop() {
return prop;
}
public void Prop(int prop) {
this.prop = prop;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop(1234);
assertEquals(1234, sourceObj.Prop());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
JUnitAsserts.assertNotEqual(sourceObj.Prop(), targetObj.Prop());
}
public void testNoGetterDoesntCopy() throws Throwable {
@SimpleObject
class TestClass implements Component {
public int prop;
@SimpleProperty
public void Prop(int prop) {
this.prop = prop;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop(1234);
assertEquals(1234, sourceObj.prop);
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
JUnitAsserts.assertNotEqual(sourceObj.prop, targetObj.prop);
}
public void testGetterNotSimplePropertyDoesntCopy() throws Throwable {
@SimpleObject
class TestClass implements Component {
private int prop;
public int Prop() {
return prop;
}
@SimpleProperty
public void Prop(int prop) {
this.prop = prop;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop(1234);
assertEquals(1234, sourceObj.Prop());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
JUnitAsserts.assertNotEqual(sourceObj.Prop(), targetObj.Prop());
}
public void testGetterSetterTypeMismatchDoesntCopy() throws Throwable {
@SimpleObject
class TestClass implements Component {
private int intProp;
private String stringProp;
@SimpleProperty
public int Prop() {
return intProp;
}
@SimpleProperty
public void Prop(String stringProp) {
this.stringProp = stringProp;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop("idontcare");
assertEquals("idontcare", sourceObj.stringProp);
sourceObj.intProp = 1234;
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
JUnitAsserts.assertNotEqual(sourceObj.Prop(), targetObj.Prop());
JUnitAsserts.assertNotEqual(sourceObj.intProp, targetObj.intProp);
}
public void testCopyMethod() throws Throwable {
@SimpleObject
class TestClass implements Component {
private String prop1;
@SimpleProperty
public String Prop1() {
return prop1;
}
@SimplePropertyCopier
public void CopyProp1(TestClass comp) {
prop1 = "foo";
}
@SimpleProperty
public void Prop1(String prop1) {
this.prop1 = prop1;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop1("idontcare");
assertEquals("idontcare", sourceObj.Prop1());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
assertEquals("foo", targetObj.Prop1());
}
public void testCopyMethodWithoutAnnotationUsesSetterAndGetter() throws Throwable {
@SimpleObject
class TestClass implements Component {
private String prop1;
@SimpleProperty
public String Prop1() {
return prop1;
}
public void CopyProp1(TestClass comp) {
prop1 = "foo";
}
@SimpleProperty
public void Prop1(String prop1) {
this.prop1 = prop1;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop1("idontcare");
assertEquals("idontcare", sourceObj.Prop1());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
assertEquals(sourceObj.Prop1(), targetObj.Prop1());
}
public void testOnePropertyWithCopyMethodAndManyPropertiesWithoutCopytMethod() throws Throwable {
// NOTE(lizlooney) - This test attempts to test whether having a copy method for one property
// prevents other properties from being copied.
// Since reflection provides the methods in no particular order, this test could pass if
// the order were such that the property with copy method was last. To make it more likely that
// that won't happen, there are nine properties here and the fifth one has a copy method.
@SimpleObject
class TestClass implements Component {
private String prop1;
private String prop2;
private String prop3;
private String prop4;
private String prop5;
private String prop6;
private String prop7;
private String prop8;
private String prop9;
@SimpleProperty
public String Prop1() {
return prop1;
}
@SimpleProperty
public void Prop1(String prop1) {
this.prop1 = prop1;
}
@SimpleProperty
public String Prop2() {
return prop2;
}
@SimpleProperty
public void Prop2(String prop2) {
this.prop2 = prop2;
}
@SimpleProperty
public String Prop3() {
return prop3;
}
@SimpleProperty
public void Prop3(String prop3) {
this.prop3 = prop3;
}
@SimpleProperty
public String Prop4() {
return prop4;
}
@SimpleProperty
public void Prop4(String prop4) {
this.prop4 = prop4;
}
@SimpleProperty
public String Prop5() {
return prop5;
}
@SimplePropertyCopier
public void CopyProp5(TestClass comp) {
prop5 = "foo";
}
@SimpleProperty
public void Prop5(String prop5) {
this.prop5 = prop5;
}
@SimpleProperty
public String Prop6() {
return prop6;
}
@SimpleProperty
public void Prop6(String prop6) {
this.prop6 = prop6;
}
@SimpleProperty
public String Prop7() {
return prop7;
}
@SimpleProperty
public void Prop7(String prop7) {
this.prop7 = prop7;
}
@SimpleProperty
public String Prop8() {
return prop8;
}
@SimpleProperty
public void Prop8(String prop8) {
this.prop8 = prop8;
}
@SimpleProperty
public String Prop9() {
return prop9;
}
@SimpleProperty
public void Prop9(String prop9) {
this.prop9 = prop9;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
TestClass sourceObj = new TestClass();
sourceObj.Prop1("idontcare1");
sourceObj.Prop2("idontcare2");
sourceObj.Prop3("idontcare3");
sourceObj.Prop4("idontcare4");
sourceObj.Prop5("idontcare5");
sourceObj.Prop6("idontcare6");
sourceObj.Prop7("idontcare7");
sourceObj.Prop8("idontcare8");
sourceObj.Prop9("idontcare9");
assertEquals("idontcare1", sourceObj.Prop1());
assertEquals("idontcare2", sourceObj.Prop2());
assertEquals("idontcare3", sourceObj.Prop3());
assertEquals("idontcare4", sourceObj.Prop4());
assertEquals("idontcare5", sourceObj.Prop5());
assertEquals("idontcare6", sourceObj.Prop6());
assertEquals("idontcare7", sourceObj.Prop7());
assertEquals("idontcare8", sourceObj.Prop8());
assertEquals("idontcare9", sourceObj.Prop9());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
assertEquals(sourceObj.Prop1(), targetObj.Prop1());
assertEquals(sourceObj.Prop2(), targetObj.Prop2());
assertEquals(sourceObj.Prop3(), targetObj.Prop3());
assertEquals(sourceObj.Prop4(), targetObj.Prop4());
assertEquals("foo", targetObj.Prop5());
assertEquals(sourceObj.Prop6(), targetObj.Prop6());
assertEquals(sourceObj.Prop7(), targetObj.Prop7());
assertEquals(sourceObj.Prop8(), targetObj.Prop8());
assertEquals(sourceObj.Prop9(), targetObj.Prop9());
}
public void testCopyMethodInSuperClass() throws Throwable {
// Tests the situation where the property getter, setter, and copy method, are declared in a
// superclass.
@SimpleObject
class SuperTestClass implements Component {
private String prop1;
@SimpleProperty
public String Prop1() {
return prop1;
}
@SimplePropertyCopier
public void CopyProp1(SuperTestClass comp) {
prop1 = "foo";
}
@SimpleProperty
public void Prop1(String prop1) {
this.prop1 = prop1;
}
@Override
public HandlesEventDispatching getDispatchDelegate() {
throw new UnsupportedOperationException();
}
}
@SimpleObject
class TestClass extends SuperTestClass {
}
TestClass sourceObj = new TestClass();
sourceObj.Prop1("idontcare");
assertEquals("idontcare", sourceObj.Prop1());
TestClass targetObj = new TestClass();
PropertyUtil.copyComponentProperties(sourceObj, targetObj);
assertEquals("foo", targetObj.Prop1());
}
}