// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
//
//
///
///
///
///
///
module CorsicaTests {
"use strict";
function errorHandler(msg) {
try {
LiveUnit.Assert.fail('There was an unhandled error in your test: ' + msg);
} catch (ex) { }
}
function post(v) {
return WinJS.Utilities.Scheduler.schedulePromiseNormal().then(function () { return v; });
}
function assertIsUndefinedString(v) {
// When setting undefined as the value of textContent:
// Firefox coerces undefined to empty string [Bug]
// IE & Chrome coerce it to the string "undefined" [Expected]
if (v !== "undefined" && v !== "") {
LiveUnit.Assert.fail("Value should be empty or undefined, but instead is " + v);
}
}
function findElement(root, id) {
if (root.id === id) { return root; }
else { return root.querySelector("#" + id); }
}
function parent(element) {
document.body.appendChild(element);
return function () { document.body.removeChild(element); };
}
function whenLoadingComplete(listview, func) {
var complete;
var p = new WinJS.Promise(function (c) {
complete = c;
});
function checkAndExecute() {
if (listview.loadingState === "complete") {
complete();
func && func();
}
}
listview.addEventListener("loadingstatechanged", LiveUnit.GetWrappedCallback(checkAndExecute), false);
checkAndExecute();
return p;
}
export class BindingDeclTests {
setUp() {
window['supportedForProcessingInitializer'] = WinJS.Binding.initializer(function (a, b, c, d) {
return WinJS.Binding.defaultBind(a, b, c, d);
});
window['notSupportedForProcessingInitializer'] = function (a, b, c, d) {
return WinJS.Binding.defaultBind(a, b, c, d);
};
}
tearDown() {
delete window['supportedForProcessingInitializer'];
delete window['notSupportedForProcessingInitializer'];
}
testBadSource = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:badProp');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
assertIsUndefinedString(mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
}
testNestedBadSourceOneTime = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:badProp.badder WinJS.Binding.oneTime');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
assertIsUndefinedString(mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testBadDest = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'badProp:name');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual("", mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testBadDest2 = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'badProp.badder:name');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual("", mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testAttribute = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'this["aria-label"]:name WinJS.Binding.setAttribute');
var obj = { name: 'Franky', width: 100 };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("aria-label"));
bindable.name = "Hollywood";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("aria-label"));
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testAttributeOneTime = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'this["aria-label"]:name WinJS.Binding.setAttributeOneTime');
var obj = { name: 'Franky', width: 100 };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("aria-label"));
bindable.name = "Hollywood";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual("Franky", mydiv.getAttribute("aria-label"));
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testToNonAriaAttribute = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'label:name WinJS.Binding.setAttribute');
var obj = { name: 'Franky', width: 100 };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("label"));
bindable.name = "Hollywood";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual(bindable.name, mydiv.getAttribute("label"));
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testToNonAriaAttributeOneTime = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'label:name WinJS.Binding.setAttributeOneTime');
var obj = { name: 'Franky', width: 100 };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("label"));
bindable.name = "Hollywood";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual('Franky', mydiv.getAttribute("label"));
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSettingAttributesAndProperties = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'label:name WinJS.Binding.setAttribute; textContent:title');
var obj = { name: 'Franky', title: 'testing' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual(obj.title, mydiv.textContent);
bindable.name = "Hollywood";
bindable.title = "new title";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual(bindable.name, mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual(bindable.title, mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSettingAttributesAndOneTimeBindingToProperties = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'label:name WinJS.Binding.setAttribute; textContent:title WinJS.Binding.oneTime');
var obj = { name: 'Franky', title: 'testing' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual(obj.title, mydiv.textContent);
bindable.name = "Hollywood";
bindable.title = "new title";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual(bindable.name, mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual('testing', mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSettingAttributesOneTimeAndBindingToProperties = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'label:name WinJS.Binding.setAttributeOneTime; textContent:title');
var obj = { name: 'Franky', title: 'testing' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual(obj.title, mydiv.textContent);
bindable.name = "Hollywood";
bindable.title = "new title";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual('Franky', mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual(bindable.title, mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testBindingToMultiplePropertiesAndSettingAttribute = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:title; style.width:width; label:name WinJS.Binding.setAttributeOneTime');
var obj = { name: 'Franky', title: 'testing', width: '100px' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual(obj.title, mydiv.textContent);
LiveUnit.Assert.areEqual(obj.width, mydiv.style.width);
bindable.name = "Hollywood";
bindable.title = "new title";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual('Franky', mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual(bindable.title, mydiv.textContent);
LiveUnit.Assert.areEqual(obj.width, mydiv.style.width);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testBindingToMultiplePropertiesWithBindingActionAndSettingAttribute = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:title testFunction; label:name WinJS.Binding.setAttribute');
window['testFunction'] = WinJS.Binding.initializer(function (source, sourceProperties, dest, destProperties) {
dest[destProperties] = source[sourceProperties];
});
var obj = { name: 'Franky', title: 'testing' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual(obj.title, mydiv.textContent);
bindable.name = "Hollywood";
bindable.title = "new title";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual(bindable.name, mydiv.getAttribute("label"));
LiveUnit.Assert.areEqual('testing', mydiv.textContent);
}).
then(null, errorHandler).
then(function () { delete window['testFunction'] }).
then(cleanup).
then(complete, errorHandler);
};
testBindingToDeepDestinationProperty = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'x.title: title WinJS.Binding.setAttribute');
var hit = 0;
var old = WinJS.log;
WinJS.log = function () {
hit++;
}
var obj = { name: 'Franky', title: 'testing' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(1, hit, "WinJS.log should be hit in that case");
}).
then(null, errorHandler).
then(function () { WinJS.log = old; }).
then(cleanup).
then(complete, errorHandler);
};
testBindingToThisInSetAttribute = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'this : title WinJS.Binding.setAttribute');
var hit = 0;
var old = WinJS.log;
WinJS.log = function () {
hit++;
}
var obj = { name: 'Franky', title: 'testing' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(1, hit, "WinJS.log should be hit in that case");
})
.then(null, errorHandler).
then(function () { WinJS.log = old; }).
then(cleanup).
then(complete, errorHandler);
};
testBindingToMissingDestinationProperty = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', ' : title WinJS.Binding.setAttribute');
var obj = { name: 'Franky', title: 'testing' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.fail("An error message should be thrown.");
}, function (e) {
// ignore the error
})
.then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testBindingToInnerTextUsingSetAttribute = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:title WinJS.Binding.setAttribute');
var obj = { title: 'testing', width: '100px' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.title, mydiv.getAttribute('textContent'));
LiveUnit.Assert.areEqual('', mydiv.textContent);
bindable.title = "new title";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.title, mydiv.getAttribute('textContent'));
LiveUnit.Assert.areEqual('', mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSetAttributeWithDeepObject = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:title.innerObj.innerTitle WinJS.Binding.setAttribute');
var obj = { title: { innerObj: { innerTitle: 'testing' } }, width: '100px' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.title.innerObj.innerTitle, mydiv.getAttribute('textContent'));
bindable.title.innerObj.innerTitle = "new title";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.title.innerObj.innerTitle, mydiv.getAttribute('textContent'));
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSetAttributeBindingToSameObject = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'foo:title WinJS.Binding.setAttribute');
var mydiv2 = document.createElement('div');
var cleanup2 = parent(mydiv2);
mydiv2.setAttribute('id', 'mydiv2');
mydiv2.setAttribute('data-win-bind', 'bar:title WinJS.Binding.setAttribute');
var obj = { title: 'testing', width: '100px' };
var bindable = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(null, bindable);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.title, mydiv.getAttribute('foo'));
LiveUnit.Assert.areEqual(obj.title, mydiv2.getAttribute('bar'));
bindable.title = "new title";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.title, mydiv.getAttribute('foo'));
LiveUnit.Assert.areEqual(obj.title, mydiv2.getAttribute('bar'));
}).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
};
testSimple = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testNestedDOMAccessDenied = function (complete) {
var mydiv = document.createElement('div');
var mydiv2 = document.createElement('div');
var cleanup = parent(mydiv);
var cleanup2 = parent(mydiv2);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name; nextElementSibling.textContent:name');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
LiveUnit.Assert.areEqual("", mydiv2.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
};
testDuplicateIDFail = function (complete) {
var mydiv = document.createElement('div');
var mydiv2 = document.createElement('div');
var cleanup = parent(mydiv);
var cleanup2 = parent(mydiv2);
mydiv.setAttribute('id', 'mydiv');
mydiv2.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name;');
mydiv2.setAttribute('data-win-bind', 'textContent:width;');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
LiveUnit.Assert.areEqual("", mydiv2.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
};
testInvalidBindToId = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('data-win-bind', 'id:name');
var obj = { name: 'Franky' };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.isTrue(obj.name !== mydiv.id);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleIdFilter = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'id:name;textContent:name');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
LiveUnit.Assert.areEqual("mydiv", mydiv.id);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleIdFilterValidation = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'id:name;textContent:name');
var obj = { name: 'Franky', width: 100 };
var old = WinJS.validation;
WinJS.validation = true;
var sawException = false;
try {
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj)).then(function () {
LiveUnit.Assert.fail("Should have thrown");
}, function (err) {
sawException = true;
WinJS.validation = old;
});
}
catch (e) {
sawException = true;
WinJS.validation = old;
}
bindingDone.
then(function () {
LiveUnit.Assert.isTrue(sawException, "Should have thrown an exception");
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testNonExtensible = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'testNonExtensible');
mydiv.setAttribute('data-win-bind', 'textContent:name');
var obj = Object.freeze({ name: 'Franky', width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(function () {
LiveUnit.Assert.fail("should not successfully bind");
},
function () {
complete();
});
};
testNonExtensibleOneTime = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name WinJS.Binding.oneTime');
var obj = Object.freeze({ name: 'Franky', width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testThisRecord = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'test:this');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv['test'].name);
LiveUnit.Assert.areEqual(obj.width, mydiv['test'].width);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testThisRecordDot = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'test:this.name');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv['test']);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testThisThisRecordDot = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'this:this.name');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.isTrue(mydiv['test'] === undefined, "binding should be a no-op against 'this'");
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testThisDotThisRecordDot = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'this.test:this.name');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv['test']);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testImplicitGlobalScope = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'testImplicitGlobalScope');
mydiv.setAttribute('data-win-bind', 'textContent:fizzle.name');
window['fizzle'] = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(window['fizzle'].name, mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(function () { delete window['fizzle']; }).
then(complete);
};
testSimpleWithCSS = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name;style.width:width');
var obj = { name: 'Franky', width: '100px' };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
LiveUnit.Assert.areEqual(obj.width, mydiv.style.width);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithDottedSource = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name.first');
var obj = { name: { first: 'Bob' }, width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name.first, mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithAction = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'flappy:name myaction');
window['myaction'] = function (source, sourceProperties, dest, destProperties) {
if (destProperties[0] === 'flappy') { dest.innerHTML = source[sourceProperties]; }
};
WinJS.Binding.initializer(window['myaction']);
var obj = { name: 'Sally', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testInvalidBinding = function () {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'q q q');
var obj = { name: 'Sally', width: 100 };
WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj)).then(
function () {
LiveUnit.Assert.fail("should have thrown an exception");
},
function (e) {
LiveUnit.Assert.isTrue(e.message.indexOf("q q q") != -1, "should contain the bad expression");
}
).then(cleanup);
};
testSimpleWithMissingAction = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'innerHTML:name myaction');
var old = WinJS.log;
function cleanupLog() {
WinJS.log = old;
}
var logs = [];
WinJS.log = function (message, tags, type) {
logs.push({ message: message, tags: tags, type: type });
}
var obj = { name: 'Sally', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
LiveUnit.Assert.areEqual(1, logs.length, "should have logged 1 error");
LiveUnit.Assert.areEqual("error", logs[0].type, "should be tagged an error");
LiveUnit.Assert.isTrue(logs[0].message.indexOf("myaction") != -1, "should contain the offending action name");
}).
then(null, errorHandler).
then(cleanup).
then(cleanupLog).
then(complete, errorHandler);
};
testSimpleWithConverter = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name myaction');
window['myaction'] = WinJS.Binding.converter(function (v) {
return v.toUpperCase();
});
WinJS.Binding.initializer(window['myaction']);
var obj = { name: 'Sally', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(post).
then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual("SALLY", mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithConverterWithUndefinedProperty = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
// The non-exiting tooltip should trigger the myaction also and set it to an empty string ""
mydiv.setAttribute('data-win-bind', 'textContent:name myaction;title:tooltip myaction');
window['myaction'] = WinJS.Binding.converter(function (v) {
return v ? v : "";
});
WinJS.Binding.initializer(window['myaction']);
var obj = { name: 'Sally', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(post).
then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual("Sally", mydiv.textContent);
LiveUnit.Assert.areEqual("", mydiv.title);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithConverterDefaultInitializer = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name');
var myaction = WinJS.Binding.converter(function (v) {
return v.toUpperCase();
});
var obj = { name: 'Sally', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj), false, null, myaction);
bindingDone.
then(post).
then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual("SALLY", mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithOneTime = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name WinJS.Binding.oneTime');
var obj = WinJS.Binding.as({ name: 'Sally', width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(post).
then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.textContent);
obj.name = "Jane";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithoutOneTime = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name');
var obj = WinJS.Binding.as({ name: 'Sally', width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(post).
then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.textContent);
obj.name = "Jane";
}).
then(post).
then(function () {
LiveUnit.Assert.areEqual("Jane", mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithNamespacedAction = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'flappy:name test.binding_decl.namespacedAction');
WinJS.Namespace.define('test.binding_decl', {
namespacedAction: function (source, sourceProperties, dest, destProperties) {
if (destProperties[0] === 'flappy') { dest.innerHTML = source[sourceProperties]; }
}
});
WinJS.Binding.initializer(window['test'].binding_decl.namespacedAction);
LiveUnit.Assert.isTrue(typeof window['test'].binding_decl.namespacedAction === 'function');
var obj = { name: 'Sparky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
delete window['test'].binding_decl;
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testNestedElementBindingWithNull = function (complete) {
var mydiv = document.createElement('div');
var cleanup2 = parent(mydiv);
mydiv.innerHTML = '\
';
WinJS.Namespace.define('test.binding_decl', {
displayName: function (source, sourceProperty, dest, destProperty) {
dest[destProperty] = source[sourceProperty].first + ' ' + source[sourceProperty].last;
}
});
WinJS.Binding.initializer(window['test'].binding_decl.displayName);
var obj: any = WinJS.Binding.as({
name: {
first: 'Microsoft',
last: 'Bob'
},
height: '5\'6"'
});
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name.first + ' ' + obj.name.last, text('name'));
LiveUnit.Assert.areEqual(obj.height, text('height'));
assertIsUndefinedString(text('street'));
assertIsUndefinedString(text('city'));
assertIsUndefinedString(text('state'));
assertIsUndefinedString(text('zip'));
obj.addProperty("address", {
street: '1234 Microsoft Way',
city: 'Redmond',
state: 'WA',
zip: 98052
});
}).
then(post).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.address.street, text('street'));
LiveUnit.Assert.areEqual(obj.address.city, text('city'));
LiveUnit.Assert.areEqual(obj.address.state, text('state'));
LiveUnit.Assert.areEqual(obj.address.zip.toString(), text('zip'));
}).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
function cleanup() {
delete window['test'];
}
};
testNestedElementBinding = function (complete) {
var mydiv = document.createElement('div');
var cleanup2 = parent(mydiv);
mydiv.innerHTML = '\
';
WinJS.Namespace.define('test.binding_decl', {
displayName: function (source, sourceProperty, dest, destProperty) {
dest[destProperty] = source[sourceProperty].first + ' ' + source[sourceProperty].last;
}
});
WinJS.Binding.initializer(window['test'].binding_decl.displayName);
var obj = {
name: {
first: 'Microsoft',
last: 'Bob'
},
height: '5\'6"',
address: {
street: '1234 Microsoft Way',
city: 'Redmond',
state: 'WA',
zip: 98052
}
};
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name.first + ' ' + obj.name.last, text('name'));
LiveUnit.Assert.areEqual(obj.height, text('height'));
LiveUnit.Assert.areEqual(obj.address.street, text('street'));
LiveUnit.Assert.areEqual(obj.address.city, text('city'));
LiveUnit.Assert.areEqual(obj.address.state, text('state'));
LiveUnit.Assert.areEqual(obj.address.zip.toString(), text('zip'));
}).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
function cleanup() {
delete window['test'];
}
};
testNestedElementBindingWithUpdatesNoBinding = function (complete) {
var mydiv = document.createElement('div');
var cleanup2 = parent(mydiv);
mydiv.innerHTML = '\
\
\
';
WinJS.Namespace.define('test.binding_decl', {
displayName: function (source, sourceProperty, dest, destProperty) {
dest[destProperty] = source[sourceProperty].first + ' ' + source[sourceProperty].last;
}
});
WinJS.Binding.initializer(window['test'].binding_decl.displayName);
var obj = {
name: {
first: 'Microsoft',
last: 'Bob'
},
height: '5\'6"',
address: {
street: 'One Microsoft Way',
city: 'Redmond',
state: 'WA',
zip: 98052
}
};
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
function verify() {
LiveUnit.Assert.areEqual('Microsoft Bob', text('name'));
LiveUnit.Assert.areEqual('5\'6"', text('height'));
LiveUnit.Assert.areEqual('One Microsoft Way', text('street'));
LiveUnit.Assert.areEqual('Redmond', text('city'));
LiveUnit.Assert.areEqual('WA', text('state'));
LiveUnit.Assert.areEqual('98052', text('zip'));
}
bindingDone.
then(verify).
then(function () { obj.height = '5\'2"'; }).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.height, '5\'2"');
}).
then(verify).
then(function () { obj.name.first = 'Mr.'; }).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name.first, 'Mr.');
}).
then(verify).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
function cleanup() {
delete window['test'];
}
};
testNestedElementBindingWithUpdatesWithNoBindObservable = function (complete) {
var mydiv = document.createElement('div');
var cleanup2 = parent(mydiv);
mydiv.innerHTML = '\
\
\
';
WinJS.Namespace.define('test.binding_decl', {
displayName: function (source, sourceProperties, dest, destProperties) {
dest[destProperties] = source[sourceProperties].first + ' ' + source[sourceProperties].last;
}
});
WinJS.Binding.initializer(window['test'].binding_decl.displayName);
var obj = {
name: {
first: 'Microsoft',
last: 'Bob'
},
height: '5\'6"',
address: {
street: 'One Microsoft Way',
city: 'Redmond',
state: 'WA',
zip: 98052
}
};
var ob = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, ob);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
function verify() {
LiveUnit.Assert.areEqual('Microsoft Bob', text('name'));
LiveUnit.Assert.areEqual('5\'6"', text('height'));
LiveUnit.Assert.areEqual('One Microsoft Way', text('street'));
LiveUnit.Assert.areEqual('Redmond', text('city'));
LiveUnit.Assert.areEqual('WA', text('state'));
LiveUnit.Assert.areEqual('98052', text('zip'));
}
bindingDone.
then(verify).
then(function () { ob.height = '5\'2"'; }).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.height, '5\'2"');
LiveUnit.Assert.areEqual('5\'2"', text('height'));
}).
then(function () { ob.name.first = 'Mr.'; }).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name.first, 'Mr.');
LiveUnit.Assert.areEqual('Microsoft Bob', text('name'));
}).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
function cleanup() {
delete window['test'];
}
};
testNestedElementBindingWithUpdatesWithBind = function (complete) {
var mydiv = document.createElement('div');
var cleanup2 = parent(mydiv);
mydiv.innerHTML = '\
\
\
';
WinJS.Namespace.define('test.binding_decl', {
displayName: function (source, sourceProperties, dest, destProperties) {
WinJS.Binding.bind(source, {
name: {
first: function (v) { dest[destProperties] = v + ' ' + source[sourceProperties].last; },
last: function (v) { dest[destProperties] = source[sourceProperties].first + ' ' + v; }
}
});
}
});
WinJS.Binding.initializer(window['test'].binding_decl.displayName);
var obj = {
name: {
first: 'Microsoft',
last: 'Bob'
},
height: '5\'6"',
address: {
street: 'One Microsoft Way',
city: 'Redmond',
state: 'WA',
zip: 98052
}
};
var ob = WinJS.Binding.as(obj);
var bindingDone = WinJS.Binding.processAll(mydiv, ob);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
function verify() {
LiveUnit.Assert.areEqual('Microsoft Bob', text('name'));
LiveUnit.Assert.areEqual('5\'6"', text('height'));
LiveUnit.Assert.areEqual('One Microsoft Way', text('street'));
LiveUnit.Assert.areEqual('Redmond', text('city'));
LiveUnit.Assert.areEqual('WA', text('state'));
LiveUnit.Assert.areEqual('98052', text('zip'));
}
bindingDone.
then(verify).
then(function () { ob.height = '5\'2"'; }).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.height, '5\'2"');
LiveUnit.Assert.areEqual('5\'2"', text('height'));
}).
then(function () { ob.height = 'foo'; }).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.height, 'foo');
LiveUnit.Assert.areEqual('foo', text('height'));
}).
then(function () { ob.name.first = 'Mr.'; }).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name.first, 'Mr.');
LiveUnit.Assert.areEqual('Mr. Bob', text('name'));
}).
then(function () { ob.name = { first: 'lotta', last: 'code' }; }).
then(post).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name.first, 'lotta');
LiveUnit.Assert.areEqual(obj.name.last, 'code');
LiveUnit.Assert.areEqual('lotta code', text('name'));
}).
then(function () { ob.address.street = '1 Microsoft Way'; }).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.address.street, '1 Microsoft Way');
LiveUnit.Assert.areEqual('1 Microsoft Way', text('street'));
}).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
function cleanup() {
delete window['test'];
}
};
testSimpleDataSourceAsync_StrictProcessing = function (complete) {
var mydiv = document.createElement('div');
var cleanup2 = parent(mydiv);
// should not work, data-win-bindsource not supported in strictProcessing mode
mydiv.setAttribute('data-win-bindsource', 'simpleds');
mydiv.innerHTML = '\
\
';
var obj = {
name: {
first: 'Microsoft',
last: 'Bob'
},
height: '5\'6"',
address: {
street: 'One Microsoft Way',
city: 'Redmond',
state: 'WA',
zip: 98052
}
};
window['simpleds'] = WinJS.Binding.as(obj);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
function verify() {
assertIsUndefinedString(text('name'));
}
function cleanup() {
delete window['simpleds'];
}
WinJS.Promise.wrap().
then(function () {
return WinJS.Binding.processAll(mydiv);
}).
then(post).
then(post).
then(function () {
assertIsUndefinedString(text('name'));
}).
then(function () { window['simpleds'].name.first = 'Mr.'; }).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name.first, 'Mr.');
assertIsUndefinedString(text('name'));
}).
then(function () { window['simpleds'].name = { first: 'lotta', last: 'code' }; }).
then(post).
then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name.first, 'lotta');
LiveUnit.Assert.areEqual(obj.name.last, 'code');
assertIsUndefinedString(text('name'));
}).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
};
testSimpleWithMultipleOneActionFunctions = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
var count = 0;
var expected = 2;
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name foo1;style.width:width foo2');
window['foo1'] = function (source, sourceProperties, dest, destProperties) {
count++;
};
WinJS.Binding.initializer(window['foo1']);
window['foo2'] = function (source, sourceProperties, dest, destProperties) {
count++;
};
WinJS.Binding.initializer(window['foo2']);
var obj = { name: 'Sally', width: '100px' };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
delete window['foo1'];
delete window['foo2'];
LiveUnit.Assert.areEqual(expected, count);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testWithMultipleParentIds = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.innerHTML = '\
\
\
';
var obj = WinJS.Binding.as({ name: 'Microsoft' });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
function verify() {
LiveUnit.Assert.areEqual('Microsoft', text('name'));
LiveUnit.Assert.areEqual('Microsoft', text('anotherName'));
}
bindingDone.
then(post).
then(verify).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testWithDifferentParents = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.innerHTML = '\
\
\
';
var obj = WinJS.Binding.as({ name: 'Microsoft' });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
function verify() {
LiveUnit.Assert.areEqual('Microsoft', text('name'));
LiveUnit.Assert.areEqual('Microsoft', text('anotherName'));
}
bindingDone.
then(post).
then(verify).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testWithBindingCache = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name');
var bindable = [{
destination: "textContent",
source: "name",
initializer: undefined
}];
var bindingCache = { expressions: [{ "textContent:name": bindable }] };
var obj = WinJS.Binding.as({ name: 'Sally' });
var bindingDone = WinJS.Binding.processAll(mydiv, obj, false, bindingCache);
bindingDone.
then(post).
then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testWithBindingCacheWithAction = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name foo1');
var count = 0;
var expected = 1;
function foo1(source, sourceProperties, dest, destProperties) {
count++;
dest[destProperties] = source[sourceProperties];
}
var bindable = [{
destination: "textContent",
source: "name",
initializer: foo1
}];
var bindingCache = { expressions: { "textContent:name foo1": bindable } };
var obj = WinJS.Binding.as({ name: 'Sally' });
var bindingDone = WinJS.Binding.processAll(mydiv, obj, false, bindingCache);
bindingDone.
then(post).
then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.textContent);
LiveUnit.Assert.areEqual(expected, count);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithActionNotPresent = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'flappy:name myaction');
var obj = { name: 'Sally', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual("", mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithActionThatGetsDeleted = function (complete) {
var count = 0;
var expected = 1;
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'flappy:name myaction');
window['myaction'] = function (source, sourceProperties, dest, destProperties) {
WinJS.Binding.bind(source,
{
name: function () {
if (destProperties[0] === 'flappy') {
dest.innerHTML = source[sourceProperties];
}
count++;
}
});
};
WinJS.Binding.initializer(window['myaction']);
var obj = WinJS.Binding.as({ name: 'Sally', width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.then(post).then(post).
then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual("Sally", mydiv.innerHTML);
obj.name = "Mary";
}).then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.innerHTML);
LiveUnit.Assert.areEqual(count, expected);
})
.then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testCheckCoalescing = function (complete) {
var count = 0;
var expected = 2;
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'flappy:name myaction');
window['myaction'] = function (source, sourceProperties, dest, destProperties) {
WinJS.Binding.bind(source, {
name: function () {
if (destProperties[0] === 'flappy') {
dest.innerHTML = source[sourceProperties];
}
count++;
}
});
};
WinJS.Binding.initializer(window['myaction']);
var obj = WinJS.Binding.as({ name: 'Sally', width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
obj.name = "Diana";
obj.name = "Mary";
bindingDone.
then(post).then(post).then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual("Mary", mydiv.innerHTML);
LiveUnit.Assert.areEqual(count, expected);
})
.then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testCheckDeclarativeWithNoUpdate = function (complete) {
var count = 0;
var expected = 1;
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'flappy:name myaction');
window['myaction'] = function (source, sourceProperties, dest, destProperties) {
WinJS.Binding.bind(source,
{
name: function () {
if (destProperties[0] === 'flappy') {
dest.innerHTML = source[sourceProperties];
}
count++;
}
});
};
WinJS.Binding.initializer(window['myaction']);
var obj = WinJS.Binding.as({ name: 'Sally', width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(post).then(post).then(function () {
obj.name = "Sally";
}).then(post).then(post).then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual("Sally", mydiv.innerHTML);
LiveUnit.Assert.areEqual(count, expected);
})
.then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testCheckDeclarativeWithUpdate = function (complete) {
var count = 0;
var expected = 2;
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'flappy:name myaction');
window['myaction'] = function (source, sourceProperties, dest, destProperties) {
WinJS.Binding.bind(source,
{
name: function () {
if (destProperties[0] === 'flappy') {
dest.innerHTML = source[sourceProperties];
}
count++;
}
});
};
WinJS.Binding.initializer(window['myaction']);
var obj = WinJS.Binding.as({ name: 'Sally', width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(post).then(post).then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.innerHTML);
obj.name = "Mary";
}).then(post).then(post).then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual("Mary", mydiv.innerHTML);
LiveUnit.Assert.areEqual(count, expected);
})
.then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testProcessAllWithNonObservable = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name');
var obj = { name: 'Bob', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testSimpleWithMultipleProcessAll = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name myaction');
var obj = { name: 'Sally', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
window['myaction'] = function (source, sourceProperties, dest, destProperties) {
dest.innerHTML = source[sourceProperties];
};
WinJS.Binding.initializer(window['myaction']);
bindingDone.then(post).then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.innerHTML);
obj.name = 'Diana';
}).
then(post).then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.innerHTML);
obj.name = 'Mary';
bindingDone = WinJS.Binding.processAll(mydiv, obj);
}).then(post).then(function () {
delete window['myaction'];
LiveUnit.Assert.areEqual("Mary", mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testWithObjectSource = function (complete) {
var count = 0;
var expected = 1;
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:obj myaction');
window['myaction'] = function (source, sourceProperties, dest, destProperties) {
dest.innerHTML = source.name.first;
count++;
};
WinJS.Binding.initializer(window['myaction']);
var obj = WinJS.Binding.as({ name: { first: 'bob' }, width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
function cleanup2() {
delete window['myaction'];
}
bindingDone.then(post).then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name.first, mydiv.innerHTML);
LiveUnit.Assert.areEqual(expected, count);
}, errorHandler, function (c) { }).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
};
testWithFunctionSource = function (complete) {
var count = 0;
var expected = 1;
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:obj myaction');
window['myaction'] = function (source, sourceProperties, dest, destProperties) {
dest.innerHTML = source.name.first();
count++;
};
WinJS.Binding.initializer(window['myaction']);
function cleanup2() {
delete window['myaction'];
}
var obj = WinJS.Binding.as({ name: { first: function () { return 'bob' } }, width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.then(post).then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name.first(), mydiv.innerHTML);
LiveUnit.Assert.areEqual(expected, count);
}, errorHandler, function (c) { }).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
};
testWithArrayAsSource = function (complete) {
var count = 0;
var expected = 2;
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:obj myaction');
window['myaction'] = function (source, sourceProperties, dest, destProperties) {
WinJS.Binding.bind(source, {
name: {
first: function (v) {
dest.innerHTML = source.name.first[count % 3];
count++;
}
}
});
};
WinJS.Binding.initializer(window['myaction']);
function cleanup2() {
delete window['myaction'];
}
var obj = WinJS.Binding.as({ name: { first: ["Bob", "Mary", "Saly"] } });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.then(post).then(post).
then(function () {
LiveUnit.Assert.areEqual(obj.name.first[(count - 1) % 3], mydiv.innerHTML);
obj.name = { first: ["Bob1", "Mary", "Saly"] };
}, errorHandler, function (c) { }).
then(post).then(post).then(function () {
LiveUnit.Assert.areEqual(obj.name.first[(count - 1) % 3], mydiv.innerHTML);
LiveUnit.Assert.areEqual(expected, count);
}, errorHandler, function (c) { }).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
};
testNestedElementBinding2 = function (complete) {
var mydiv = document.createElement('div');
var cleanup2 = parent(mydiv);
mydiv.innerHTML = '\
';
var obj = {
name: 'Microsoft',
height: '5\'6"',
address: {
street: '1234 Microsoft Way',
}
};
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, text('name'));
LiveUnit.Assert.areEqual(obj.name, text('name2'));
LiveUnit.Assert.areEqual(obj.height, text('height'));
LiveUnit.Assert.areEqual(obj.address.street, text('street'));
}).
then(null, errorHandler).
then(cleanup2).
then(complete, errorHandler);
};
testNestedElementBindingWithChild = function (complete) {
var mydiv = document.createElement('div');
var cleanup2 = parent(mydiv);
mydiv.innerHTML = '\
';
var obj = {
height: '5\'6"',
address: {
name: 'Microsoft',
street: '1234 Microsoft Way',
}
};
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
bindingDone.
then(function () {
assertIsUndefinedString(text('name'));
LiveUnit.Assert.areEqual(obj.height, text('height'));
assertIsUndefinedString(text('street'));
}).
then(null, errorHandler).
then(cleanup2).
then(complete, errorHandler);
};
testNestedElementBindingWithoutWinDefine = function (complete) {
var mydiv = document.createElement('div');
var cleanup2 = parent(mydiv);
mydiv.innerHTML = '\
';
WinJS.Namespace.define('test.binding_decl', {
displayName: function (source, sourceProperty, dest, destProperty) {
dest[destProperty] = source[sourceProperty].first + ' ' + source[sourceProperty].last;
}
});
WinJS.Binding.initializer(window['test'].binding_decl.displayName);
var obj = {
name: {
first: 'Microsoft',
last: 'Bob'
},
height: '5\'6"',
address: {
street: '1234 Microsoft Way',
city: 'Redmond',
state: 'WA',
zip: 98052
}
};
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
function text(id) {
return findElement(mydiv, id).innerHTML;
}
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name.first + ' ' + obj.name.last, text('name'));
LiveUnit.Assert.areEqual(obj.height, text('height'));
LiveUnit.Assert.areEqual(obj.address.street, text('street'));
LiveUnit.Assert.areEqual(obj.address.city, text('city'));
LiveUnit.Assert.areEqual(obj.address.state, text('state'));
LiveUnit.Assert.areEqual(obj.address.zip.toString(), text('zip'));
}).
then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
function cleanup() {
delete window['test'];
}
};
testTemplateWithListView = function (complete) {
function id(elementId) {
return document.getElementById(elementId);
}
var u = WinJS.Utilities;
var listView, count = 0;
var sampleDataSource = [];
var holder = document.createElement("div");
holder.id = "testTemplateWithListView";
holder.innerHTML = "";
var cleanup1 = parent(holder);
listView = document.createElement("div");
listView.id = "listViewExample";
listView.setAttribute("data-win-control", "WinJS.UI.ListView ");
listView.setAttribute("data-win-options", "{itemDataSource : DataSource , layout:{type:WinJS.UI.ListLayout},itemTemplate:sampleTemplate, selectionMode:'single'} ");
var cleanup2 = parent(listView);
for (var i = 0; i < 5; i++) {
var t = "Corsica_" + i;
var d = "Javascript Toolkit_" + i;
sampleDataSource.push({ title: t, description: d });
}
window['DataSource'] = Helper.ItemsManager.simpleSynchronousArrayDataSource(sampleDataSource);
WinJS.UI.processAll().
then(function () {
return whenLoadingComplete(listView.winControl, function () {
count = 0;
u.query(".sampleTitle", listView).forEach(function (e) {
count++;
});
u.query(".sampleDesc", listView).forEach(function (e) {
count++;
});
LiveUnit.Assert.areEqual(10, count, "Should have found the right number of yes/no elements");
});
}).
then(null, errorHandler).
then(post).
then(cleanup1).
then(cleanup2).
then(function () {
delete window['DataSource'];
}, function () {
delete window['DataSource'];
}).
then(complete);
};
testTemplateWithScrollingListView = function (complete) {
function id(elementId) {
return document.getElementById(elementId);
}
var u = WinJS.Utilities;
var listView, count = 0;
var sampleDataSource = [];
var holder = document.createElement("div");
holder.id = "testTemplateWithListView";
holder.innerHTML = "";
var cleanup1 = parent(holder);
listView = document.createElement("div");
listView.id = "listViewExample";
listView.setAttribute("data-win-control", "WinJS.UI.ListView ");
listView.setAttribute("data-win-options", "{itemDataSource : DataSource , layout:{type:WinJS.UI.ListLayout},itemTemplate:sampleTemplate, selectionMode:'single'} ");
var cleanup2 = parent(listView);
for (var i = 0; i < 20; i++) {
var t = "Corsica_" + i;
var d = "Javascript Toolkit_" + i;
sampleDataSource.push({ title: t, description: d });
}
window['DataSource'] = Helper.ItemsManager.simpleSynchronousArrayDataSource(sampleDataSource);
WinJS.UI.processAll().
then(function () {
return whenLoadingComplete(listView.winControl, function () {
var elementHeight = 40; // we need to get the actual height of each element;
listView.scrollPosition = 11 * elementHeight;
listView.scrollPosition = 4 * elementHeight;
listView.scrollPosition = 14 * elementHeight;
count = 0;
u.query(".sampleTitle", listView).forEach(function (e) {
count++;
});
u.query(".sampleDesc", listView).forEach(function (e) {
count++;
});
listView.scrollPosition = 0;
LiveUnit.Assert.areEqual(40, count, "Should have found the right number of yes/no elements");
});
}).
then(null, errorHandler).
then(post).
then(cleanup1).
then(cleanup2).
then(function () {
delete window['DataSource'];
}, function () {
delete window['DataSource'];
}).
then(complete);
};
testBindingToGlobalObject = function (complete) {
var t = 1;
var result = 1;
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:parentNode.child.grandChild');
WinJS.Namespace.define('parentNode', { child: { grandChild: "innerHTML content" } });
var bindingDone = WinJS.Binding.processAll();
function cleanup2() {
delete window['parentNode'];
}
bindingDone.then(post).then(function () {
LiveUnit.Assert.areEqual("innerHTML content", mydiv.innerHTML);
}).then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
};
testBindingToGlobalNameSpace = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:value');
window['value'] = 10;
var bindingDone = WinJS.Binding.processAll();
function cleanup2() {
delete window['value'];
}
bindingDone.then(post).then(function () {
LiveUnit.Assert.areEqual(window['value'].toString(), mydiv.innerHTML);
}).then(null, errorHandler).
then(cleanup).
then(cleanup2).
then(complete, errorHandler);
}
testBindingWithNonExistingProperty = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent1:name');
var obj = { name: 'Franky', width: 100 };
var bindingDone = WinJS.Binding.processAll(mydiv, WinJS.Binding.as(obj));
bindingDone.
then(function () {
LiveUnit.Assert.areEqual(obj.name, mydiv['textContent1']);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testUsingNotSupportedForProcessingBindingRHS_StrictProcessing = function (complete) {
var holder = document.createElement("div");
holder.innerHTML = "";
WinJS.Binding.processAll(holder).then(
function () {
LiveUnit.Assert.fail("should not get here when strictProcessing");
},
function (e) {
LiveUnit.Assert.areEqual("WinJS.Utilities.requireSupportedForProcessing", e.name);
}
).
then(null, errorHandler).
then(complete);
}
testUsingNotSupportedForProcessingBindingLHS_StrictProcessing = function (complete) {
var holder = document.createElement("div");
holder.innerHTML = "";
WinJS.Binding.processAll(holder).then(
function () {
LiveUnit.Assert.fail("should not get here when strictProcessing");
},
function (e) {
LiveUnit.Assert.areEqual("WinJS.Utilities.requireSupportedForProcessing", e.name);
}
).
then(null, errorHandler).
then(complete);
}
testUsingNotSupportedForProcessingBindingInitializer_StrictProcessing = function (complete) {
var holder = document.createElement("div");
holder.innerHTML = "";
WinJS.Binding.processAll(holder).then(
function () {
LiveUnit.Assert.fail("should not get here when strictProcessing");
},
function (e) {
LiveUnit.Assert.areEqual("WinJS.Utilities.requireSupportedForProcessing", e.name);
}
)
.then(null, errorHandler)
.then(complete);
}
testDefaultBind = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name WinJS.Binding.defaultBind');
var obj = WinJS.Binding.as({ name: 'Sally' });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(post).then(function () {
LiveUnit.Assert.areEqual("Sally", mydiv.textContent);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testCheckDefaultBindingWithCoalescing = function (complete) {
var mydiv = document.createElement('div');
var cleanup = parent(mydiv);
mydiv.setAttribute('id', 'mydiv');
mydiv.setAttribute('data-win-bind', 'textContent:name WinJS.Binding.defaultBind');
var obj = WinJS.Binding.as({ name: 'First', width: 100 });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
obj.name = "Second";
obj.name = "Third";
bindingDone.
then(post).then(function () {
LiveUnit.Assert.areEqual("Third", mydiv.innerHTML);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testAddClassOneTime = function (complete) {
var mydiv = document.createElement("div");
var cleanup = parent(mydiv);
mydiv.classList.add("originalClass");
mydiv.setAttribute("id", "mydiv");
mydiv.setAttribute("data-win-bind", "textContent:name WinJS.Binding.addClassOneTime");
var obj = WinJS.Binding.as({ name: "Sally" });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(post).then(function () {
LiveUnit.Assert.areEqual("originalClass Sally", mydiv.className);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testAddClassOneTimeWithEmptyBinding = function (complete) {
var mydiv = document.createElement("div");
var cleanup = parent(mydiv);
mydiv.classList.add("originalClass");
mydiv.setAttribute("id", "mydiv");
mydiv.setAttribute("data-win-bind", "textContent:name WinJS.Binding.addClassOneTime");
var obj = WinJS.Binding.as({ name: "" });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(post).then(function () {
LiveUnit.Assert.areEqual("originalClass", mydiv.className);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testAddClassOneTimeWithArray = function (complete) {
var mydiv = document.createElement("div");
var cleanup = parent(mydiv);
mydiv.classList.add("originalClass");
mydiv.setAttribute("id", "mydiv");
mydiv.setAttribute("data-win-bind", "textContent:names WinJS.Binding.addClassOneTime");
var obj = WinJS.Binding.as({ names: ["Sally", "Nelly"] });
var bindingDone = WinJS.Binding.processAll(mydiv, obj);
bindingDone.
then(post).then(function () {
LiveUnit.Assert.areEqual("originalClass Sally Nelly", mydiv.className);
}).
then(null, errorHandler).
then(cleanup).
then(complete, errorHandler);
};
testGetValue = function () {
var obj = {
title: "foo",
pages: {
page1: "bar"
}
}
LiveUnit.Assert.areEqual(WinJS.Binding.getValue(obj, ["title"]), "foo");
LiveUnit.Assert.areEqual(WinJS.Binding.getValue(obj, ["pages", "page1"]), "bar");
LiveUnit.Assert.areEqual(WinJS.Binding.getValue(obj, ["nonExisting"]), undefined);
LiveUnit.Assert.areEqual(WinJS.Binding.getValue(obj, ["pages", "page2"]), undefined);
}
}
}
LiveUnit.registerTestClass('CorsicaTests.BindingDeclTests');