UNPKG

can-stache-bindings

Version:

Default binding syntaxes for can-stache

460 lines (394 loc) 13.3 kB
var QUnit = require('steal-qunit'); var testHelpers = require('../helpers'); var stacheBindings = require('can-stache-bindings'); var domEvents = require('can-dom-events'); var stache = require('can-stache'); var SimpleMap = require("can-simple-map"); var MockComponent = require("../mock-component-simple-map"); var encoder = require("can-attribute-encoder"); var canTestHelpers = require('can-test-helpers'); function siblingsDataToInfo(siblingData) { return { parent: siblingData.parent.source, child: siblingData.child.source, childEvent: siblingData.child.event, parentToChild: siblingData.parent.exports, childToParent: siblingData.child.exports, childName: siblingData.child.name, parentName: siblingData.parent.name, bindingAttributeName: siblingData.bindingAttributeName, initializeValues: siblingData.initializeValues, syncChildWithParent: siblingData.parent.syncSibling }; } stache.addBindings(stacheBindings); testHelpers.makeTests("can-stache-bindings - colon - basics", function(name, doc, enableMO){ QUnit.test("basics", function(assert) { assert.expect(5); var viewModel = new SimpleMap({ toChild: "toChild", toParent: "toParent", twoWay: "twoWay" }); MockComponent.extend({ tag: "basic-colon", viewModel: viewModel }); var template = stache("<basic-colon "+ "toChild:from='valueA' toParent:to='valueB' twoWay:bind='valueC' "+ "on:vmevent='methodD()'" + "/>"); var MySimpleMap = SimpleMap.extend({ methodD: function(){ assert.ok(true, "on:vmevent bindings work"); } }); var parent = new MySimpleMap({ valueA: 'A', valueB: 'B', valueC: 'C' }); template(parent); assert.deepEqual(parent.get(), { valueA: 'A', valueB: 'toParent', valueC: 'C', }, "initial scope values correct"); assert.deepEqual(viewModel.get(), { toChild: "A", toParent: "toParent", twoWay: "C" }, "initial VM values correct"); // Change scope parent.set({ valueA: 'a', valueB: 'b', valueC: 'c' }); assert.deepEqual(viewModel.get(), { toChild: "a", toParent: "toParent", twoWay: "c" }, "scope set VM values correct"); // Change vm viewModel.set({ toChild: "to-child", toParent: "to-parent", twoWay: "two-way" }); assert.deepEqual(parent.get(), { valueA: "a", valueB: "to-parent", valueC: "two-way" }, "vm set scope values correct"); viewModel.dispatch({type: "vmevent"}); }); QUnit.test("getSiblingBindingData", function(assert) { var info = stacheBindings.getSiblingBindingData({name: "foo-ed:from", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModelOrAttribute", childEvent: undefined, parentToChild: true, childToParent: false, childName: "foo-ed", parentName: "bar", bindingAttributeName: "foo-ed:from", initializeValues: true, syncChildWithParent: false }, ":from"); info = stacheBindings.getSiblingBindingData({name: "foo-ed:bind", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModelOrAttribute", childEvent: undefined, parentToChild: true, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "foo-ed:bind", initializeValues: true, syncChildWithParent: true }, ":bind"); info = stacheBindings.getSiblingBindingData({name: "foo-ed:to", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModelOrAttribute", childEvent: undefined, parentToChild: false, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "foo-ed:to", initializeValues: true, syncChildWithParent: false }, ":to"); info = stacheBindings.getSiblingBindingData({name: "foo-ed:from", value: "bar"}, {favorViewModel: true}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModel", childEvent: undefined, parentToChild: true, childToParent: false, childName: "foo-ed", parentName: "bar", bindingAttributeName: "foo-ed:from", initializeValues: true, syncChildWithParent: false }, ":from, favorViewModel=true"); info = stacheBindings.getSiblingBindingData({name: "foo-ed:bind", value: "bar"}, {favorViewModel: true}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModel", childEvent: undefined, parentToChild: true, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "foo-ed:bind", initializeValues: true, syncChildWithParent: true }, ":bind, favorViewModel=true"); info = stacheBindings.getSiblingBindingData({name: "foo-ed:to", value: "bar"}, {favorViewModel: true}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModel", childEvent: undefined, parentToChild: false, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "foo-ed:to", initializeValues: true, syncChildWithParent: false }, ":to, favorViewModel=true"); }); QUnit.test("getSiblingBindingData for vm:", function(assert) { var info = stacheBindings.getSiblingBindingData({name: "vm:foo-ed:from", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModel", childEvent: undefined, parentToChild: true, childToParent: false, childName: "foo-ed", parentName: "bar", bindingAttributeName: "vm:foo-ed:from", initializeValues: true, syncChildWithParent: false }, ":from"); info = stacheBindings.getSiblingBindingData({name: "vm:foo-ed:bind", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModel", childEvent: undefined, parentToChild: true, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "vm:foo-ed:bind", initializeValues: true, syncChildWithParent: true }, ":bind"); info = stacheBindings.getSiblingBindingData({name: "vm:foo-ed:to", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModel", childEvent: undefined, parentToChild: false, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "vm:foo-ed:to", initializeValues: true, syncChildWithParent: false }, ":to"); info = stacheBindings.getSiblingBindingData({name: "vm:foo-ed:from", value: "bar"}, {favorViewModel: true}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModel", childEvent: undefined, parentToChild: true, childToParent: false, childName: "foo-ed", parentName: "bar", bindingAttributeName: "vm:foo-ed:from", initializeValues: true, syncChildWithParent: false }, ":from, favorViewModel=true"); info = stacheBindings.getSiblingBindingData({name: "vm:foo-ed:bind", value: "bar"}, {favorViewModel: true}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModel", childEvent: undefined, parentToChild: true, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "vm:foo-ed:bind", initializeValues: true, syncChildWithParent: true }, ":bind, favorViewModel=true"); info = stacheBindings.getSiblingBindingData({name: "vm:foo-ed:to", value: "bar"}, {favorViewModel: true}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModel", childEvent: undefined, parentToChild: false, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "vm:foo-ed:to", initializeValues: true, syncChildWithParent: false }, ":to, favorViewModel=true"); }); QUnit.test("getSiblingBindingData for el:", function(assert) { var info = stacheBindings.getSiblingBindingData({name: "el:foo-ed:from", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "attribute", childEvent: undefined, parentToChild: true, childToParent: false, childName: "foo-ed", parentName: "bar", bindingAttributeName: "el:foo-ed:from", initializeValues: true, syncChildWithParent: false }, ":from"); info = stacheBindings.getSiblingBindingData({name: "el:foo-ed:bind", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "attribute", childEvent: undefined, parentToChild: true, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "el:foo-ed:bind", initializeValues: true, syncChildWithParent: true }, ":bind"); info = stacheBindings.getSiblingBindingData({name: "el:foo-ed:to", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "attribute", childEvent: undefined, parentToChild: false, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "el:foo-ed:to", initializeValues: true, syncChildWithParent: false }, ":to"); info = stacheBindings.getSiblingBindingData({name: "el:foo-ed:from", value: "bar"}, null, null, null, true); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "attribute", childEvent: undefined, parentToChild: true, childToParent: false, childName: "foo-ed", parentName: "bar", bindingAttributeName: "el:foo-ed:from", initializeValues: true, syncChildWithParent: false }, ":from, favorViewModel=true"); info = stacheBindings.getSiblingBindingData({name: "el:foo-ed:bind", value: "bar"}, null, null, null, true); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "attribute", childEvent: undefined, parentToChild: true, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "el:foo-ed:bind", initializeValues: true, syncChildWithParent: true }, ":bind, favorViewModel=true"); info = stacheBindings.getSiblingBindingData({name: "el:foo-ed:to", value: "bar"}, null, null, null, true); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "attribute", childEvent: undefined, parentToChild: false, childToParent: true, childName: "foo-ed", parentName: "bar", bindingAttributeName: "el:foo-ed:to", initializeValues: true, syncChildWithParent: false }, ":to, favorViewModel=true"); }); QUnit.test("getSiblingBindingData works for value:to:on:click (#269)", function(assert) { var info = stacheBindings.getSiblingBindingData({name: "value:to:on:click", value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModelOrAttribute", childEvent: "click", parentToChild: false, childToParent: true, childName: "value", parentName: "bar", bindingAttributeName: "value:to:on:click", initializeValues: false, syncChildWithParent: false }, "new vm binding"); }); QUnit.test("decode values with To (#504)", function(assert) { var name = encoder.encode("goToHome:to"); var info = stacheBindings.getSiblingBindingData({name: name, value: "bar"}); assert.deepEqual(siblingsDataToInfo(info), { parent: "scope", child: "viewModelOrAttribute", childEvent: undefined, parentToChild: false, childToParent: true, childName: "goToHome", parentName: "bar", bindingAttributeName: "goToHome:to", initializeValues: true, syncChildWithParent: false }, "to parent binding"); }); canTestHelpers.dev.devOnlyTest("warning when binding to non-existing value (#136) (#119)", function(assert) { var teardown = canTestHelpers.dev.willWarn('This element does not have a viewModel. (Attempting to bind `target:vm:bind="source.bar"`)'); var template = stache("<div target:vm:bind='source.bar'/>"); var map = new SimpleMap({ source: new SimpleMap({ foo: "foo" }) }); template(map); assert.equal(teardown(), 1, 'warning shown'); }); QUnit.test("parent stache is able to teardown child bindings (#278)", function(assert) { var map = new SimpleMap({value: "VALUE"}); var template = stache("<div>{{#if value}}<span><input value:bind='value'/></span>{{/if}}</div>"); var frag = template(map), input = frag.firstChild.getElementsByTagName("input")[0]; this.fixture.appendChild(frag); assert.equal(input.value, "VALUE", "value set initially"); map.set("value",""); assert.equal(input.value, "VALUE", "value should not have been updated"); }); QUnit.test("bindings still work for moved elements (#460)", function(assert) { var done = assert.async(); var map = new SimpleMap({value: "first"}); var template = stache("<input value:bind='value'/>"); var frag = template(map); var input = frag.firstChild; this.fixture.appendChild(frag); // Move the input to inside the div var div = doc.createElement("div"); this.fixture.appendChild(div); div.appendChild(input); testHelpers.afterMutation(function () { map.set("value", "second"); assert.equal(input.value, "second", "value should have been updated"); input.value = "third"; domEvents.dispatch(input, "change"); assert.equal(map.get("value"), "third", "map should have been updated"); done(); }); }); });