diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj index 28de7d593..655640cd4 100644 --- a/CrossPlatformModules.csproj +++ b/CrossPlatformModules.csproj @@ -528,7 +528,7 @@ - + @@ -1992,7 +1992,7 @@ False - + \ No newline at end of file diff --git a/apps/tests/ui/observable-tests.ts b/apps/tests/observable-tests.ts similarity index 83% rename from apps/tests/ui/observable-tests.ts rename to apps/tests/observable-tests.ts index b8bb5598e..b0a29ddf4 100644 --- a/apps/tests/ui/observable-tests.ts +++ b/apps/tests/observable-tests.ts @@ -7,7 +7,7 @@ import observable = require("data/observable"); // import dependencyObservable = require("ui/core/dependency-observable"); -import TKUnit = require("../TKUnit"); +import TKUnit = require("./TKUnit"); import types = require("utils/types"); import proxy = require("ui/core/proxy"); @@ -379,7 +379,7 @@ export var test_Observable_WhenCreatedWithJSON_PropertyChangedWithBracketsNotati TKUnit.assert(receivedCount === 1, "PropertyChanged event not raised properly."); } -export function test_AddingTwoEventHandlersAndRemovingWithinHandlerShouldRaiseAllEvents() { +export var test_AddingTwoEventHandlersAndRemovingWithinHandlerShouldRaiseAllEvents = function() { var observableInstance = new observable.Observable(); var firstHandlerCalled = false; var secondHandlerCalled= false; @@ -405,3 +405,77 @@ export function test_AddingTwoEventHandlersAndRemovingWithinHandlerShouldRaiseAl TKUnit.assertEqual(firstHandlerCalled, true); TKUnit.assertEqual(secondHandlerCalled, true); } + +export var test_ObservableCreatedWithJSON_shouldDistinguishSeparateObjects = function () { + var obj1 = {val: 1}; + var obj2 = {val: 2}; + var observable1 = new observable.Observable(obj1); + var observable2 = new observable.Observable(obj2); + + var val1 = observable1.get("val"); + var val2 = observable2.get("val"); + TKUnit.assert(val1 === 1 && val2 === 2, `Observable should keep separate objects separate! val1: ${val1}; val2: ${val2};`); + + var propName1; + var newValue1; + observable1.on(observable.Observable.propertyChangeEvent, (data: observable.PropertyChangeData) => { + propName1 = data.propertyName; + newValue1 = data.value; + }); + + var propName2; + var newValue2; + observable2.on(observable.Observable.propertyChangeEvent, (data: observable.PropertyChangeData) => { + propName2 = data.propertyName; + newValue2 = data.value; + }); + + observable1.set("val", 10); + TKUnit.wait(0.1); + TKUnit.assert(propName1 === "val", "propName1 should be 'val'"); + TKUnit.assert(newValue1 === 10, "newValue1 should be 10"); + + observable2.set("val", 20); + TKUnit.wait(0.1); + TKUnit.assert(propName2 === "val", "propName2 should be 'val'"); + TKUnit.assert(newValue2 === 20, "newValue2 should be 20"); + + val1 = observable1.get("val"); + val2 = observable2.get("val"); + TKUnit.assert(val1 === 10 && val2 === 20, `Observable should keep separate objects separate! val1: ${val1}; val2: ${val2};`); +}; + +export var test_ObservablesCreatedWithJSON_shouldNotInterfereWithOneAnother = function () { + var observable1 = new observable.Observable({ property1: 1 }); + var observable2 = new observable.Observable({ property2: 2 }); + + TKUnit.assert(observable1.get("property1") === 1, `Expected: 1; Actual: ${observable1.get("property1")}`); + TKUnit.assert(observable1.get("property2") === undefined, `Expected: undefined; Actual: ${observable1.get("property2") }`); + + TKUnit.assert(observable2.get("property1") === undefined, `Expected: undefined; Actual: ${observable2.get("property1") }`); + TKUnit.assert(observable2.get("property2") === 2, `Expected: 2; Actual: ${observable2.get("property2") }`); + + var propName1; + var newValue1; + observable1.on(observable.Observable.propertyChangeEvent, (data: observable.PropertyChangeData) => { + propName1 = data.propertyName; + newValue1 = data.value; + }); + + var propName2; + var newValue2; + observable2.on(observable.Observable.propertyChangeEvent, (data: observable.PropertyChangeData) => { + propName2 = data.propertyName; + newValue2 = data.value; + }); + + observable1.set("property1", 10); + TKUnit.wait(0.1); + TKUnit.assert(propName1 === "property1", "propName1 should be 'property1'"); + TKUnit.assert(newValue1 === 10, "newValue1 should be 10"); + + observable2.set("property2", 20); + TKUnit.wait(0.1); + TKUnit.assert(propName2 === "property2", "propName2 should be 'property2'"); + TKUnit.assert(newValue2 === 20, "newValue2 should be 20"); +}; \ No newline at end of file diff --git a/apps/tests/testRunner.ts b/apps/tests/testRunner.ts index e74940ed8..e3ea56eea 100644 --- a/apps/tests/testRunner.ts +++ b/apps/tests/testRunner.ts @@ -45,7 +45,7 @@ allTests["TIMER"] = require("./timer-tests"); allTests["COLOR"] = require("./color-tests"); allTests["OBSERVABLE-ARRAY"] = require("./observable-array-tests"); allTests["VIRTUAL-ARRAY"] = require("./virtual-array-tests"); -allTests["OBSERVABLE"] = require("./ui/observable-tests"); +allTests["OBSERVABLE"] = require("./observable-tests"); allTests["DEPENDENCY-OBSERVABLE"] = require("./ui/dependency-observable-tests"); allTests["BINDABLE"] = require("./ui/bindable-tests"); allTests["BINDING-EXPRESSIONS"] = require("./ui/binding-expressions-tests"); diff --git a/data/observable/observable.ts b/data/observable/observable.ts index 565fc58e7..e677fede6 100644 --- a/data/observable/observable.ts +++ b/data/observable/observable.ts @@ -15,31 +15,29 @@ export class Observable implements definition.Observable { constructor(json?: any) { if (json) { this._map = new Map(); - var that = this; - - var definePropertyFunc = function definePropertyFunc(propertyName) { - Object.defineProperty(Observable.prototype, propertyName, { - get: function () { - return that._map.get(propertyName); - }, - set: function (value) { - that._map.set(propertyName, value); - that.notify(that._createPropertyChangeData(propertyName, value)); - }, - enumerable: true, - configurable: true - }); - }; - for (var prop in json) { if (json.hasOwnProperty(prop)) { - definePropertyFunc(prop); + this._defineNewProperty(prop); this.set(prop, json[prop]); } } } } + private _defineNewProperty(propertyName: string): void { + Object.defineProperty(this, propertyName, { + get: function () { + return this._map.get(propertyName); + }, + set: function (value) { + this._map.set(propertyName, value); + this.notify(this._createPropertyChangeData(propertyName, value)); + }, + enumerable: true, + configurable: true + }); + } + get typeName(): string { return types.getClass(this); }