Index: chrome/test/data/extensions/samples/benchmark/jst/jstemplate_test.js |
=================================================================== |
--- chrome/test/data/extensions/samples/benchmark/jst/jstemplate_test.js (revision 0) |
+++ chrome/test/data/extensions/samples/benchmark/jst/jstemplate_test.js (revision 0) |
@@ -0,0 +1,357 @@ |
+// 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)); |
+} |
+ |