123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- // Copyright 2006 Google Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- // implied. See the License for the specific language governing
- // permissions and limitations under the License.
- /**
- * @author Steffen Meschkat (mesch@google.com)
- * @fileoverview Unittest and examples for jstemplates.
- */
- function jstWrap(data, template) {
- return jstProcess(new JsEvalContext(data), template);
- }
- function testJstSelect() {
- // Template cardinality from jsselect.
- var t = document.getElementById('t1');
- var d = {
- items: [ 'A', 'B', 'C', '' ]
- }
- jstWrap(d, t);
- var h = t.innerHTML;
- var clone = domCloneNode(t);
- assertTrue(/>A<\/div>/.test(h));
- assertTrue(/>B<\/div>/.test(h));
- assertTrue(/>C<\/div>/.test(h));
- assertTrue(/><\/div>/.test(h));
- // Reprocessing with identical data.
- jstWrap(d, t);
- assertAttributesMatch(t, clone);
- // Reprocessing with changed data.
- d.items[1] = 'BB';
- jstWrap(d, t);
- h = t.innerHTML;
- assertTrue(/>A<\/div>/.test(h));
- assertFalse(/>B<\/div>/.test(h));
- assertTrue(/>BB<\/div>/.test(h));
- assertTrue(/>C<\/div>/.test(h));
- // Reprocessing with dropped data.
- d.items.pop();
- d.items.pop();
- jstWrap(d, t);
- h = t.innerHTML;
- assertTrue(/>A<\/div>/.test(h));
- assertTrue(/>BB<\/div>/.test(h));
- assertFalse(/>C<\/div>/.test(h));
- assertFalse(/><\/div>/.test(h));
- // Reprocessing with dropped data, once more.
- d.items.pop();
- jstWrap(d, t);
- h = t.innerHTML;
- assertTrue(/>A<\/div>/.test(h));
- assertFalse(/>BB<\/div>/.test(h));
- assertFalse(/>C<\/div>/.test(h));
- // Reprocessing with empty data -- the last template instance is
- // preserved, and only hidden.
- d.items.pop();
- jstWrap(d, t);
- assertTrue(/>A<\/div>/.test(h));
- assertFalse(/>BB<\/div>/.test(h));
- assertFalse(/>C<\/div>/.test(h));
- // Reprocessing with added data.
- d.items.push('D');
- jstWrap(d, t);
- h = t.innerHTML;
- assertFalse(/>A<\/div>/.test(h));
- assertTrue(/>D<\/div>/.test(h));
- }
- function testJstDisplay() {
- var t = document.getElementById('t2');
- var d = {
- display: true
- }
- jstWrap(d, t);
- var h = t.innerHTML;
- assertFalse(/display:\s*none/.test(h));
- d.display = false;
- jstWrap(d, t);
- h = t.innerHTML;
- assertTrue(/display:\s*none/.test(h));
- // Check that 'this' within js expressions is the template node
- t = document.getElementById('t2a');
- d = {
- showId: 'x'
- };
- jstWrap(d, t);
- h = t.innerHTML;
- assertFalse(/display:\s*none/.test(h));
- d.showId = 'y';
- jstWrap(d, t);
- h = t.innerHTML;
- assertTrue(/display:\s*none/.test(h));
- }
- function stringContains(str, sub) {
- return str.indexOf(sub) != -1;
- }
- function testJseval() {
- var data = {};
- var counter = 0;
- var ctx = new JsEvalContext(data);
- ctx.setVariable("callback1", function() {
- ++counter;
- });
- ctx.setVariable("callback2", function() {
- counter *= 2;
- });
- jstProcess(ctx, document.getElementById('testJseval1'));
- assertEquals("testJseval1", 1, counter);
- jstProcess(ctx, document.getElementById('testJseval2'));
- assertEquals("testJseval2", 4, counter);
- }
- function testJstValues() {
- var t = document.getElementById('t3');
- var d = {};
- jstWrap(d, t);
- var h = t.innerHTML;
- assertTrue(stringContains(h, 'http://maps.google.com/'));
- var t3a = document.getElementById('t3a');
- assertEquals('http://maps.google.com/', t3a.foo.bar.baz);
- assertEquals('http://maps.google.com/', t3a.bar);
- assertEquals('red', t3a.style.backgroundColor);
- }
- function testJstTransclude() {
- var t = document.getElementById('t4');
- var p = document.getElementById('parent');
- var d = {};
- jstWrap(d, t);
- var h = p.innerHTML;
- assertTrue(h, stringContains(h, 'http://maps.google.com/'));
- }
- function assertAttributesMatch(first, second) {
- assertEquals('assertAttributesMatch: number of child nodes',
- jsLength(first.childNodes), jsLength(second.childNodes));
- var b = second.firstChild;
- for (var a = first.firstChild; a; a = a.nextSibling) {
- var att = a.attributes;
- if (att) {
- assertTrue(b.attributes != null);
- assertEquals('assertAttributesMatch: number of attribute nodes',
- att.length, b.attributes.length);
- for (var i = 0; i < jsLength(att); i++) {
- var a = att[i];
- assertEquals('assertAttributesMatch: value of attribute ' + a.name,
- a.value, b.getAttribute(a.name));
- }
- } else {
- assertNull(b.attributes);
- }
- b = b.nextSibling;
- }
- }
- function testJsskip() {
- var div = domCreateElement(document, "DIV");
- div.innerHTML = [
- '<div jseval="outercallback()" jsskip="1">',
- '<div jseval="innercallback()">',
- '</div>',
- '</div>'
- ].join('');
- var data = {};
- var ctx = new JsEvalContext(data);
- var outerCalled = false;
- ctx.setVariable("outercallback", function() {
- outerCalled = true;
- });
- var innerCalled = false;
- ctx.setVariable("innercallback", function() {
- innerCalled = true;
- });
- jstProcess(ctx, div);
- assertTrue(outerCalled);
- assertFalse(innerCalled);
- }
- function testScalarContext() {
- var t = document.getElementById('testScalarContext');
- jstWrap(true, t);
- assertTrue(/>true</.test(t.innerHTML));
- jstWrap(false, t);
- assertTrue(/>false</.test(t.innerHTML));
- jstWrap(0, t);
- assertTrue(/>0</.test(t.innerHTML));
- jstWrap("foo", t);
- assertTrue(/>foo</.test(t.innerHTML));
- jstWrap(undefined, t);
- assertTrue(/>undefined</.test(t.innerHTML));
- jstWrap(null, t);
- assertTrue(/>null</.test(t.innerHTML));
- }
- function testJstLoadTemplate() {
- var wrapperId = 'testJstLoadTemplateWrapper';
- var id = 'testJstLoadTemplate';
- jstLoadTemplate_(document, '<div id="' + id + '">content</div>', wrapperId);
- var wrapperElem = document.getElementById(wrapperId);
- assertTrue('Expected wrapper element to be in document',
- !!wrapperElem);
- var newTemplate = document.getElementById(id);
- assertTrue('Expected newly loaded template to be in document',
- !!newTemplate);
- assertTrue('Expected wrapper to be grandparent of template',
- newTemplate.parentNode.parentNode == wrapperElem);
- // Make sure the next template loaded with the same wrapper id re-uses the
- // wrapper element.
- var id2 = 'testJstLoadTemplate2';
- jstLoadTemplate_(document, '<div id="' + id2 + '">content</div>', wrapperId);
- var newTemplate2 = document.getElementById(id2);
- assertTrue('Expected newly loaded template to be in document',
- !!newTemplate2);
- assertTrue('Expected wrapper to be grandparent of template',
- newTemplate2.parentNode.parentNode == wrapperElem);
- }
- function testJstGetTemplateFromDom() {
- var element;
- // Get by id a template in the document
- // Success
- element = jstGetTemplate('t1');
- assertTrue("Asserted jstGetTemplate('t1') to return a dom element",
- !!element);
- // Failure
- element = jstGetTemplate('asdf');
- assertFalse("Asserted jstGetTemplate('asdf') to return null",
- !!element);
- }
- function testJstGetTemplateFromFunction() {
- var element;
- // Fetch a jstemplate by id from within a html string, passed via a function.
- function returnHtmlWithId(id) {
- var html =
- '<div>' +
- '<div id="' + id + '">Here is the template</div>' +
- '</div>';
- return html;
- }
- // Success
- element = jstGetTemplate('template',
- partial(returnHtmlWithId, 'template'));
- assertTrue("Expected jstGetTemplate('template') to return a dom element",
- !!element);
- // Failure
- element = jstGetTemplate('asdf',
- partial(returnHtmlWithId, 'zxcv'));
- assertFalse("Expected jstGetTemplate('zxcv') to return null",
- !!element);
- }
- function testPrepareNode() {
- var id, node;
- // Reset the cache so we're testing from a known state.
- JstProcessor.jstCache_ = {};
- JstProcessor.jstCache_[0] = {};
- // Skip pre-processed nodes. Preprocessed nodes are those with a
- // PROP_jstcache property.
- var t = document.getElementById('t1');
- var caches = [];
- caches.push(JstProcessor.prepareNode_(t));
- caches.push(JstProcessor.prepareNode_(t));
- assertEquals('The same cache should be returned on each call to prepareNode',
- caches[0], caches[1]);
- // Preprocessing a node with a jst attribute should return a valid struct
- id = 'testPrepareNodeWithAttributes';
- jstLoadTemplate_(document, '<div id="' + id + '" jsskip="1"></div>');
- node = document.getElementById(id);
- var cache = JstProcessor.prepareNode_(node);
- try {
- var jsskip = cache['jsskip']({}, {});
- } catch (e) {
- fail('Exception when evaluating jsskip from cache');
- }
- assertEquals(1, jsskip);
- }
- function testPrepareNodeWithNoAttributes() {
- // Preprocessing a node with no jst attributes should return null
- var id = 'testPrepareNodeNoAttributes';
- jstLoadTemplate_(document, '<div id="' + id + '"></div>');
- var node = document.getElementById(id);
- assertEquals('prepareNode with no jst attributes should return default',
- JstProcessor.jstcache_[0], JstProcessor.prepareNode_(node));
- }
- function testJsVars() {
- var template = document.createElement('div');
- document.body.appendChild(template);
- template.innerHTML = '<div jsvars="foo:\'foo\';bar:true;$baz:1"></div>';
- var context = new JsEvalContext;
- jstProcess(context, template);
- assertEquals('foo', context.getVariable('foo'));
- assertEquals(1, context.getVariable('$baz'));
- assertTrue(context.getVariable('bar'));
- assertUndefined(context.getVariable('foobar'));
- }
- function testCacheReuse() {
- var template = document.createElement('div');
- document.body.appendChild(template);
- template.innerHTML =
- '<div jsvars="foo:\'foo\';bar:true;$baz:1"></div>' +
- '<span jsvars="foo:\'foo\';bar:true;$baz:1"></span>';
- JstProcessor.prepareTemplate_(template);
- assertEquals(template.firstChild.getAttribute(ATT_jstcache),
- template.lastChild.getAttribute(ATT_jstcache));
- }
|