UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

958 lines (771 loc) 26.4 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2007-2008 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Fabian Jakobs (fjakobs) ************************************************************************ */ /** * @ignore(qx.Node, qx.test.A, qx.test.B, qx.test.clName, qx.test.IForm) * @ignore(qx.TestProperty, qx.Super) */ qx.Class.define("qx.test.core.Property", { extend : qx.dev.unit.TestCase, members : { testBasic : function() { this.assertNotUndefined(qx.core.Property); // Check instance var inst = new qx.test.core.PropertyHelper; this.assertNotUndefined(inst, "instance"); // Public setter/getter etc. this.assertFunction(inst.setPublicProp, "public setter"); this.assertFunction(inst.getPublicProp, "public getter"); this.assertFunction(inst.resetPublicProp, "public reset"); this.assertUndefined(inst.togglePublicProp, "public toggler"); this.assertUndefined(inst.setThemedPublicProp, "public themed"); // Boolean property this.assertFunction(inst.toggleBooleanProp, "boolean toggler"); inst.dispose(); }, testBuiltinTypes : function() { this.assertNotUndefined(qx.core.Property); // Check instance var inst = new qx.test.core.PropertyHelper; this.assertNotUndefined(inst, "instance"); // Type checks: String this.assertIdentical("Hello", inst.setStringProp("Hello"), "string property, set"); this.assertIdentical("Hello", inst.getStringProp(), "string property, get"); // Type checks: Boolean, true this.assertIdentical(true, inst.setBooleanProp(true), "boolean property, set"); this.assertIdentical(true, inst.getBooleanProp(), "boolean property, get"); // Type checks: Boolean, false this.assertIdentical(false, inst.setBooleanProp(false), "boolean property, set"); this.assertIdentical(false, inst.getBooleanProp(), "boolean property, get"); // Type checks: Number, int this.assertIdentical(3, inst.setNumberProp(3), "number property, set"); this.assertIdentical(3, inst.getNumberProp(), "number property, get"); // Type checks: Number, float this.assertIdentical(3.14, inst.setNumberProp(3.14), "number property, set"); this.assertIdentical(3.14, inst.getNumberProp(), "number property, get"); // Type checks: Object, inline var obj = {}; this.assertIdentical(obj, inst.setObjectProp(obj), "object property, set"); this.assertIdentical(obj, inst.getObjectProp(), "object property, get"); // Type checks: Object, new var obj = new Object; this.assertIdentical(obj, inst.setObjectProp(obj), "object property, set"); this.assertIdentical(obj, inst.getObjectProp(), "object property, get"); // Type checks: Array, inline var arr = []; this.assertIdentical(arr, inst.setArrayProp(arr), "array property, set"); this.assertIdentical(arr, inst.getArrayProp(), "array property, get"); // Type checks: Array, new var arr = new Array; this.assertIdentical(arr, inst.setArrayProp(arr), "array property, set"); this.assertIdentical(arr, inst.getArrayProp(), "array property, get"); inst.dispose(); }, testInheritance : function() { this.assertNotUndefined(qx.core.Property); var pa = new qx.test.core.InheritanceDummy(); var ch1 = new qx.test.core.InheritanceDummy(); var ch2 = new qx.test.core.InheritanceDummy(); var ch3 = new qx.test.core.InheritanceDummy(); var chh1 = new qx.test.core.InheritanceDummy(); var chh2 = new qx.test.core.InheritanceDummy(); var chh3 = new qx.test.core.InheritanceDummy(); pa.add(ch1); pa.add(ch2); pa.add(ch3); ch2.add(chh1); ch2.add(chh2); ch2.add(chh3); // Simple: Only inheritance, no local values this.assertTrue(pa.setEnabled(true), "a1"); this.assertTrue(pa.getEnabled(), "a2"); this.assertTrue(ch1.getEnabled(), "a3"); this.assertTrue(ch2.getEnabled(), "a4"); this.assertTrue(ch3.getEnabled(), "a5"); this.assertTrue(chh1.getEnabled(), "a6"); this.assertTrue(chh2.getEnabled(), "a7"); this.assertTrue(chh3.getEnabled(), "a8"); // Enabling local value this.assertFalse(ch2.setEnabled(false), "b1"); this.assertFalse(ch2.getEnabled(), "b2"); this.assertFalse(chh1.getEnabled(), "b3"); this.assertFalse(chh2.getEnabled(), "b4"); this.assertFalse(chh3.getEnabled(), "b5"); // Reset local value ch2.resetEnabled(); this.assertTrue(ch2.getEnabled(), "c2"); this.assertTrue(chh1.getEnabled(), "c3"); this.assertTrue(chh2.getEnabled(), "c4"); this.assertTrue(chh3.getEnabled(), "c5"); pa.dispose(); ch1.dispose(); ch2.dispose(); ch3.dispose(); chh1.dispose(); chh2.dispose(); chh3.dispose(); }, testParent : function() { var pa = new qx.test.core.InheritanceDummy(); var ch1 = new qx.test.core.InheritanceDummy(); var ch2 = new qx.test.core.InheritanceDummy(); var ch3 = new qx.test.core.InheritanceDummy(); this.assertIdentical(pa.getEnabled(), null, "d1"); this.assertIdentical(ch1.getEnabled(), null, "d2"); this.assertIdentical(ch2.getEnabled(), null, "d3"); this.assertIdentical(ch3.getEnabled(), null, "d4"); pa.add(ch1); this.assertTrue(pa.setEnabled(true), "a1"); // ch1 gets enabled, too this.assertFalse(ch3.setEnabled(false), "a2"); this.assertTrue(pa.getEnabled(), "b1"); this.assertTrue(ch1.getEnabled(), "b2"); this.assertIdentical(ch2.getEnabled(), null, "b3"); this.assertFalse(ch3.getEnabled(), "b4"); pa.add(ch2); // make ch2 enabled_ through inheritance pa.add(ch3); // keep ch2 disabled, user value has higher priority this.assertTrue(pa.getEnabled(), "c1"); this.assertTrue(ch1.getEnabled(), "c2"); this.assertTrue(ch2.getEnabled(), "c3"); this.assertFalse(ch3.getEnabled(), "c4"); pa.dispose(); ch1.dispose(); ch2.dispose(); ch3.dispose(); }, testMultiValues : function() { this.assertNotUndefined(qx.core.Property); // Check instance var inst = new qx.test.core.PropertyHelper; this.assertNotUndefined(inst, "instance"); // Check init value this.assertIdentical(inst.getInitProp(), "foo", "a1"); this.assertIdentical(inst.setInitProp("hello"), "hello", "a2"); this.assertIdentical(inst.getInitProp(), "hello", "a3"); this.assertIdentical(inst.resetInitProp(), undefined, "a4"); this.assertIdentical(inst.getInitProp(), "foo", "a5"); // Check null value this.assertIdentical(inst.getNullProp(), "bar", "b1"); this.assertIdentical(inst.setNullProp("hello"), "hello", "b2"); this.assertIdentical(inst.getNullProp(), "hello", "b3"); this.assertIdentical(inst.setNullProp(null), null, "b4"); this.assertIdentical(inst.getNullProp(), null, "b5"); this.assertIdentical(inst.resetNullProp(), undefined, "b6"); this.assertIdentical(inst.getNullProp(), "bar", "b7"); // Check appearance value this.assertIdentical(inst.setThemedAppearanceProp("black"), "black", "c1"); this.assertIdentical(inst.getAppearanceProp(), "black", "c2"); this.assertIdentical(inst.setAppearanceProp("white"), "white", "c3"); this.assertIdentical(inst.getAppearanceProp(), "white", "c4"); this.assertIdentical(inst.resetAppearanceProp(), undefined, "c5"); this.assertIdentical(inst.getAppearanceProp(), "black", "c6"); // No prop this.assertIdentical(inst.getNoProp(), null, "c1"); inst.dispose(); }, testInitApply : function() { var inst = new qx.test.core.PropertyHelper; this.assertNotUndefined(inst, "instance"); this.assertUndefined(inst.lastApply); inst.setInitApplyProp1("juhu"); //set to init value this.assertJsonEquals(["juhu", "juhu"], inst.lastApply); inst.lastApply = undefined; inst.setInitApplyProp1("juhu"); // set to same value this.assertUndefined(inst.lastApply); // apply must not be called inst.lastApply = undefined; inst.setInitApplyProp1("kinners"); // set to new value this.assertJsonEquals(["kinners", "juhu"], inst.lastApply); inst.lastApply = undefined; this.assertUndefined(inst.lastApply); inst.setInitApplyProp2(null); //set to init value this.assertJsonEquals([null, null], inst.lastApply); inst.lastApply = undefined; inst.dispose(); }, testInit : function() { // now test the init functions var self = this; var inst = new qx.test.core.PropertyHelper(function(inst) { inst.initInitApplyProp1(); self.assertJsonEquals(["juhu", null], inst.lastApply); inst.lastApply = undefined; inst.initInitApplyProp2(); self.assertJsonEquals([null, null], inst.lastApply); inst.lastApply = undefined; }); this.assertNotUndefined(inst, "instance"); inst.dispose(); }, testDefinesThanSubClassWithInterface : function() { // see bug #2162 for details delete qx.test.A; delete qx.test.B; delete qx.test.IForm; qx.Class.define("qx.test.A", { extend : qx.core.Object, properties : { enabled : {} } }); var a = new qx.test.A(); qx.Interface.define("qx.test.IForm", { members : { setEnabled : function(value) {} } }); qx.Class.define("qx.test.B", { extend : qx.test.A, implement : qx.test.IForm }); var b = new qx.test.B(); b.setEnabled(true); a.dispose(); b.dispose(); }, testPropertyNamedClassname : function() { qx.Class.define("qx.test.clName", { extend : qx.core.Object, properties : { classname : {} } }); delete qx.test.clName; }, testWrongPropertyDefinitions : function() { if (qx.core.Environment.get("qx.debug")) { // date this.assertException(function() { qx.Class.define("qx.test.clName", { extend : qx.core.Object, properties : new Date() }); }, Error, new RegExp(".*Invalid.*"), "123"); delete qx.test.clName; // array this.assertException(function() { qx.Class.define("qx.test.clName", { extend : qx.core.Object, properties : [1,2,3] }); }, Error, new RegExp(".*Invalid.*"), "123"); delete qx.test.clName; // qooxdoo class var o = new qx.core.Object(); this.assertException(function() { qx.Class.define("qx.test.clName", { extend : qx.core.Object, properties : o }); }, Error, new RegExp(".*Invalid.*"), "123"); delete qx.test.clName; o.dispose(); // RegExp this.assertException(function() { qx.Class.define("qx.test.clName", { extend : qx.core.Object, properties : new RegExp() }); }, Error, new RegExp(".*Invalid.*"), "123"); delete qx.test.clName; // null this.assertException(function() { qx.Class.define("qx.test.clName", { extend : qx.core.Object, properties : null }); }, Error, new RegExp(".*Invalid.*"), "123"); delete qx.test.clName; // boolean this.assertException(function() { qx.Class.define("qx.test.clName", { extend : qx.core.Object, properties : true }); }, Error, new RegExp(".*Invalid.*"), "123"); delete qx.test.clName; // number this.assertException(function() { qx.Class.define("qx.test.clName", { extend : qx.core.Object, properties : 123 }); }, Error, new RegExp(".*Invalid.*"), "123"); delete qx.test.clName; } }, testRecursive : function() { qx.Class.define("qx.Node", { extend : qx.core.Object, construct : function() { this._min = 0; }, properties : { value : { apply : "applyValue" } }, members : { applyValue: function(value, old) { if (value < this._min) { this.setValue(this._min); } } } }); var root = new qx.Node(); root.setValue(100); this.assertEquals(100, root.getValue()); root.setValue(-100); this.assertEquals(0, root.getValue()); root.dispose(); }, testEventWithInitOldData: function() { qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Boolean", init : false, event : "changeProp" } } }); var object = new qx.TestProperty(); // test for the default (false) this.assertFalse(object.getProp()); // check for the event var self = this; this.assertEventFired(object, "changeProp", function () { object.setProp(true); }, function(e) { self.assertTrue(e.getData(), "Wrong data in the event!"); self.assertFalse(e.getOldData(), "Wrong old data in the event!"); }, "Change event not fired!"); object.dispose(); }, testEventWithoutInitOldData: function() { qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Boolean", nullable : true, event : "changeProp" } } }); var object = new qx.TestProperty(); // test for the default (false) this.assertNull(object.getProp()); // check for the event var self = this; this.assertEventFired(object, "changeProp", function () { object.setProp(true); }, function(e) { self.assertTrue(e.getData(), "Wrong data in the event!"); self.assertNull(e.getOldData(), "Wrong old data in the event!"); }, "Change event not fired!"); object.dispose(); }, testEventWithInitAndInheritableOldData: function() { qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Boolean", init : false, inheritable : true, event : "changeProp" } } }); var object = new qx.TestProperty(); // test for the default (false) this.assertFalse(object.getProp()); // check for the event var self = this; this.assertEventFired(object, "changeProp", function () { object.setProp(true); }, function(e) { self.assertTrue(e.getData(), "Wrong data in the event!"); self.assertFalse(e.getOldData(), "Wrong old data in the event!"); }, "Change event not fired!"); object.dispose(); }, testEventWithoutInitAndInheritableOldData: function() { qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Boolean", nullable : true, inheritable : true, event : "changeProp" } } }); var object = new qx.TestProperty(); // test for the default (false) this.assertNull(object.getProp()); // check for the event var self = this; this.assertEventFired(object, "changeProp", function () { object.setProp(true); }, function(e) { self.assertTrue(e.getData(), "Wrong data in the event!"); self.assertNull(e.getOldData(), "Wrong old data in the event!"); }, "Change event not fired!"); object.dispose(); }, /* --------------------------------------------------------------------------- IS-EQUAL OVERRIDE TEST --------------------------------------------------------------------------- */ /** * Check whether the (numeric) value is negative zero (-0) * * @param value {number} Value to check * @return {Boolean} whether the value is <code>-0</code> */ __isNegativeZero : function (value) { return value===0 && (1/value < 0); // 1/-0 => -Infinity }, /** * Check whether the (numeric) value is positive zero (+0) * * @param value {number} Value to check * @return {Boolean} whether the value is <code>+0</code> */ __isPositiveZero : function (value) { return value===0 && (1/value > 0); // 1/+0 => +Infinity }, testWrongIsEqualDefinitions : function () { if (qx.core.Environment.get("qx.debug")) { var re = new RegExp("Invalid type for 'isEqual'.*"); var o = new qx.core.Object(); [ new Date(), // date [1,2,3], // array {}, // object o, // qooxdoo class new RegExp(), // RegExp null, // null true, false, // boolean 123 // number ].forEach(function (isEqualTestValue, i) { var msg = "case[" + i + "] (" + String(isEqualTestValue) + ")"; this.assertException(function () { qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Number", isEqual : isEqualTestValue } } }); new qx.TestProperty().set({prop: 0}); }, Error, re, msg); delete qx.TestProperty; }, this); o.dispose(); } // end-if (qx.core.Environment.get("qx.debug")) }, testIsEqualInline : function () { qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Number", nullable : true, event : "changeProp", isEqual : "Object.is(a, b)" } } }); var object = new qx.TestProperty(); object.setProp(0); // initialize with +0 // // check for the event // var self = this; // No change expected this.assertEventNotFired(object, "changeProp", function () { object.setProp(0); object.setProp(+0); }, function (e) {}, "'changeProp' event fired!"); // Change expected this.assertEventFired(object, "changeProp", function () { object.setProp(-0); }, function (e) { var isNegativeZero = self.__isNegativeZero( e.getData() ); var isPositiveZero = self.__isPositiveZero( e.getOldData() ); self.assertTrue(isNegativeZero, "Wrong data in the event!"); self.assertTrue(isPositiveZero, "Wrong old data in the event!"); }, "Change event not fired!"); // @todo: check 'apply' and 'transform', too object.dispose(); }, testIsEqualFunction : function () { qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Number", nullable : true, event : "changeProp", isEqual : function (x,y) { return Object.is(x, y); } } } }); var object = new qx.TestProperty(); object.setProp(0); // initialize with +0 // // check for the event // var self = this; // No change expected this.assertEventNotFired(object, "changeProp", function () { object.setProp(0); object.setProp(+0); }, function (e) {}, "'changeProp' event fired!"); // Change expected this.assertEventFired(object, "changeProp", function () { object.setProp(-0); }, function (e) { var isNegativeZero = self.__isNegativeZero( e.getData() ); var isPositiveZero = self.__isPositiveZero( e.getOldData() ); self.assertTrue(isNegativeZero, "Wrong data in the event!"); self.assertTrue(isPositiveZero, "Wrong old data in the event!"); }, "Change event not fired!"); // @todo: check 'apply' and 'transform', too object.dispose(); }, testIsEqualMember : function () { qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Number", nullable : true, event : "changeProp", isEqual : "__fooBar" } }, members : { __fooBar : function (foo, bar) { return Object.is(foo, bar); } } }); var object = new qx.TestProperty(); object.setProp(0); // initialize with +0 // // check for the event // var self = this; // No change expected this.assertEventNotFired(object, "changeProp", function () { object.setProp(0); object.setProp(+0); }, function (e) {}, "'changeProp' event fired!"); // Change expected this.assertEventFired(object, "changeProp", function () { object.setProp(-0); }, function (e) { var isNegativeZero = self.__isNegativeZero( e.getData() ); var isPositiveZero = self.__isPositiveZero( e.getOldData() ); self.assertTrue(isNegativeZero, "Wrong data in the event!"); self.assertTrue(isPositiveZero, "Wrong old data in the event!"); }, "Change event not fired!"); // @todo: check 'apply' and 'transform', too object.dispose(); }, testIsEqualInlineContext : function () { var context, object; qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Number", nullable : true, event : "changeProp", isEqual : "(this.__checkCtx(a,b))" } }, members : { __checkCtx : function (foo, bar) { context = this; } } }); object = new qx.TestProperty().set({prop: 4711}); this.assertIdentical(object, context); object.dispose(); }, testIsEqualFunctionContext : function () { var context, object; qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Number", nullable : true, event : "changeProp", isEqual : function (x, y) { context = this; } } } }); object = new qx.TestProperty().set({prop: 4711}); this.assertIdentical(object, context); object.dispose(); }, testIsEqualMemberContext : function () { var context, object; qx.Class.define("qx.TestProperty", { extend : qx.core.Object, properties : { prop : { check : "Number", nullable : true, event : "changeProp", isEqual : "__checkCtx" } }, members : { __checkCtx : function (foo, bar) { context = this; } } }); object = new qx.TestProperty().set({prop: 4711}); this.assertIdentical(object, context); object.dispose(); }, testIsEqualBaseClassMember : function () { var context, object; qx.Class.define("qx.Super", { extend : qx.core.Object, members : { __checkCtx : function (foo, bar) { context = this; } } }); qx.Class.define("qx.TestProperty", { extend: qx.Super, properties : { prop : { check : "Number", nullable : true, event : "changeProp", isEqual : "__checkCtx" } } }); object = new qx.TestProperty().set({prop: 4711}); this.assertIdentical(object, context); object.dispose(); }, testTransform : function () { qx.Class.define("qx.TestProperty", { extend : qx.core.Object, construct: function() { this.base(arguments); this.initPropTwo(new qx.data.Array()); }, properties : { prop : { check : "qx.data.Array", nullable : true, event : "changeProp", transform : "__transform" }, propTwo : { check : "qx.data.Array", nullable : true, event : "changePropTwo", transform : "__transform", deferredInit: true } }, members : { __transform : function (value, oldValue) { if (oldValue === undefined) return value; if (!value) oldValue.removeAll(); else oldValue.replace(value) return oldValue; } } }); var object = new qx.TestProperty(); var arr = new qx.data.Array(); object.setProp(arr); this.assertIdentical(arr, object.getProp()); arr.push("1"); var arr2 = new qx.data.Array(); arr2.push("2"); arr2.push("3"); object.setProp(arr2); this.assertIdentical(arr, object.getProp()); this.assertArrayEquals([ "2", "3" ], arr.toArray()); var savePropTwo = object.getPropTwo(); object.setPropTwo(arr2); this.assertIdentical(savePropTwo, object.getPropTwo()); this.assertArrayEquals([ "2", "3" ], savePropTwo.toArray()); } } });