UNPKG

can-stache

Version:

Live binding handlebars templates

350 lines (300 loc) 9.59 kB
var QUnit = require("steal-qunit"); var stache = require("can-stache"); var DefineMap = require("can-define/map/map"); var DefineList = require("can-define/list/list"); var define = require("can-define"); var makeStacheTestHelpers = require("./helpers"); var DOCUMENT = require("can-globals/document/document"); var stacheTestHelpers = makeStacheTestHelpers(DOCUMENT()); QUnit.module("can-stache with can-define"); QUnit.test("basic replacement and updating", function(assert) { var map = new DefineMap({ message: "World" }); var stashed = stache("<h1 class='foo'>{{message}}</h1>"); var frag = stashed(map); assert.equal( stacheTestHelpers.cloneAndClean(frag).firstChild.firstChild.nodeValue, "World","got back the right text"); }); QUnit.test('Helper each inside a text section (attribute) (#8)', function(assert){ var template = stache('<div class="{{#each list}}{{.}} {{/}}"></div>'); var vm = new DefineMap({ list: new DefineList(['one','two']) }); var frag = template(vm); var className = stacheTestHelpers.cloneAndClean(frag).firstChild.className; assert.equal( className, 'one two ' ); vm.list.push('three'); className = stacheTestHelpers.cloneAndClean(frag).firstChild.className; assert.equal( className, 'one two three ' ); }); QUnit.test("Using #each on a DefineMap", function(assert){ var template = stache("{{#each obj}}{{%key}}{{.}}{{/each}}"); var VM = DefineMap.extend({ seal: false }, { foo: "string", bar: "string" }); var vm = new VM({ foo: "bar", bar: "foo" }); vm.set("baz", "qux"); var frag = template({ obj: vm }); var first = stacheTestHelpers.cloneAndClean(frag).firstChild, second = first.nextSibling.nextSibling, third = second.nextSibling.nextSibling; assert.equal(first.nodeValue, "foo"); assert.equal(first.nextSibling.nodeValue, "bar"); assert.equal(second.nodeValue, "bar"); assert.equal(second.nextSibling.nodeValue, "foo"); assert.equal(third.nodeValue, "baz"); assert.equal(third.nextSibling.nodeValue, "qux"); }); QUnit.test("{{%index}} work with {{#key}} iteration", function(assert) { var template = stache('<p>{{#iter}}<span>{{%index}}</span>{{/iter}}</p>'); var div = document.createElement('div'); var dom = template({iter: new DefineList(['hey', 'there'])}); div.appendChild(dom); var span = div.getElementsByTagName('span'); assert.equal((span[0].innerHTML), '0', 'iteration for %index'); assert.equal((span[1].innerHTML), '1', 'iteration for %index'); }); // cf. https://github.com/canjs/can-stache/issues/180 QUnit.test("Renders live bound `{{defineList[0]}}` and `{{defineList.0}}` data (#180)", function(assert) { var list = new DefineList([ 'zero' ]); var renderer = stache('<div><span class="brackets">{{list[0]}}</span><span class="dot">{{list.0}}</span>'); //var html = renderer({ list: list }); var html = document.getElementById('qunit-fixture'); html.appendChild(renderer({ list: list })); // should render: // <div> // <span class="brackets">zero</span> // <span class="dot">zero</span> // </div> assert.equal(html.querySelector('.brackets').textContent, 'zero', '{{list[0]}}'); assert.equal(html.querySelector('.dot').textContent, 'zero', '{{list.0}}'); list.set(0, 'even'); assert.equal(html.querySelector('.brackets').textContent, 'even', '{{list[0]}} set as list.set(0, even)'); assert.equal(html.querySelector('.dot').textContent, 'even', '{{list.0}} set as list.set(0, even)'); }); QUnit.test("Renders #each live bound `defineList[%index]` data (#180)", function(assert) { var list = new DefineList([true, false, true]); var renderer = stache('<form>{{#each list}}<input type="checkbox" value="{{%index}}" class="{{#if list[%index]}}selected{{/if}}" />{{/each}}</form>'); var html = renderer({ list: list }); // should render: // <form> // <input type="checkbox" value="0" class="selected" /> // <input type="checkbox" value="1" class /> // <input type="checkbox" value="2" class="selected" /> // </form> assert.equal(html.querySelectorAll('input').length, 3, 'three checkboxes'); assert.equal(html.querySelector('[value="0"]').className, 'selected', 'first IS selected'); assert.equal(html.querySelector('[value="1"]').className, '', 'second NOT selected'); assert.equal(html.querySelector('[value="2"]').className, 'selected', 'third IS selected'); list.set(0, false); list[1] = true; list[2] = false; list.push(true); assert.equal(html.querySelectorAll('input').length, 4, 'AFTER DATA CHANGES: four checkboxes'); assert.equal(html.querySelector('[value="0"]').className, '', 'first NOT selected'); assert.equal(html.querySelector('[value="1"]').className, 'selected', 'second IS selected'); assert.equal(html.querySelector('[value="2"]').className, '', 'third NOT selected'); assert.equal(html.querySelector('[value="3"]').className, 'selected', 'fourth IS selected'); list.shift(); list.pop(); assert.equal(html.querySelectorAll('input').length, 2, 'AFTER DATA CHANGES: two checkboxes'); assert.equal(html.querySelector('[value="0"]').className, 'selected', 'first IS selected'); assert.equal(html.querySelector('[value="1"]').className, '', 'second NOT selected'); }); QUnit.test("iterate a DefineMap with {{#each}} (#can-define/125)", function(assert) { var template = stache('<p>{{#each iter}}<span>{{%key}} {{.}}</span>{{/each}}</p>'); var div = document.createElement('div'); var dom = template({iter: new DefineMap({first: "justin", last: "meyer"})}); div.appendChild(dom); var span = div.getElementsByTagName('span'); assert.equal((span[0].innerHTML), 'first justin', 'first'); assert.equal((span[1].innerHTML), 'last meyer', 'last'); }); QUnit.test("Stache with single property", function(assert) { var Typer = define.Constructor({ foo: { type: 'string' } }); var template = stache('{{foo}}'); var t = new Typer({ foo: 'bar' }); var frag = template(t); assert.equal(stacheTestHelpers.cloneAndClean(frag).firstChild.nodeValue, 'bar'); t.foo = "baz"; assert.equal(stacheTestHelpers.cloneAndClean(frag).firstChild.nodeValue, 'baz'); }); QUnit.test("stache with double property", function(assert) { var nailedIt = 'Nailed it'; var Example = define.Constructor({ name: { value: nailedIt } }); var NestedMap = define.Constructor({ isEnabled: { value: true }, test: { Value: Example }, examples: { type: { one: { Value: Example }, two: { type: { deep: { Value: Example } }, Value: Object } }, Value: Object } }); var nested = new NestedMap(); var template = stache('{{test.name}}'); var frag = template(nested); assert.equal(stacheTestHelpers.cloneAndClean(frag).firstChild.nodeValue, nailedIt); }); QUnit.test("Stache with one nested property", function(assert) { var nailedIt = 'Nailed it'; var Example = define.Constructor({ name: { value: nailedIt } }); var NestedMap = define.Constructor({ isEnabled: { value: true }, test: { Value: Example }, examples: { type: { one: { Value: Example }, two: { type: { deep: { Value: Example } }, Value: Object } }, Value: Object } }); var nested = new NestedMap(); var template = stache('{{examples.one.name}}'); var frag = template(nested); assert.equal(stacheTestHelpers.cloneAndClean(frag).firstChild.nodeValue, nailedIt); }); QUnit.test("Stache with two nested property", function(assert) { var nailedIt = 'Nailed it'; var Example = define.Constructor({ name: { value: nailedIt } }); var NestedMap = define.Constructor({ isEnabled: { value: true }, test: { Value: Example }, examples: { type: { one: { Value: Example }, two: { type: { deep: { Value: Example } }, Value: Object } }, Value: Object } }); var nested = new NestedMap(); var template = stache('{{examples.two.deep.name}}'); var frag = template(nested); assert.equal(stacheTestHelpers.cloneAndClean(frag).firstChild.nodeValue, nailedIt); }); QUnit.test('list.sort a list of DefineMaps', function(assert) { var Account = DefineMap.extend({ name: "string", amount: "number", slug: { serialize: true, get: function(){ return this.name.toLowerCase().replace(/ /g,'-').replace(/[^\w-]+/g,''); } } }); Account.List = DefineList.extend({ "*": Account, limit: "number", skip: "number", total: "number" }); var accounts = new Account.List([ { name: "Savings", amount: 20.00 }, { name: "Checking", amount: 103.24 }, { name: "Kids Savings", amount: 48155.13 } ]); accounts.limit = 3; var template = stache('{{#each accounts}}{{name}},{{/each}}')({accounts: accounts}); assert.equal(template.textContent, "Savings,Checking,Kids Savings,", "template rendered properly."); accounts.sort(function(a, b){ if (a.name < b.name) { return -1; } else if (a.name > b.name){ return 1; } else { return 0; } }); assert.equal(accounts.length, 3); assert.equal(template.textContent, "Checking,Kids Savings,Savings,", "template updated properly."); // Try sorting in reverse on the dynamic `slug` property accounts.sort(function(a, b){ if (a.slug < b.slug) { return 1; } else if (a.slug > b.slug){ return -1; } else { return 0; } }); assert.equal(accounts.length, 3); assert.equal(accounts.limit, 3, "expandos still present after sorting/replacing."); assert.equal(template.textContent, "Savings,Kids Savings,Checking,", "template updated properly."); });