aboutsummaryrefslogtreecommitdiff
path: root/includes/js/dojox/dtl/tests
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dojox/dtl/tests')
-rw-r--r--includes/js/dojox/dtl/tests/context.js79
-rw-r--r--includes/js/dojox/dtl/tests/demo_Templated_Jaxer.html87
-rw-r--r--includes/js/dojox/dtl/tests/html/buffer.js35
-rw-r--r--includes/js/dojox/dtl/tests/html/tag.js233
-rw-r--r--includes/js/dojox/dtl/tests/html/util.js160
-rw-r--r--includes/js/dojox/dtl/tests/module.js15
-rw-r--r--includes/js/dojox/dtl/tests/runTests.html9
-rw-r--r--includes/js/dojox/dtl/tests/templates/hello.html1
-rw-r--r--includes/js/dojox/dtl/tests/templates/pocket.html1
-rw-r--r--includes/js/dojox/dtl/tests/templates/pocket2.html1
-rw-r--r--includes/js/dojox/dtl/tests/text/filter.js740
-rw-r--r--includes/js/dojox/dtl/tests/text/load.js6
-rw-r--r--includes/js/dojox/dtl/tests/text/tag.js480
13 files changed, 1847 insertions, 0 deletions
diff --git a/includes/js/dojox/dtl/tests/context.js b/includes/js/dojox/dtl/tests/context.js
new file mode 100644
index 0000000..a366098
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/context.js
@@ -0,0 +1,79 @@
+if(!dojo._hasResource["dojox.dtl.tests.context"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tests.context"] = true;
+dojo.provide("dojox.dtl.tests.context");
+
+dojo.require("dojox.dtl");
+dojo.require("dojox.dtl.Context");
+
+doh.register("dojox.dtl.context",
+ [
+ function test_context_creation(t){
+ var context = new dojox.dtl.Context({ foo: "foo", bar: "bar" });
+ t.is("foo", context.foo);
+ t.is("bar", context.bar);
+ },
+ function test_context_push(t){
+ var context = new dojox.dtl.Context({ foo: "foo", bar: "bar" });
+ context.push();
+ for(var key in context._dicts[0]){
+ t.t(key == "foo" || key == "bar");
+ }
+ },
+ function test_context_pop(t){
+ var context = new dojox.dtl.Context({ foo: "foo", bar: "bar" });
+ context.push();
+ t.is("undefined", typeof context.foo);
+ t.is("undefined", typeof context.bar);
+ context.pop();
+ t.is("foo", context.foo);
+ t.is("bar", context.bar);
+ },
+ function test_context_overpop(t){
+ var context = new dojox.dtl.Context();
+ try{
+ context.pop();
+ t.t(false);
+ }catch(e){
+ t.is("pop() called on empty Context", e.message);
+ }
+ },
+ function test_context_filter(t){
+ var context = new dojox.dtl.Context({ foo: "one", bar: "two", baz: "three" });
+ var filtered = context.filter("foo", "bar");
+ t.is(filtered.foo, "one");
+ t.is(filtered.bar, "two");
+ t.f(filtered.baz);
+
+ filtered = context.filter({ bar: true, baz: true });
+ t.f(filtered.foo);
+ t.is(filtered.bar, "two");
+ t.is(filtered.baz, "three");
+
+ filtered = context.filter(new dojox.dtl.Context({ foo: true, baz: true }));
+ t.is(filtered.foo, "one");
+ t.f(filtered.bar);
+ t.is(filtered.baz, "three");
+ },
+ function test_context_extend(t){
+ var context = new dojox.dtl.Context({ foo: "one" });
+ var extended = context.extend({ bar: "two", baz: "three" });
+ t.is(extended.foo, "one");
+ t.is(extended.bar, "two");
+ t.is(extended.baz, "three");
+
+ extended = context.extend({ barr: "two", bazz: "three" });
+ t.is(extended.foo, "one");
+ t.f(extended.bar);
+ t.f(extended.baz);
+ t.is(extended.barr, "two");
+ t.is(extended.bazz, "three");
+
+ t.f(context.bar)
+ t.f(context.baz);
+ t.f(context.barr);
+ t.f(context.bazz);
+ }
+ ]
+);
+
+}
diff --git a/includes/js/dojox/dtl/tests/demo_Templated_Jaxer.html b/includes/js/dojox/dtl/tests/demo_Templated_Jaxer.html
new file mode 100644
index 0000000..29e5470
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/demo_Templated_Jaxer.html
@@ -0,0 +1,87 @@
+<html>
+ <head>
+ <title>Demo using dojox.dtl._Templated</title>
+ <script runat="server">
+ djConfig = {baseUrl:"/dojo/",usePlainJson: true, parseOnLoad: true};
+ </script>
+ <script runat="server" type="text/javascript" src="../../../dojo/dojo.js"></script>
+ <script runat="server" type="text/javascript">
+ dojo.require("dojo.jaxer");
+ dojo.require("dijit.dijit");
+ dojo.require("dojox.dtl._Templated");
+ dojo.require("dojo.parser");
+
+ dojo.declare("Fruit", [dijit._Widget, dojox.dtl._Templated], {
+ oldRepl: "Fruit: ",
+ _dijitTemplateCompat: true,
+ items: ["apple", "banana", "orange"],
+ keyUp: function(e){
+ if(e.keyCode == dojo.keys.ENTER){
+ var i = dojo.indexOf(this.items, e.target.value);
+ if(i != -1){
+ this.items.splice(i, 1);
+ }else{
+ this.items.push(e.target.value);
+ }
+ e.target.value = "";
+ this.render();
+ dojo.query("input", this.domNode).forEach("item.focus();");
+ }
+ },
+ templateString: '<div><input dojoAttachEvent="onkeyup: keyUp"><ul>{% for item in items %}<li>${oldRepl} {{ item }}</li>{% endfor %}</ul></div>'
+ });
+ </script>
+ <body>
+ <h1>Using Dojo's Django Template language on Jaxer</h1>
+ <p>
+ Aptana's Jaxer is server side JavaScript (SSJS) server. With some modifications to
+ a web page, Dojo can be run on the server. With Dojo running on the server, you can
+ utilize the Dojo's Django Template library rendering engine to do templating within
+ Jaxer. The latest build of Dojo includes some patches to properly work with Jaxer,
+ so you need a build of Dojo later than 2/18/08 to work with Jaxer. Next, the
+ following modifications to your page are needed to run Jaxer:
+ <ul>
+ <li>
+ You must explicitly set the base url of the Dojo library. Jaxer does not provide
+ the ability for Dojo to auto-detect the base url as it can in other environments.
+ Therefore you must declare the base url with the djConfig global variable:
+ <pre>
+ &lt;script runat="server">
+ djConfig = {baseUrl:"/dojo/", // use the base path of dojo here
+ usePlainJson: true, parseOnLoad: true};
+ &lt;/script>
+ </pre>
+ </li>
+ <li>
+ Next, you must add the runat attribute with a value of "server" to all of the script
+ tags that you want executed on the server. Your script tags should look like:
+ <pre>
+ &lt;script runat="server" type="text/javascript" src="../../../dojo/dojo.js">&lt;/script>
+ </pre>
+ </li>
+ <li>
+ Last, you must dojo.require("dojo.jaxer") with a script tag. This should immediately
+ follow the declaration of dojo.js:
+ <pre>
+ &lt;script runat="server" type="text/javascript" src="../../../dojo/dojo.js">&lt;/script>
+ &lt;script runat="server" type="text/javascript">dojo.require("dojo.jaxer");&lt;/script>
+ </pre>
+ </li>
+ </ul>
+ </p>
+ <p>
+ Once this is done, Dojo should load in Jaxer, and you can utilize the library capabilities of
+ Dojo. In particular, you can now use DTL renderer as you would on
+ the browser. If you are running this in Jaxer, below should be a working demonstration of
+ a template that is rendered on the server.
+ </p>
+ <div dojoType="Fruit"></div>
+ <p>
+ It is important to note that Jaxer is not capable of transferring the programmaticaly set
+ event handlers for widgets, it can only send the static HTML to the browser. This means
+ you can use DTL as a templating engine to create HTML on the server, but Dojo client side widgets
+ are still necessary if you want to use interactive widgets on the browser.
+ </p>
+ </body>
+ </head>
+</html> \ No newline at end of file
diff --git a/includes/js/dojox/dtl/tests/html/buffer.js b/includes/js/dojox/dtl/tests/html/buffer.js
new file mode 100644
index 0000000..3077d8c
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/html/buffer.js
@@ -0,0 +1,35 @@
+if(!dojo._hasResource["dojox.dtl.tests.html.buffer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tests.html.buffer"] = true;
+dojo.provide("dojox.dtl.tests.html.buffer");
+
+dojo.require("dojox.dtl.html");
+dojo.require("dojox.dtl.Context");
+dojo.require("dojox.dtl.tests.html.util");
+
+doh.register("dojox.dtl.html.buffer",
+ [
+ function test_insertion_order_text(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ first: false,
+ last: false
+ });
+
+ var template = new dd.HtmlTemplate("<div>{% if first %}first{% endif %}middle{% if last %}last{% endif %}</div>");
+ t.is("<div>middle</div>", dd.tests.html.util.render(template, context));
+
+ context.first = true;
+ t.is("<div>firstmiddle</div>", dd.tests.html.util.render(template, context));
+
+ context.first = false;
+ context.last = true;
+ t.is("<div>middlelast</div>", dd.tests.html.util.render(template, context));
+
+ context.first = true;
+ t.is("<div>firstmiddlelast</div>", dd.tests.html.util.render(template, context));
+ }
+ ]
+);
+
+}
diff --git a/includes/js/dojox/dtl/tests/html/tag.js b/includes/js/dojox/dtl/tests/html/tag.js
new file mode 100644
index 0000000..c964913
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/html/tag.js
@@ -0,0 +1,233 @@
+if(!dojo._hasResource["dojox.dtl.tests.html.tag"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tests.html.tag"] = true;
+dojo.provide("dojox.dtl.tests.html.tag");
+
+dojo.require("dojox.dtl.html");
+dojo.require("dojox.dtl.Context");
+dojo.require("dojox.dtl.tests.html.util");
+
+doh.register("dojox.dtl.html.tag",
+ [
+ function test_errors(t){
+ var dd = dojox.dtl;
+ var template;
+
+ // No root node after rendering
+ var found = false;
+ try {
+ template = new dd.HtmlTemplate('No div');
+ dd.tests.html.util.render(template);
+ }catch(e){
+ t.is("Text should not exist outside of the root node in template", e.message);
+ found = true;
+ }
+ t.t(found);
+
+ var context = new dojox.dtl.Context({test: "Pocket"});
+ found = false;
+ try {
+ template = new dd.HtmlTemplate('{{ test }}');
+ dd.tests.html.util.render(template, context);
+ }catch(e){
+ t.is("Text should not exist outside of the root node in template", e.message);
+ found = true;
+ }
+ t.t(found);
+
+ template = new dd.HtmlTemplate('<div></div>extra content');
+ found = false;
+ try {
+ dd.tests.html.util.render(template);
+ }catch(e){
+ t.is("Content should not exist outside of the root node in template", e.message);
+ found = true;
+ }
+ t.t(found);
+
+ // More than one top-level node (except for blocks)
+ template = new dd.HtmlTemplate('<div></div><div></div>');
+ found = false;
+ try {
+ dd.tests.html.util.render(template);
+ }catch(e){
+ t.is("Content should not exist outside of the root node in template", e.message);
+ found = true;
+ }
+ t.t(found);
+
+ // Logic block rules out any root node
+ template = new dd.HtmlTemplate('{% if missing %}<div></div>{% endif %}');
+ found = false;
+ try {
+ dd.tests.html.util.render(template);
+ }catch(e){
+ t.is("Rendered template does not have a root node", e.message);
+ found = true;
+ }
+ t.t(found);
+ },
+ function test_structures(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ actions: ["ate", "picked"],
+ items: [
+ {
+ name: "apple"
+ },
+ {
+ name: "banana",
+ date: new Date(2007, 2, 16, 14, 30, 10)
+ },
+ {
+ name: "orange",
+ date: new Date(2008, 0, 1, 12, 0, 0)
+ }
+ ]
+ });
+
+ var template = new dd.HtmlTemplate('<div><ul>I {% for action in actions %}{% if not forloop.first %}, {% endif %}{{action}}{% endfor %} the following:<ul>{% for item in items %}<li>{{ item.name }}{% if item.date %} at {{ item.date|date:"P" }}{% endif %}</li>{% endfor %}</ul></ul></div>');
+ t.is('<div><ul>I ate, picked the following:<ul><li>apple</li><li>banana at 2:30 pm</li><li>orange at noon</li></ul></ul></div>', dd.tests.html.util.render(template, context));
+ },
+ function test_tag_extend(t){
+ // Problems to look for:
+ // * Content outside of blocks
+ },
+ function test_tag_for(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ items: ["apple", "banana", "lemon"]
+ });
+ var template = new dd.HtmlTemplate('<div><ul>{% for item in items %}<li class="{{ item|length }}">{{ item }}</li>{% endfor %}</ul></div>');
+
+ t.is('<div><ul><li class="5">apple</li><li class="6">banana</li><li class="5">lemon</li></ul></div>', dd.tests.html.util.render(template, context));
+
+ // The line break is there to make sure our regex works
+ template = new dd.HtmlTemplate('<div><select>{% for item in items %}<option>{{ item }}</option>\n{% endfor %}</select></div>');
+
+ t.is('<div><select><option>apple</option><option>banana</option><option>lemon</option></select></div>', dd.tests.html.util.render(template, context));
+ },
+ function test_tag_if(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({key: true});
+ var template = new dd.HtmlTemplate('{% if key %}<div>has key</div>{% else %}<div>no key</div>{% endif %}');
+ t.is("<div>has key</div>", dd.tests.html.util.render(template, context));
+ context.key = false;
+ t.is("<div>no key</div>", dd.tests.html.util.render(template, context));
+ },
+ function test_tag_ifchanged(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ year: 2008,
+ days: [
+ new Date(2008, 0, 12),
+ new Date(2008, 0, 28),
+ new Date(2008, 1, 1),
+ new Date(2008, 1, 1),
+ new Date(2008, 1, 1)
+ ]
+ });
+
+ var template = new dd.HtmlTemplate("<div><h1>Archive for {{ year }}</h1>"+
+"{% for date in days %}"+
+'{% ifchanged %}<h3>Month: </h3><h3>{{ date|date:"F" }}</h3>{% endifchanged %}'+
+'<a href="{{ date|date:\'M/d\'|lower }}/">{{ date|date:\'j\' }}</a>'+
+"{% endfor %}</div>");
+
+ t.is('<div><h1>Archive for 2008</h1>'+
+'<h3>Month: </h3><h3>January</h3>'+
+'<a href="jan/12/">12</a>'+
+'<a href="jan/28/">28</a>'+
+'<h3>Month: </h3><h3>February</h3>'+
+'<a href="feb/01/">1</a>'+
+'<a href="feb/01/">1</a>'+
+'<a href="feb/01/">1</a></div>', dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate('<div>{% for date in days %}'+
+'{% ifchanged date.date %} {{ date.date }} {% endifchanged %}'+
+'{% ifchanged date.hour date.date %}'+
+'{{ date.hour }}'+
+'{% endifchanged %}'+
+'{% endfor %}</div>');
+ t.is('<div> 2008-01-12 0 2008-01-28 0 2008-02-01 0</div>', dd.tests.html.util.render(template, context));
+ },
+ function test_tag_ifequal(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ items: [
+ { name: "apple", color: "red" },
+ { name: "banana", color: "yellow" },
+ { name: "pear", color: "green" },
+ { name: "kiwi", color: "brown" }
+ ],
+ edit_item: "banana"
+ });
+
+ var template = new dd.HtmlTemplate("<div><ul>{% for item in items %}<li>{{ item.name }}</li>{% endfor %}</ul></div>");
+ t.is('<div><ul><li>apple</li><li>banana</li><li>pear</li><li>kiwi</li></ul></div>', dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate("<div><ul>{% for item in items %}<li><span>{{ item.name }}</span><br/><p>{{ item.color }}</p></li>{% endfor %}</ul></div>");
+ t.is('<div><ul><li><span>apple</span><br/><p>red</p></li><li><span>banana</span><br/><p>yellow</p></li><li><span>pear</span><br/><p>green</p></li><li><span>kiwi</span><br/><p>brown</p></li></ul></div>', dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate("<div><ul>{% for item in items %}<li>{% ifequal item.name edit_item %}<label>Name: <input type='text' name='name' value=\"{{ item.name }}\"/></label><br/><label>Color: <textarea name='color'>{{ item.color }}</textarea></label>{% else %}<span>{{ item.name }}</span><br/><p>{{ item.color }}</p>{% endifequal %}</li>{% endfor %}</ul></div>");
+ t.is('<div><ul><li><span>apple</span><br/><p>red</p></li><li><label>Name: <input type="text" name="name" value="banana"/></label><br/><label>Color: <textarea name="color">yellow</textarea></label></li><li><span>pear</span><br/><p>green</p></li><li><span>kiwi</span><br/><p>brown</p></li></ul></div>', dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate("<div><ul>{% for item in items %}<li>{% ifequal item.name edit_item %}<div><label>Name: <input type='text' name='name' value=\"{{ item.name }}\"/></label><br/><label>Color: <textarea name='color'>{{ item.color }}</textarea></label></div>{% else %}<div><span>{{ item.name }}</span><br/><p>{{ item.color }}</p></div>{% endifequal %}</li>{% endfor %}</ul></div>");
+ t.is('<div><ul><li><div><span>apple</span><br/><p>red</p></div></li><li><div><label>Name: <input type="text" name="name" value="banana"/></label><br/><label>Color: <textarea name="color">yellow</textarea></label></div></li><li><div><span>pear</span><br/><p>green</p></div></li><li><div><span>kiwi</span><br/><p>brown</p></div></li></ul></div>', dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate("<div><ul>{% for item in items %}{% ifequal item.name edit_item %}<li><label>Name: <input type='text' name='name' value=\"{{ item.name }}\"/></label><br/><label>Color: <textarea name='color'>{{ item.color }}</textarea></label></li>{% else %}<li><span>{{ item.name }}</span><br/><p>{{ item.color }}</p></li>{% endifequal %}{% endfor %}</ul></div>");
+ t.is('<div><ul><li><span>apple</span><br/><p>red</p></li><li><label>Name: <input type="text" name="name" value="banana"/></label><br/><label>Color: <textarea name="color">yellow</textarea></label></li><li><span>pear</span><br/><p>green</p></li><li><span>kiwi</span><br/><p>brown</p></li></ul></div>', dd.tests.html.util.render(template, context));
+ },
+ function test_tag_include(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ hello: dojo.moduleUrl("dojox.dtl.tests.templates", "hello.html"),
+ person: "Bob",
+ people: ["Charles", "Ralph", "Julia"]
+ });
+
+ var template = new dd.HtmlTemplate("<div>{% include hello %}</div>");
+ t.is("<div>Hello, <span>Bob</span></div>", dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate('<div>{% include "../../dojox/dtl/tests/templates/hello.html" %}</div>');
+ t.is("<div>Hello, <span>Bob</span></div>", dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate('<div>{% for person in people %}<div class="include">{% include hello %} </div>{% endfor %}</div>');
+ t.is('<div><div class="include">Hello, <span>Charles</span> </div><div class="include">Hello, <span>Ralph</span> </div><div class="include">Hello, <span>Julia</span> </div></div>', dd.tests.html.util.render(template, context));
+ },
+ function test_tag_spaceless(t){
+ var dd = dojox.dtl;
+
+ var template = new dd.HtmlTemplate("{% spaceless %}<ul> \n <li>Hot</li> \n\n<li>Pocket </li>\n </ul>{% endspaceless %}");
+ t.is("<ul><li>Hot</li><li>Pocket </li></ul>", dd.tests.html.util.render(template));
+ },
+ function test_tag_ssi(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ hello: dojo.moduleUrl("dojox.dtl.tests.templates", "hello.html"),
+ person: "Bob",
+ people: ["Charles", "Ralph", "Julia"]
+ });
+
+ var template = new dd.HtmlTemplate("<div>{% ssi hello parsed %}</div>");
+ t.is("<div>Hello, <span>Bob</span></div>", dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate("<div>{% ssi hello %}</div>");
+ t.is("<div>Hello, <span>{{ person }}</span></div>", dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate('<div>{% ssi "../../dojox/dtl/tests/templates/hello.html" parsed %}</div>');
+ t.is("<div>Hello, <span>Bob</span></div>", dd.tests.html.util.render(template, context));
+
+ template = new dd.HtmlTemplate('<div>{% for person in people %}{% ssi hello parsed %} {% endfor %}</div>');
+ t.is("<div>Hello, <span>Charles</span> Hello, <span>Ralph</span> Hello, <span>Julia</span> </div>", dd.tests.html.util.render(template, context));
+ }
+ ]
+);
+
+}
diff --git a/includes/js/dojox/dtl/tests/html/util.js b/includes/js/dojox/dtl/tests/html/util.js
new file mode 100644
index 0000000..b4efe5a
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/html/util.js
@@ -0,0 +1,160 @@
+if(!dojo._hasResource["dojox.dtl.tests.html.util"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tests.html.util"] = true;
+dojo.provide("dojox.dtl.tests.html.util");
+
+dojo.require("dojox.dtl.html");
+dojo.require("dojox.dtl.render.html");
+dojo.require("dojox.string.Builder");
+
+dojox.dtl.HtmlBuffer.prototype.onClone = function(from, to){
+ var clones = this._clones = this._clones || [];
+
+ for(var i = 0, group; group = clones[i]; i++){
+ for(var j = 0, item; item = group[j]; j++){
+ if(item === from){
+ group.push(to);
+ return
+ }else if(item === to){
+ group.push(from);
+ return;
+ }
+ }
+ }
+
+ clones.push([from, to]);
+}
+dojox.dtl.HtmlBuffer.prototype.onAddEvent = function(node, type, description){
+ var events = this._events = this._events || [];
+
+ var found = false;
+ for(var i = 0, evt; evt = events[i]; i++){
+ if(evt[0] === node){
+ found = true;
+ evt[1] = type;
+ evt[2] = description;
+ }
+ }
+
+ if(!found){
+ events.push([node, type, description]);
+ }
+}
+
+dojox.dtl.tests.html.util.render = function(/*HtmlTemplate*/ template, /*Context*/ context) {
+ try {
+ var div = document.createElement("div");
+ dojo.style(div, "visibility", "hidden");
+ var attach = document.createElement("div");
+ div.appendChild(attach);
+ dojo.body().appendChild(div);
+
+ var buffer = template.getBuffer();
+ var canvas = new dojox.dtl.render.html.Render(attach, template);
+ canvas.render(context, template, buffer);
+ var clones = buffer._clones;
+ var events = buffer._events;
+
+ var first = dojox.dtl.tests.html.util.serialize(canvas.domNode, template.tokens, clones, events).toString();
+
+ buffer = template.getBuffer();
+ buffer._clones = clones;
+ buffer._events = events;
+ canvas.render(context, template, buffer);
+
+ var second = dojox.dtl.tests.html.util.serialize(canvas.domNode, template.tokens, clones, events).toString();
+
+ doh.is("Compare re-render: " + first, "Compare re-render: " + second);
+ return first;
+ }
+ catch(e){
+ throw e;
+ }finally{
+ div.parentNode.removeChild(div);
+ }
+}
+
+dojox.dtl.tests.html.util.serialize = function(node, tokens, clones, events, output) {
+ var types = dojox.dtl.html.types;
+ clones = clones || [];
+ events = events || [];
+
+ if (node.nodeType == 3) {
+ output.append(node.nodeValue);
+ }else{
+ var name = node.nodeName.toLowerCase();
+
+ if (!output) {
+ output = new dojox.string.Builder();
+ }
+ output.append("<").append(name);
+
+ var attributes = dojo.filter(tokens, function(token){
+ if(token[0] == types.attr){
+ for(var i = 0, group; group = clones[i]; i++){
+ // group is any set of nodes that were originally the sam
+ var count = 0;
+ for(var j = 0, item; item = group[j]; j++){
+ if(item === token[1] || item === node){
+ if(count++){
+ // This is entered when we have 2 hits within a clone group.
+ // The first would be the original node
+ // The second would be if our current node is a clone
+ // of the original
+ return true;
+ }
+ }
+ }
+ }
+ }
+ });
+
+ for(var i = 0, attribute; attribute = attributes[i]; i++){
+ var value = "";
+ if(attribute[2] == "class"){
+ value = node.className || value;
+ }else if(attribute[2] == "for"){
+ value = node.htmlFor || value;
+ }else if(node.getAttribute){
+ value = node.getAttribute(attribute[2], 2) || value;
+ if(dojo.isIE && (attribute[2] == "href" || attribute[2] == "src")){
+ if(dojo.isIE){
+ var hash = location.href.lastIndexOf(location.hash);
+ var href = location.href.substring(0, hash).split("/");
+ href.pop();
+ href = href.join("/") + "/";
+ if(value.indexOf(href) == 0){
+ value = value.replace(href, "");
+ }
+ value = decodeURIComponent(value);
+ }
+ }
+ }
+ if(value){
+ output.append(" ").append(attribute[2]).append('="').append(value.replace(/"/g, '\\"')).append('"');
+ }
+ }
+
+ // Deal with events
+ if(events){
+ for(var i = 0, evt; evt = events[i]; i++){
+ if(evt[0] === node){
+ output.append(" ").append(evt[1]).append('="').append(evt[2]).append('"');
+ }
+ }
+ }
+
+ if(!node.childNodes.length){
+ output.append("/>");
+ }else{
+ output.append(">");
+ dojo.forEach(node.childNodes, function(node){
+ dojox.dtl.tests.html.util.serialize(node, tokens, clones, events, output);
+ });
+ output.append("</").append(name).append(">");
+ }
+
+ return output;
+ }
+}
+
+}
diff --git a/includes/js/dojox/dtl/tests/module.js b/includes/js/dojox/dtl/tests/module.js
new file mode 100644
index 0000000..57dcafb
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/module.js
@@ -0,0 +1,15 @@
+if(!dojo._hasResource["dojox.dtl.tests.module"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tests.module"] = true;
+dojo.provide("dojox.dtl.tests.module");
+
+try{
+ dojo.require("dojox.dtl.tests.text.filter");
+ dojo.require("dojox.dtl.tests.text.tag");
+ dojo.require("dojox.dtl.tests.html.tag");
+ dojo.require("dojox.dtl.tests.html.buffer");
+ dojo.require("dojox.dtl.tests.context");
+}catch(e){
+ doh.debug(e);
+}
+
+}
diff --git a/includes/js/dojox/dtl/tests/runTests.html b/includes/js/dojox/dtl/tests/runTests.html
new file mode 100644
index 0000000..32338f6
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>Dojox Djanto Template Language D.O.H. Unit Test Runner</title>
+ <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojox.dtl.tests.module"></HEAD>
+ <BODY>
+ Redirecting to D.O.H runner.
+ </BODY>
+</HTML> \ No newline at end of file
diff --git a/includes/js/dojox/dtl/tests/templates/hello.html b/includes/js/dojox/dtl/tests/templates/hello.html
new file mode 100644
index 0000000..18e4c1a
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/templates/hello.html
@@ -0,0 +1 @@
+Hello, <span>{{ person }}</span> \ No newline at end of file
diff --git a/includes/js/dojox/dtl/tests/templates/pocket.html b/includes/js/dojox/dtl/tests/templates/pocket.html
new file mode 100644
index 0000000..f78c520
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/templates/pocket.html
@@ -0,0 +1 @@
+{% block pocket %}Hot{% endblock %} Pocket \ No newline at end of file
diff --git a/includes/js/dojox/dtl/tests/templates/pocket2.html b/includes/js/dojox/dtl/tests/templates/pocket2.html
new file mode 100644
index 0000000..547f9a2
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/templates/pocket2.html
@@ -0,0 +1 @@
+{% for item in items %}({% block pocket %}Hot{% endblock %}) {% endfor %}Pocket \ No newline at end of file
diff --git a/includes/js/dojox/dtl/tests/text/filter.js b/includes/js/dojox/dtl/tests/text/filter.js
new file mode 100644
index 0000000..d96f931
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/text/filter.js
@@ -0,0 +1,740 @@
+if(!dojo._hasResource["dojox.dtl.tests.text.filter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tests.text.filter"] = true;
+dojo.provide("dojox.dtl.tests.text.filter");
+
+dojo.require("dojox.dtl");
+dojo.require("dojox.dtl.Context");
+dojo.require("dojox.dtl.utils.date");
+dojo.require("dojox.date.php");
+dojo.require("dojox.string.sprintf");
+
+// If you update something here, update it in the HTML tests
+doh.register("dojox.dtl.text.filter",
+ [
+ function test_filter_add(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ four: 4 });
+ tpl = new dd.Template('{{ four|add:"6" }}');
+ t.is("10", tpl.render(context));
+ context.four = "4";
+ t.is("10", tpl.render(context));
+ tpl = new dd.Template('{{ four|add:"six" }}');
+ t.is("4", tpl.render(context));
+ tpl = new dd.Template('{{ four|add:"6.6" }}');
+ t.is("10", tpl.render(context));
+ },
+ function test_filter_addslashes(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ unslashed: "Test back slashes \\, double quotes \" and single quotes '" })
+ var tpl = new dd.Template('{{ unslashed|addslashes }}');
+ t.is("Test back slashes \\\\, double quotes \\\" and single quotes \\'", tpl.render(context));
+ },
+ function test_filter_capfirst(t){
+ var dd = dojox.dtl;
+
+ var tpl = new dd.Template('{{ uncapped|capfirst }}');
+ t.is("Cap", tpl.render(new dd.Context({ uncapped: "cap" })));
+ },
+ function test_filter_center(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context();
+ var tpl = new dd.Template('{{ narrow|center }}');
+ context.narrow = "even";
+ t.is("even", tpl.render(context));
+ context.narrow = "odd";
+ t.is("odd", tpl.render(context));
+ tpl = new dd.Template('{{ narrow|center:"5" }}');
+ context.narrow = "even";
+ t.is("even ", tpl.render(context));
+ context.narrow = "odd";
+ t.is(" odd ", tpl.render(context));
+ tpl = new dd.Template('{{ narrow|center:"6" }}');
+ context.narrow = "even";
+ t.is(" even ", tpl.render(context));
+ context.narrow = "odd";
+ t.is(" odd ", tpl.render(context));
+ tpl = new dd.Template('{{ narrow|center:"12" }}');
+ context.narrow = "even";
+ t.is(" even ", tpl.render(context));
+ context.narrow = "odd";
+ t.is(" odd ", tpl.render(context));
+ },
+ function test_filter_cut(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ uncut: "Apples and oranges" });
+ var tpl = new dd.Template('{{ uncut|cut }}');
+ t.is("Apples and oranges", tpl.render(context));
+ tpl = new dd.Template('{{ uncut|cut:"A" }}');
+ t.is("pples and oranges", tpl.render(context));
+ tpl = new dd.Template('{{ uncut|cut:" " }}');
+ t.is("Applesandoranges", tpl.render(context));
+ tpl = new dd.Template('{{ uncut|cut:"e" }}');
+ t.is("Appls and orangs", tpl.render(context));
+ },
+ function test_filter_date(t){
+ var dd = dojox.dtl;
+ var context = new dd.Context({ now: new Date(2007, 0, 1), then: new Date(2007, 1, 1) });
+
+ var tpl = new dd.Template('{{ now|date }}');
+ t.is(dojox.dtl.utils.date.format(context.now, "N j, Y"), tpl.render(context));
+
+ context.then = new Date(2007, 0, 1);
+ tpl = new dd.Template('{{ now|date:"d" }}');
+ t.is("01", tpl.render(context));
+
+ tpl = new dd.Template('{{ now|date:"D" }}');
+ t.is("Mon", tpl.render(context));
+
+ tpl = new dd.Template('{{ now|date:"j" }}');
+ t.is("1", tpl.render(context));
+
+ tpl = new dd.Template('{{ now|date:"l" }}');
+ t.is("Monday", tpl.render(context));
+
+ tpl = new dd.Template('{{ now|date:"N" }}');
+ t.is("Jan.", tpl.render(context));
+
+ tpl = new dd.Template('{{ now|date:"S" }}');
+ t.is("st", tpl.render(context));
+ context.now.setDate(2);
+ t.is("nd", tpl.render(context));
+ context.now.setDate(3);
+ t.is("rd", tpl.render(context));
+ context.now.setDate(4);
+ t.is("th", tpl.render(context));
+ context.now.setDate(5);
+ t.is("th", tpl.render(context));
+ context.now.setDate(6);
+ t.is("th", tpl.render(context));
+ context.now.setDate(7);
+ t.is("th", tpl.render(context));
+ context.now.setDate(8);
+ t.is("th", tpl.render(context));
+ context.now.setDate(9);
+ t.is("th", tpl.render(context));
+ context.now.setDate(10);
+ t.is("th", tpl.render(context));
+ context.now.setDate(11);
+ t.is("th", tpl.render(context));
+ context.now.setDate(12);
+ t.is("th", tpl.render(context));
+ context.now.setDate(13);
+ t.is("th", tpl.render(context));
+ context.now.setDate(14);
+ t.is("th", tpl.render(context));
+ context.now.setDate(15);
+ t.is("th", tpl.render(context));
+ context.now.setDate(16);
+ t.is("th", tpl.render(context));
+ context.now.setDate(17);
+ t.is("th", tpl.render(context));
+ context.now.setDate(18);
+ t.is("th", tpl.render(context));
+ context.now.setDate(19);
+ t.is("th", tpl.render(context));
+ context.now.setDate(20);
+ t.is("th", tpl.render(context));
+ context.now.setDate(21);
+ t.is("st", tpl.render(context));
+ context.now.setDate(22);
+ t.is("nd", tpl.render(context));
+ context.now.setDate(23);
+ t.is("rd", tpl.render(context));
+ context.now.setDate(24);
+ t.is("th", tpl.render(context));
+ context.now.setDate(25);
+ t.is("th", tpl.render(context));
+ context.now.setDate(26);
+ t.is("th", tpl.render(context));
+ context.now.setDate(27);
+ t.is("th", tpl.render(context));
+ context.now.setDate(28);
+ t.is("th", tpl.render(context));
+ context.now.setDate(29);
+ t.is("th", tpl.render(context));
+ context.now.setDate(30);
+ t.is("th", tpl.render(context));
+ context.now.setDate(31);
+ t.is("st", tpl.render(context));
+ context.now.setDate(1);
+
+ tpl = new dd.Template('{{ now|date:"w" }}');
+ t.is("1", tpl.render(context));
+
+ tpl = new dd.Template('{{ now|date:"z" }}');
+ t.is("0", tpl.render(context));
+
+ tpl = new dd.Template('{{ now|date:"W" }}');
+ t.is("1", tpl.render(context));
+ },
+ function test_filter_default(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context();
+ tpl = new dd.Template('{{ empty|default }}');
+ t.is("", tpl.render(context));
+ tpl = new dd.Template('{{ empty|default:"full" }}');
+ t.is("full", tpl.render(context));
+ context.empty = "not empty";
+ t.is("not empty", tpl.render(context));
+ },
+ function test_filter_default_if_none(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context();
+ tpl = new dd.Template('{{ empty|default_if_none }}');
+ t.is("", tpl.render(context));
+ tpl = new dd.Template('{{ empty|default_if_none:"full" }}');
+ t.is("", tpl.render(context));
+ context.empty = null;
+ t.is("full", tpl.render(context));
+ context.empty = "not empty";
+ t.is("not empty", tpl.render(context));
+ },
+ function test_filter_dictsort(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ fruit: [
+ { name: "lemons", toString: function(){ return this.name; } },
+ { name: "apples", toString: function(){ return this.name; } },
+ { name: "grapes", toString: function(){ return this.name; } }
+ ]
+ });
+ tpl = new dd.Template('{{ fruit|dictsort|join:"|" }}');
+ t.is("lemons|apples|grapes", tpl.render(context));
+ tpl = new dd.Template('{{ fruit|dictsort:"name"|join:"|" }}');
+ t.is("apples|grapes|lemons", tpl.render(context));
+ },
+ function test_filter_dictsort_reversed(t){
+ var dd = dojox.dtl;
+
+ context = new dd.Context({
+ fruit: [
+ { name: "lemons", toString: function(){ return this.name; } },
+ { name: "apples", toString: function(){ return this.name; } },
+ { name: "grapes", toString: function(){ return this.name; } }
+ ]
+ });
+ tpl = new dd.Template('{{ fruit|dictsortreversed:"name"|join:"|" }}');
+ t.is("lemons|grapes|apples", tpl.render(context));
+ },
+ function test_filter_divisibleby(t){
+ var dd = dojox.dtl;
+
+ context = new dd.Context();
+ tpl = new dd.Template('{{ 4|divisibleby:"2" }}');
+ t.is("true", tpl.render(context));
+ context = new dd.Context({ number: 4 });
+ tpl = new dd.Template('{{ number|divisibleby:3 }}');
+ t.is("false", tpl.render(context));
+ },
+ function test_filter_escape(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ unescaped: "Try & cover <all> the \"major\" 'situations' at once" });
+ tpl = new dd.Template('{{ unescaped|escape }}');
+ t.is("Try &amp; cover &lt;all&gt; the &quot;major&quot; &#39;situations&#39; at once", tpl.render(context));
+ },
+ function test_filter_filesizeformat(t){
+ var dd = dojox.dtl;
+
+ var tpl = new dd.Template('{{ 1|filesizeformat }}');
+ t.is("1 byte", tpl.render());
+ tpl = new dd.Template('{{ 512|filesizeformat }}');
+ t.is("512 bytes", tpl.render());
+ tpl = new dd.Template('{{ 1024|filesizeformat }}');
+ t.is("1.0 KB", tpl.render());
+ tpl = new dd.Template('{{ 2048|filesizeformat }}');
+ t.is("2.0 KB", tpl.render());
+ tpl = new dd.Template('{{ 1048576|filesizeformat }}');
+ t.is("1.0 MB", tpl.render());
+ tpl = new dd.Template('{{ 1073741824|filesizeformat }}');
+ t.is("1.0 GB", tpl.render());
+ },
+ function test_filter_first(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ fruit: [
+ { name: "lemons", toString: function(){ return this.name; } },
+ { name: "apples", toString: function(){ return this.name; } },
+ { name: "grapes", toString: function(){ return this.name; } }
+ ]
+ });
+ tpl = new dd.Template('{{ fruit|first }}');
+ t.is("lemons", tpl.render(context));
+ },
+ function test_filter_fix_ampersands(t){
+ var dd = dojox.dtl;
+
+ var tpl = new dd.Template('{{ "One & Two"|fix_ampersands }}');
+ t.is("One &amp; Two", tpl.render());
+ },
+ function test_filter_floatformat(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ num1: 34.23234, num2: 34.00000 });
+ var tpl = new dd.Template('{{ num1|floatformat }}');
+ t.is("34.2", tpl.render(context));
+ tpl = new dd.Template('{{ num2|floatformat }}');
+ t.is("34", tpl.render(context));
+ tpl = new dd.Template('{{ num1|floatformat:3 }}');
+ t.is("34.232", tpl.render(context));
+ tpl = new dd.Template('{{ num2|floatformat:3 }}');
+ t.is("34.000", tpl.render(context));
+ tpl = new dd.Template('{{ num1|floatformat:-3 }}');
+ t.is("34.2", tpl.render(context));
+ tpl = new dd.Template('{{ num2|floatformat:-3 }}');
+ t.is("34", tpl.render(context));
+ },
+ function test_filter_get_digit(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ pi: 314159265 });
+ var tpl = new dd.Template('{{ pi|get_digit:1 }}');
+ t.is("3", tpl.render(context));
+ tpl = new dd.Template('{{ pi|get_digit:"2" }}');
+ t.is("1", tpl.render(context));
+ tpl = new dd.Template('{{ pi|get_digit:0 }}');
+ t.is("314159265", tpl.render(context));
+ tpl = new dd.Template('{{ "nada"|get_digit:1 }}');
+ t.is("0", tpl.render(context));
+ },
+ function test_filter_iriencode(t){
+ var dd = dojox.dtl;
+
+ var tpl = new dd.Template('{{ "http://homepage.com/~user"|urlencode|iriencode }}');
+ t.is("http%3A//homepage.com/%7Euser", tpl.render());
+ tpl = new dd.Template('{{ "pottedmeat@dojotoolkit.org"|iriencode }}');
+ t.is("pottedmeat%40dojotoolkit.org", tpl.render());
+ },
+ function test_filter_join(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ items: ["foo", "bar", "baz" ]});
+ var tpl = new dd.Template("{{ items|join }}");
+ t.is("foo,bar,baz", tpl.render(context));
+
+ tpl = new dd.Template('{{ items|join:"mustard" }}');
+ t.is("foomustardbarmustardbaz", tpl.render(context));
+ },
+ function test_filter_length(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ fruit: [
+ { name: "lemons", toString: function(){ return this.name; } },
+ { name: "apples", toString: function(){ return this.name; } },
+ { name: "grapes", toString: function(){ return this.name; } }
+ ]
+ });
+ tpl = new dd.Template('{{ fruit|length }}');
+ t.is("3", tpl.render(context));
+ tpl = new dd.Template('{{ fruit|first|length }}');
+ t.is("6", tpl.render(context));
+ },
+ function test_filter_length_is(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ fruit: [
+ { name: "lemons", toString: function(){ return this.name; } },
+ { name: "apples", toString: function(){ return this.name; } },
+ { name: "grapes", toString: function(){ return this.name; } }
+ ]
+ });
+ tpl = new dd.Template('{{ fruit|length_is:"3" }}');
+ t.is("true", tpl.render(context));
+ tpl = new dd.Template('{{ fruit|length_is:"4" }}');
+ t.is("false", tpl.render(context));
+ },
+ function test_filter_linebreaks(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ unbroken: "This is just\r\n\n\ra bunch\nof text\n\n\nand such" });
+ tpl = new dd.Template('{{ unbroken|linebreaks }}');
+ t.is("<p>This is just</p>\n\n<p>a bunch<br />of text</p>\n\n<p>and such</p>", tpl.render(context));
+ },
+ function test_filter_linebreaksbr(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ unbroken: "This is just\r\n\n\ra bunch\nof text\n\n\nand such" });
+ tpl = new dd.Template('{{ unbroken|linebreaksbr }}');
+ t.is("This is just<br /><br />a bunch<br />of text<br /><br /><br />and such", tpl.render(context));
+ },
+ function test_filter_linenumbers(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ lines: "One\nTwo\nThree\nFour\n" });
+ var tpl = new dd.Template('{{ lines|linenumbers }}');
+ t.is("1. One\n2. Two\n3. Three\n4. Four\n5. ", tpl.render(context));
+ },
+ function test_filter_ljust(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context();
+ var tpl = new dd.Template('{{ narrow|ljust }}');
+ context.narrow = "even";
+ t.is("even", tpl.render(context));
+ context.narrow = "odd";
+ t.is("odd", tpl.render(context));
+ tpl = new dd.Template('{{ narrow|ljust:"5" }}');
+ context.narrow = "even";
+ t.is("even ", tpl.render(context));
+ context.narrow = "odd";
+ t.is("odd ", tpl.render(context));
+ tpl = new dd.Template('{{ narrow|ljust:"6" }}');
+ context.narrow = "even";
+ t.is("even ", tpl.render(context));
+ context.narrow = "odd";
+ t.is("odd ", tpl.render(context));
+ tpl = new dd.Template('{{ narrow|ljust:"12" }}');
+ context.narrow = "even";
+ t.is("even ", tpl.render(context));
+ context.narrow = "odd";
+ t.is("odd ", tpl.render(context));
+ },
+ function test_filter_lower(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ mixed: "MiXeD" });
+ var tpl = new dd.Template('{{ mixed|lower }}');
+ t.is("mixed", tpl.render(context));
+ },
+ function test_filter_make_list(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ word: "foo", number: 314159265, arr: ["first", "second"], obj: {first: "first", second: "second"} });
+ var tpl = new dd.Template('{{ word|make_list|join:"|" }} {{ number|make_list|join:"|" }} {{ arr|make_list|join:"|" }} {{ obj|make_list|join:"|" }}');
+ t.is("f|o|o 3|1|4|1|5|9|2|6|5 first|second first|second", tpl.render(context));
+ },
+ function test_filter_phone2numeric(t){
+ var dd = dojox.dtl;
+
+ tpl = new dd.Template('{{ "1-800-pottedmeat"|phone2numeric }}');
+ t.is("1-800-7688336328", tpl.render());
+ },
+ function test_filter_pluralize(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ animals: ["bear", "cougar", "aardvark"] });
+ var tpl = new dd.Template('{{ animals|length }} animal{{ animals|length|pluralize }}');
+ t.is("3 animals", tpl.render(context));
+ context.animals = ["bear"];
+ t.is("1 animal", tpl.render(context));
+ context = new dd.Context({ fairies: ["tinkerbell", "Andy Dick" ]});
+ tpl = new dd.Template('{{ fairies|length }} fair{{ fairies|length|pluralize:"y,ies" }}');
+ t.is("2 fairies", tpl.render(context));
+ context.fairies.pop();
+ t.is("1 fairy", tpl.render(context));
+ },
+ function test_filter_pprint(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ animals: ["bear", "cougar", "aardvark"] });
+ tpl = new dd.Template("{{ animals|pprint }}");
+ t.is('["bear","cougar","aardvark"]', tpl.render(context));
+ },
+ function test_filter_random(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ fruit: [
+ { name: "lemons", toString: function(){ return this.name; } },
+ { name: "apples", toString: function(){ return this.name; } },
+ { name: "grapes", toString: function(){ return this.name; } }
+ ]
+ });
+ tpl = new dd.Template('{{ fruit|random }}');
+ result = tpl.render(context);
+ t.t(result == "lemons" || result == "apples" || result == "grapes");
+ var different = false;
+ for(var i = 0; i < 10; i++){
+ // Check to see if it changes
+ if(result != tpl.render(context) && result == "lemons" || result == "apples" || result == "grapes"){
+ different = true;
+ break;
+ }
+ }
+ t.t(different);
+ },
+ function test_filter_removetags(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ tagged: "I'm gonna do something <script>evil</script> with the <html>filter" });
+ tpl = new dd.Template('{{ tagged|removetags:"script <html>" }}');
+ t.is("I'm gonna do something evil with the filter", tpl.render(context));
+ },
+ function test_filter_rjust(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context();
+ var tpl = new dd.Template('{{ narrow|rjust }}');
+ context.narrow = "even";
+ t.is("even", tpl.render(context));
+ context.narrow = "odd";
+ t.is("odd", tpl.render(context));
+ tpl = new dd.Template('{{ narrow|rjust:"5" }}');
+ context.narrow = "even";
+ t.is(" even", tpl.render(context));
+ context.narrow = "odd";
+ t.is(" odd", tpl.render(context));
+ tpl = new dd.Template('{{ narrow|rjust:"6" }}');
+ context.narrow = "even";
+ t.is(" even", tpl.render(context));
+ context.narrow = "odd";
+ t.is(" odd", tpl.render(context));
+ tpl = new dd.Template('{{ narrow|rjust:"12" }}');
+ context.narrow = "even";
+ t.is(" even", tpl.render(context));
+ context.narrow = "odd";
+ t.is(" odd", tpl.render(context));
+ },
+ function test_filter_slice(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ fruit: [
+ { name: "lemons", toString: function(){ return this.name; } },
+ { name: "apples", toString: function(){ return this.name; } },
+ { name: "grapes", toString: function(){ return this.name; } }
+ ]
+ });
+ tpl = new dd.Template('{{ fruit|slice:":1"|join:"|" }}');
+ t.is("lemons", tpl.render(context));
+ tpl = new dd.Template('{{ fruit|slice:"1"|join:"|" }}');
+ t.is("apples|grapes", tpl.render(context));
+ tpl = new dd.Template('{{ fruit|slice:"1:3"|join:"|" }}');
+ t.is("apples|grapes", tpl.render(context));
+ tpl = new dd.Template('{{ fruit|slice:""|join:"|" }}');
+ t.is("lemons|apples|grapes", tpl.render(context));
+ tpl = new dd.Template('{{ fruit|slice:"-1"|join:"|" }}');
+ t.is("grapes", tpl.render(context));
+ tpl = new dd.Template('{{ fruit|slice:":-1"|join:"|" }}');
+ t.is("lemons|apples", tpl.render(context));
+ tpl = new dd.Template('{{ fruit|slice:"-2:-1"|join:"|" }}');
+ t.is("apples", tpl.render(context));
+ },
+ function test_filter_slugify(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ unslugged: "Apples and oranges()"});
+ tpl = new dd.Template('{{ unslugged|slugify }}');
+ t.is("apples-and-oranges", tpl.render(context));
+ },
+ function test_filter_stringformat(t){
+ var dd = dojox.dtl;
+
+ var tpl = new dd.Template('{{ 42|stringformat:"7.3f" }}');
+ t.is(" 42.000", tpl.render());
+ },
+ function test_filter_striptags(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ tagged: "I'm gonna do something <script>evil</script> with the <html>filter" });
+ tpl = new dd.Template('{{ tagged|striptags }}');
+ t.is("I'm gonna do something evil with the filter", tpl.render(context));
+ },
+ function test_filter_time(t){
+ var dd = dojox.dtl;
+ var context = new dd.Context({ now: new Date(2007, 0, 1) });
+
+ tpl = new dd.Template('{{ now|time }}');
+ t.is(dojox.dtl.utils.date.format(context.now, "P"), tpl.render(context));
+ },
+ function test_filter_timesince(t){
+ var dd = dojox.dtl;
+ var context = new dd.Context({ now: new Date(2007, 0, 1), then: new Date(2007, 1, 1) });
+
+ tpl = new dd.Template('{{ now|timesince:then }}');
+ t.is("1 month", tpl.render(context));
+ context.then = new Date(2007, 0, 5);
+ t.is("4 days", tpl.render(context));
+ context.then = new Date(2007, 0, 17);
+ t.is("2 weeks", tpl.render(context));
+ context.then = new Date(2008, 1, 1);
+ t.is("1 year", tpl.render(context));
+ },
+ function test_filter_timeuntil(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ now: new Date(2007, 0, 1), then: new Date(2007, 1, 1) });
+ var tpl = new dd.Template('{{ now|timeuntil:then }}');
+ t.is("1 month", tpl.render(context));
+ context.then = new Date(2007, 0, 5);
+ t.is("4 days", tpl.render(context));
+ context.then = new Date(2007, 0, 17);
+ t.is("2 weeks", tpl.render(context));
+ context.then = new Date(2008, 1, 1);
+ t.is("1 year", tpl.render(context));
+ },
+ function test_filter_title(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ name: "potted meat" });
+ var tpl = new dd.Template("{{ name|title }}");
+ t.is("Potted Meat", tpl.render(context));
+
+ context.name = "What's going on?";
+ t.is("What's Going On?", tpl.render(context));
+
+ context.name = "use\nline\nbREAKs\tand tabs";
+ t.is("Use\nLine\nBreaks\tAnd Tabs", tpl.render(context));
+ },
+ function test_filter_truncatewords(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ word: "potted meat writes a lot of tests" });
+ var tpl = new dd.Template("{{ word|truncatewords }}");
+ t.is(context.word, tpl.render(context));
+
+ tpl = new dd.Template('{{ word|truncatewords:"1" }}');
+ t.is("potted", tpl.render(context));
+
+ tpl = new dd.Template('{{ word|truncatewords:"2" }}');
+ t.is("potted meat", tpl.render(context));
+
+ tpl = new dd.Template('{{ word|truncatewords:20" }}');
+ t.is(context.word, tpl.render(context));
+
+ context.word = "potted \nmeat \nwrites a lot of tests";
+ tpl = new dd.Template('{{ word|truncatewords:"3" }}');
+ t.is("potted \nmeat \nwrites", tpl.render(context));
+ },
+ function test_filter_truncatewords_html(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ body: "Test a string <em>that ends <i>inside a</i> tag</em> with different args",
+ size: 2
+ })
+ var tpl = new dd.Template('{{ body|truncatewords_html:size }}');
+ t.is("Test a ...", tpl.render(context));
+ context.size = 4;
+ t.is("Test a string <em>that ...</em>", tpl.render(context));
+ context.size = 6;
+ t.is("Test a string <em>that ends <i>inside ...</i></em>", tpl.render(context));
+ },
+ function test_filter_unordered_list(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ states: ["States", [["Kansas", [["Lawrence", []], ["Topeka", []]]], ["Illinois", []]]] });
+ tpl = new dd.Template('{{ states|unordered_list }}');
+ t.is("\t<li>States\n\t<ul>\n\t\t<li>Kansas\n\t\t<ul>\n\t\t\t<li>Lawrence</li>\n\t\t\t<li>Topeka</li>\n\t\t</ul>\n\t\t</li>\n\t\t<li>Illinois</li>\n\t</ul>\n\t</li>", tpl.render(context));
+ },
+ function test_filter_upper(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({ mixed: "MiXeD" });
+ var tpl = new dd.Template('{{ mixed|upper }}');
+ t.is("MIXED", tpl.render(context));
+ },
+ function test_filter_urlencode(t){
+ var dd = dojox.dtl;
+
+ var tpl = new dd.Template('{{ "http://homepage.com/~user"|urlencode }}');
+ t.is("http%3A//homepage.com/%7Euser", tpl.render());
+ },
+ function test_filter_urlize(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ body: "My favorite websites are www.televisionwithoutpity.com, http://daringfireball.net and you can email me at pottedmeat@sitepen.com"
+ });
+ var tpl = new dd.Template("{{ body|urlize }}");
+ t.is('My favorite websites are <a href="http://www.televisionwithoutpity.com" rel="nofollow">www.televisionwithoutpity.com</a> <a href="http://daringfireball.net" rel="nofollow">http://daringfireball.net</a> and you can email me at <a href="mailto:pottedmeat@sitepen.com">pottedmeat@sitepen.com</a>', tpl.render(context));
+ },
+ function test_filter_urlizetrunc(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ body: "My favorite websites are www.televisionwithoutpity.com, http://daringfireball.net and you can email me at pottedmeat@sitepen.com"
+ });
+ var tpl = new dd.Template("{{ body|urlizetrunc }}");
+ t.is('My favorite websites are <a href="http://www.televisionwithoutpity.com" rel="nofollow">www.televisionwithoutpity.com</a> <a href="http://daringfireball.net" rel="nofollow">http://daringfireball.net</a> and you can email me at <a href="mailto:pottedmeat@sitepen.com">pottedmeat@sitepen.com</a>', tpl.render(context));
+ tpl = new dd.Template('{{ body|urlizetrunc:"2" }}');
+ t.is('My favorite websites are <a href="http://www.televisionwithoutpity.com" rel="nofollow">www.televisionwithoutpity.com</a> <a href="http://daringfireball.net" rel="nofollow">http://daringfireball.net</a> and you can email me at <a href="mailto:pottedmeat@sitepen.com">pottedmeat@sitepen.com</a>', tpl.render(context));
+ tpl = new dd.Template('{{ body|urlizetrunc:"10" }}');
+ t.is('My favorite websites are <a href="http://www.televisionwithoutpity.com" rel="nofollow">www.tel...</a> <a href="http://daringfireball.net" rel="nofollow">http://...</a> and you can email me at <a href="mailto:pottedmeat@sitepen.com">pottedmeat@sitepen.com</a>', tpl.render(context));
+ },
+ function test_filter_wordcount(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ food: "Hot Pocket"
+ });
+ var tpl = new dd.Template("{{ food|wordcount }}");
+ t.is("2", tpl.render(context));
+ context.food = "";
+ t.is("0", tpl.render(context));
+ context.food = "A nice barbecue, maybe a little grilled veggies, some cole slaw.";
+ t.is("11", tpl.render(context));
+ },
+ function test_filter_wordwrap(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ body: "shrimp gumbo, shrimp pie, shrimp scampi, shrimp stew, fried shrimp, baked shrimp, shrimp o grotten, grilled shrimp, shrimp on a stick, shrimp salad, shrimp pop overs, shrimp cake, shrimp legs, shrimp stuffed eggs, shrimp cre oll, shrimp soup, creamed shrimp on toast, shrimp crapes, shrimply good crescent rolls, shrimp pizza, scalloped shrimp, boiled shrimp, shrimp cocktail"
+ });
+ var tpl = new dd.Template("{{ body|wordwrap }}");
+ t.is(context.body, tpl.render(context));
+ tpl = new dd.Template("{{ body|wordwrap:width }}");
+ context.width = 10;
+ t.is("shrimp\ngumbo,\nshrimp\npie,\nshrimp\nscampi,\nshrimp\nstew,\nfried\nshrimp,\nbaked\nshrimp,\nshrimp o\ngrotten,\ngrilled\nshrimp,\nshrimp on\na stick,\nshrimp\nsalad,\nshrimp pop\novers,\nshrimp\ncake,\nshrimp\nlegs,\nshrimp\nstuffed\neggs,\nshrimp cre\noll,\nshrimp\nsoup,\ncreamed\nshrimp on\ntoast,\nshrimp\ncrapes,\nshrimply\ngood\ncrescent\nrolls,\nshrimp\npizza,\nscalloped\nshrimp,\nboiled\nshrimp,\nshrimp\ncocktail", tpl.render(context));
+ tpl = new dd.Template('{{ body|wordwrap:"80" }}');
+ t.is("shrimp gumbo, shrimp pie, shrimp scampi, shrimp stew, fried shrimp, baked\nshrimp, shrimp o grotten, grilled shrimp, shrimp on a stick, shrimp salad,\nshrimp pop overs, shrimp cake, shrimp legs, shrimp stuffed eggs, shrimp cre oll,\nshrimp soup, creamed shrimp on toast, shrimp crapes, shrimply good crescent\nrolls, shrimp pizza, scalloped shrimp, boiled shrimp, shrimp cocktail", tpl.render(context));
+ },
+ function test_filter_yesno(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context();
+ tpl = new dd.Template('{{ true|yesno }}');
+ t.is("yes", tpl.render(context));
+ context = new dd.Context({ test: "value" });
+ tpl = new dd.Template('{{ test|yesno }}');
+ t.is("yes", tpl.render(context));
+ tpl = new dd.Template('{{ false|yesno }}');
+ t.is("no", tpl.render(context));
+ tpl = new dd.Template('{{ null|yesno }}');
+ t.is("maybe", tpl.render(context));
+ tpl = new dd.Template('{{ true|yesno:"bling,whack,soso" }}');
+ t.is("bling", tpl.render(context));
+ context = new dd.Context({ test: "value" });
+ tpl = new dd.Template('{{ test|yesno:"bling,whack,soso" }}');
+ t.is("bling", tpl.render(context));
+ tpl = new dd.Template('{{ false|yesno:"bling,whack,soso" }}');
+ t.is("whack", tpl.render(context));
+ tpl = new dd.Template('{{ null|yesno:"bling,whack,soso" }}');
+ t.is("soso", tpl.render(context));
+ tpl = new dd.Template('{{ null|yesno:"bling,whack" }}');
+ t.is("whack", tpl.render(context));
+ },
+ function test_filter_contrib_key(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ headers: ["action", "type"],
+ items: [
+ {
+ action: "eat",
+ type: "apple",
+ },
+ {
+ action: "mash",
+ type: "banana"
+ }
+ ]
+ });
+
+ var tpl = new dd.Template("{% load dojox.dtl.contrib.objects %}<ul>{% for item in items %}<li><ul>{% for header in headers %}<li>{{ header }}: {{ item|key:header }}</li>{% endfor %}</ul></li>{% endfor %}</ul>");
+ t.is('<ul><li><ul><li>action: eat</li><li>type: apple</li></ul></li><li><ul><li>action: mash</li><li>type: banana</li></ul></li></ul>', tpl.render(context));
+ }
+ ]
+);
+
+}
diff --git a/includes/js/dojox/dtl/tests/text/load.js b/includes/js/dojox/dtl/tests/text/load.js
new file mode 100644
index 0000000..b4c7472
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/text/load.js
@@ -0,0 +1,6 @@
+if(!dojo._hasResource["dojox.dtl.tests.text.load"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tests.text.load"] = true;
+dojo.provide("dojox.dtl.tests.text.load");
+// Test for the {% load %} tag
+
+}
diff --git a/includes/js/dojox/dtl/tests/text/tag.js b/includes/js/dojox/dtl/tests/text/tag.js
new file mode 100644
index 0000000..7abbc43
--- /dev/null
+++ b/includes/js/dojox/dtl/tests/text/tag.js
@@ -0,0 +1,480 @@
+if(!dojo._hasResource["dojox.dtl.tests.text.tag"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.dtl.tests.text.tag"] = true;
+dojo.provide("dojox.dtl.tests.text.tag");
+
+dojo.require("dojox.dtl");
+dojo.require("dojox.dtl.Context");
+
+doh.register("dojox.dtl.text.tag",
+ [
+ function test_tag_block_and_extends(t){
+ var dd = dojox.dtl;
+
+ // Simple (messy) string-based extension
+ var template = new dd.Template('{% extends "../../dojox/dtl/tests/templates/pocket.html" %}{% block pocket %}Simple{% endblock %}');
+ t.is("Simple Pocket", template.render());
+
+ // Variable replacement
+ var context = new dd.Context({
+ parent: "../../dojox/dtl/tests/templates/pocket.html"
+ })
+ template = new dd.Template('{% extends parent %}{% block pocket %}Variabled{% endblock %}');
+ t.is("Variabled Pocket", template.render(context));
+
+ // Nicer dojo.moduleUrl and variable based extension
+ context.parent = dojo.moduleUrl("dojox.dtl.tests.templates", "pocket.html");
+ template = new dd.Template('{% extends parent %}{% block pocket %}Slightly More Advanced{% endblock %}');
+ t.is("Slightly More Advanced Pocket", template.render(context));
+
+ // dojo.moduleUrl with support for more variables.
+ // This is important for HTML templates where the "shared" flag will be important.
+ context.parent = {
+ url: dojo.moduleUrl("dojox.dtl.tests.templates", "pocket.html")
+ }
+ template = new dd.Template('{% extends parent %}{% block pocket %}Super{% endblock %}');
+ t.is("Super Pocket", template.render(context));
+ },
+ function test_tag_block(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ parent: dojo.moduleUrl("dojox.dtl.tests.templates", "pocket2.html"),
+ items: ["apple", "banana", "lemon" ]
+ });
+
+ var template = new dd.Template("{% extends parent %}{% block pocket %}My {{ item }}{% endblock %}");
+ t.is("(My apple) (My banana) (My lemon) Pocket", template.render(context));
+ },
+ function test_tag_comment(t){
+ var dd = dojox.dtl;
+
+ var template = new dd.Template('Hot{% comment %}<strong>Make me disappear</strong>{% endcomment %} Pocket');
+ t.is("Hot Pocket", template.render());
+
+ var found = false;
+ try{
+ template = new dd.Template('Hot{% comment %}<strong>Make me disappear</strong> Pocket');
+ }catch(e){
+ t.is("Unclosed tag found when looking for endcomment", e.message);
+ found = true;
+ }
+ t.t(found);
+ },
+ function test_tag_cycle(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ items: ["apple", "banana", "lemon"],
+ unplugged: "Torrey"
+ });
+ var template = new dd.Template("{% for item in items %}{% cycle 'Hot' 'Diarrhea' unplugged 'Extra' %} Pocket. {% endfor %}");
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket. ", template.render(context));
+ // Make sure that it doesn't break on re-render
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket. ", template.render(context));
+
+ // Test repeating the loop
+ context.items.push("guava", "mango", "pineapple");
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket. Extra Pocket. Hot Pocket. Diarrhea Pocket. ", template.render(context));
+
+ // Repeat the above tests for the old style
+ // ========================================
+ context.items = context.items.slice(0, 3);
+ template = new dd.Template("{% for item in items %}{% cycle Hot,Diarrhea,Torrey,Extra %} Pocket. {% endfor %}");
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket. ", template.render(context));
+ // Make sure that it doesn't break on re-render
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket. ", template.render(context));
+
+ // Test repeating the loop
+ context.items.push("guava", "mango", "pineapple");
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket. Extra Pocket. Hot Pocket. Diarrhea Pocket. ", template.render(context));
+
+ // Now test outside of the for loop
+ // ================================
+ context = new dojox.dtl.Context({ unplugged: "Torrey" });
+ template = new dd.Template("{% cycle 'Hot' 'Diarrhea' unplugged 'Extra' as steakum %} Pocket. {% cycle steakum %} Pocket. {% cycle steakum %} Pocket.");
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket.", template.render(context));
+
+ template = new dd.Template("{% cycle 'Hot' 'Diarrhea' unplugged 'Extra' as steakum %} Pocket. {% cycle steakum %} Pocket. {% cycle steakum %} Pocket. {% cycle steakum %} Pocket. {% cycle steakum %} Pocket. {% cycle steakum %} Pocket.");
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket. Extra Pocket. Hot Pocket. Diarrhea Pocket.", template.render(context));
+//t.t(false)
+ // Test for nested objects
+ context.items = {
+ list: ["apple", "banana", "lemon"]
+ };
+ template = new dd.Template("{% for item in items.list %}{% cycle 'Hot' 'Diarrhea' unplugged 'Extra' %} Pocket. {% endfor %}");
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket. ", template.render(context));
+ // Make sure that it doesn't break on re-render
+ t.is("Hot Pocket. Diarrhea Pocket. Torrey Pocket. ", template.render(context));
+ },
+ function test_tag_debug(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ items: ["apple", "banana", "lemon"],
+ unplugged: "Torrey"
+ });
+ var template = new dd.Template("{% debug %}");
+ t.is('items: ["apple","banana","lemon"]\n\nunplugged: "Torrey"\n\n', template.render(context));
+ },
+ function test_tag_filter(t){
+ var dd = dojox.dtl;
+
+ var template = new dd.Template('{% filter lower|center:"15" %}Hot Pocket{% endfilter %}');
+ t.is(" hot pocket ", template.render());
+ },
+ function test_tag_firstof(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ found: "unicorn"
+ });
+
+ var template = new dd.Template("{% firstof one two three four found %}");
+ t.is("unicorn", template.render(context));
+
+ context.four = null;
+ t.is("null", template.render(context));
+
+ context.three = false;
+ t.is("false", template.render(context));
+ },
+ function test_tag_for(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ items: ["apple", "banana", "lemon"]
+ });
+ var template = new dd.Template("{% for item in items %}<li>{{ item }}</li>{% endfor %}");
+ t.is("<li>apple</li><li>banana</li><li>lemon</li>", template.render(context));
+
+ template = new dd.Template("{% for item in items reversed %}<li>{{ item }}</li>{% endfor %}");
+ t.is("<li>lemon</li><li>banana</li><li>apple</li>", template.render(context));
+
+ context.items = {
+ apple: "Red Delicious",
+ banana: "Cavendish",
+ lemon: "Citrus"
+ };
+ template = new dd.Template("{% for key, value in items.items %}<li>{{ value }} {{ key|title }}</li>{% endfor %}");
+ t.is("<li>Red Delicious Apple</li><li>Cavendish Banana</li><li>Citrus Lemon</li>", template.render(context));
+
+ // The same thing above, but using "zipped" sets
+ context.items = [
+ ["apple", "Red Delicious", 1.99],
+ ["banana", "Cavendish", 0.49],
+ ["lemon", "Citrus", 0.29]
+ ];
+ template = new dd.Template("{% for fruit, type, price in items %}<li>{{ type }} {{ fruit|title }} costs ${{ price}}</li>{% endfor %}");
+ t.is("<li>Red Delicious Apple costs $1.99</li><li>Cavendish Banana costs $0.49</li><li>Citrus Lemon costs $0.29</li>", template.render(context));
+
+ template = new dd.Template("{% for fruit, type, price in items reversed %}<li>{{ type }} {{ fruit|title }} costs ${{ price}}</li>{% endfor %}");
+ t.is("<li>Citrus Lemon costs $0.29</li><li>Cavendish Banana costs $0.49</li><li>Red Delicious Apple costs $1.99</li>", template.render(context));
+
+ // Now to create some errors
+ var found = false;
+ try {
+ template = new dd.Template("{% for item initems %}<li>{{ item }}</li>{% endfor %}");
+ }catch(e){
+ found = true;
+ t.is("'for' statements should have at least four words: for item initems", e.message);
+ }
+ t.t(found);
+
+ found = false;
+ try {
+ template = new dd.Template("{% for item ni items %}<li>{{ item }}</li>{% endfor %}");
+ }catch(e){
+ found = true;
+ t.is("'for' tag received an invalid argument: for item ni items", e.message);
+ }
+ t.t(found);
+
+ found = false;
+ try {
+ template = new dd.Template("{% for my item in items %}<li>{{ item }}</li>{% endfor %}");
+ }catch(e){
+ found = true;
+ t.is("'for' tag received an invalid argument: for my item in items", e.message);
+ }
+ t.t(found);
+ },
+ function test_tag_if(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ jokes: {
+ hot_pockets: true,
+ unicycles: true,
+ bacon: true
+ }
+ });
+ var template = new dd.Template("Comedian is {% if jokes.hot_pockets and jokes.unicycles and jokes.bacon %}funny{% else %}not funny{% endif %}");
+ t.is("Comedian is funny", template.render(context));
+
+ context.jokes.unicycles = false;
+ t.is("Comedian is not funny", template.render(context));
+
+ context.comedians = {
+ hedberg: true,
+ gaffigan: true,
+ cook: true
+ };
+ template = new dd.Template("Show will be {% if comedians.hedberg or comedians.gaffigan %}worth seeing{% else %}not worth seeing{% endif %}");
+ t.is("Show will be worth seeing", template.render(context));
+
+ // NOTE: "and" is implied by nesting. eg {% if sunny %}{% if windy %}It's Sunny and Windy{% endif %}{% endif %}
+ // Not mixing ands and ors allows for MUCH faster rendering
+ template = new dd.Template("Show will {% if comedians.hedberg or comedians.gaffigan %}{% if comedians.cook %}not {% endif %}be worth seeing{% else %}not be worth seeing{% endif %}");
+ t.is("Show will not be worth seeing", template.render(context));
+
+ context.comedians.cook = false;
+ t.is("Show will be worth seeing", template.render(context));
+
+ template = new dd.Template("Show will be {% if comedians.hedberg and comedians.gaffigan and not comedians.cook %}AWESOME{% else %}almost awesome{% endif %}");
+ t.is("Show will be AWESOME", template.render(context));
+
+ context.comedians.cook = true;
+ t.is("Show will be almost awesome", template.render(context));
+
+ // Now we test for errors.
+ var found = false;
+ try {
+ template = new dd.Template("Show will be {% if comedians.hedberg or comedians.gaffigan and not comedians.cook %}worth seeing{% else %}not worth seeing{% endif %}");
+ }catch(e){
+ found = true;
+ t.is("'if' tags can't mix 'and' and 'or'", e.message);
+ }
+ t.t(found);
+ },
+ function test_tag_ifchanged(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ year: 2008,
+ days: [
+ new Date(2008, 0, 12),
+ new Date(2008, 0, 28),
+ new Date(2008, 1, 1),
+ new Date(2008, 1, 1),
+ new Date(2008, 1, 1)
+ ]
+ });
+
+ var template = new dd.Template("<h1>Archive for {{ year }}</h1>"+
+"{% for date in days %}"+
+'{% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}'+
+'<a href="{{ date|date:\'M/d\'|lower }}/">{{ date|date:\'j\' }}</a>'+
+"{% endfor %}");
+ t.is('<h1>Archive for 2008</h1>'+
+'<h3>January</h3>'+
+'<a href="jan/12/">12</a>'+
+'<a href="jan/28/">28</a>'+
+'<h3>February</h3>'+
+'<a href="feb/01/">1</a>'+
+'<a href="feb/01/">1</a>'+
+'<a href="feb/01/">1</a>', template.render(context));
+
+ template = new dd.Template('{% for date in days %}'+
+'{% ifchanged date.date %} {{ date.date }} {% endifchanged %}'+
+'{% ifchanged date.hour date.date %}'+
+'{{ date.hour }}'+
+'{% endifchanged %}'+
+'{% endfor %}');
+ t.is(' 2008-01-12 0 2008-01-28 0 2008-02-01 0', template.render(context));
+ },
+ function test_tag_ifequal(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ user: {
+ id: 314
+ },
+ comment: {
+ user_id: 314
+ }
+ });
+
+ var template = new dd.Template("{% ifequal user.id comment.user_id %}You posted this{% endifequal %}");
+ t.is("You posted this", template.render(context));
+
+ context.user.id = 313;
+ t.is("", template.render(context));
+
+ // Errors
+ var found = false;
+ try {
+ template = new dd.Template("{% ifequal user.id %}You posted this{% endifequal %}");
+ }catch(e){
+ found = true;
+ t.is("ifequal takes two arguments", e.message);
+ }
+ t.t(found);
+
+ found = false;
+ try {
+ template = new dd.Template("{% ifequal user.id comment.user_id %}You posted this{% endif %}");
+ }catch(e){
+ found = true;
+ t.is("No tag found for endif", e.message);
+ }
+ t.t(found);
+ },
+ function test_tag_ifnotequal(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ favorite: "hedberg",
+ comedian: "cook"
+ });
+
+ var template = new dd.Template("{% ifnotequal favorite comedian %}Not your favorite{% else %}Your favorite{% endifnotequal %}");
+ t.is("Not your favorite", template.render(context));
+
+ context.comedian = "hedberg";
+ t.is("Your favorite", template.render(context));
+ },
+ function test_tag_include(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ hello: dojo.moduleUrl("dojox.dtl.tests.templates", "hello.html"),
+ person: "Bob",
+ people: ["Charles", "Ralph", "Julia"]
+ });
+
+ var template = new dd.Template("{% include hello %}");
+ t.is("Hello, <span>Bob</span>", template.render(context));
+
+ template = new dd.Template('{% include "../../dojox/dtl/tests/templates/hello.html" %}');
+ t.is("Hello, <span>Bob</span>", template.render(context));
+
+ template = new dd.Template('{% for person in people %}{% include hello %} {% endfor %}');
+ t.is("Hello, <span>Charles</span> Hello, <span>Ralph</span> Hello, <span>Julia</span> ", template.render(context));
+ },
+ function test_tag_load(t){
+ t.f(dojox.dtl.tests.text.load);
+ new dojox.dtl.Template("{% load dojox.dtl.tests.text.load %}");
+ t.t(dojox.dtl.tests.text.load);
+ },
+ function test_tag_now(t){
+ var dd = dojox.dtl;
+
+ var template = new dd.Template('It is {% now "jS F Y H:i" %}');
+ t.t(template.render().match(/^It is \d{1,2}[a-z]{2} [A-Z][a-z]+ [0-9]{4,} \d{2}:\d{2}$/));
+
+ template = new dd.Template('It is the {% now "jS \\o\\f F" %}');
+ t.t(template.render().match(/^It is the \d{1,2}[a-z]{2} of [A-Z][a-z]+$/));
+
+ template = new dd.Template("It is the {% now 'jS \\o\\f F' %}");
+ t.t(template.render().match(/^It is the \d{1,2}[a-z]{2} of [A-Z][a-z]+$/));
+
+ var found = false;
+ try{
+ template = new dd.Template("It is the {% now 'jS \\o\\f F %}");
+ }catch(e){
+ found = true;
+ t.is("'now' statement takes one argument", e.message);
+ }
+ t.t(found);
+
+ found = false;
+ try{
+ template = new dd.Template('It is the {% now "jS \\o\\f F %}');
+ }catch(e){
+ found = true;
+ t.is("'now' statement takes one argument", e.message);
+ }
+ t.t(found);
+ },
+ function test_tag_regroup(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ people: [
+ { firstName: "Bill", lastName: "Clinton", gender: "Male" },
+ { firstName: "Margaret", lastName: "Thatcher", gender: "Female" },
+ { firstName: "Path", lastName: "Smith", gender: "Unkown" },
+ { firstName: "Condoleezza", lastName: "Rice", gender: "Female" },
+ { firstName: "George", lastName: "Bush", gender: "Male" }
+ ]
+ });
+
+ var template = new dd.Template("{% regroup people|dictsort:'gender' by gender as grouped %}<ul>{% for group in grouped %}<li>{{ group.grouper }}<ul>{% for item in group.list %}<li>{{ item.firstName }} {{ item.lastName }}</li>{% endfor %}</ul></li>{% endfor %}</ul>");
+ t.t(template.render(context).match(new RegExp("^<ul><li>Female<ul><li>(Condoleezza Rice|Margaret Thatcher)</li><li>(Condoleezza Rice|Margaret Thatcher)</li></ul></li><li>Male<ul><li>(Bill Clinton|George Bush)</li><li>(Bill Clinton|George Bush)</li></ul></li><li>Unkown<ul><li>Path Smith</li></ul></li></ul>$")));
+ },
+ function test_tag_spaceless(t){
+ var dd = dojox.dtl;
+
+ var template = new dd.Template("{% spaceless %}<ul> \n <li>Hot</li> \n\n<li>Pocket </li>\n </ul>{% endspaceless %}");
+ t.is("<ul><li>Hot</li><li>Pocket </li></ul>", template.render());
+ },
+ function test_tag_ssi(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ hello: dojo.moduleUrl("dojox.dtl.tests.templates", "hello.html"),
+ person: "Bob",
+ people: ["Charles", "Ralph", "Julia"]
+ });
+
+ var template = new dd.Template("{% ssi hello parsed %}");
+ t.is("Hello, <span>Bob</span>", template.render(context));
+
+ template = new dd.Template("{% ssi hello %}");
+ t.is("Hello, <span>{{ person }}</span>", template.render(context));
+
+ template = new dd.Template('{% ssi "../../dojox/dtl/tests/templates/hello.html" parsed %}');
+ t.is("Hello, <span>Bob</span>", template.render(context));
+
+ template = new dd.Template('{% for person in people %}{% ssi hello parsed %} {% endfor %}');
+ t.is("Hello, <span>Charles</span> Hello, <span>Ralph</span> Hello, <span>Julia</span> ", template.render(context));
+ },
+ function test_tag_templatetag(t){
+ var dd = dojox.dtl;
+
+ var template = new dd.Template("{% templatetag openblock %}");
+ t.is("{%", template.render());
+ template = new dd.Template("{% templatetag closeblock %}");
+ t.is("%}", template.render());
+ template = new dd.Template("{% templatetag openvariable %}");
+ t.is("{{", template.render());
+ template = new dd.Template("{% templatetag closevariable %}");
+ t.is("}}", template.render());
+ template = new dd.Template("{% templatetag openbrace %}");
+ t.is("{", template.render());
+ template = new dd.Template("{% templatetag closebrace %}");
+ t.is("}", template.render());
+ template = new dd.Template("{% templatetag opencomment %}");
+ t.is("{#", template.render());
+ template = new dd.Template("{% templatetag closecomment %}");
+ t.is("#}", template.render());
+ },
+ function test_tag_widthratio(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ this_value: 175,
+ max_value: 200
+ });
+
+ var template = new dd.Template('<img src="bar.gif" height="10" width="{% widthratio this_value max_value 100 %}" />');
+ t.is('<img src="bar.gif" height="10" width="88" />', template.render(context));
+ },
+ function test_tag_with(t){
+ var dd = dojox.dtl;
+
+ var context = new dd.Context({
+ person: {
+ someSqlMethod: function(){
+ return 4815162342;
+ }
+ }
+ });
+
+ var template = new dd.Template('{% with person.someSqlMethod as total %}{{ total }} object{{ total|pluralize }}{% endwith %}')
+ t.is("4815162342 objects", template.render(context));
+ }
+ ]
+);
+
+}