We design and develop ambitious web and mobile applications,
A more official portfolio page is on its way, but in the meantime, check out
var CompilerContext, Ember, EmberHandlebars, Emblem, Handlebars, LoadedEmber, bindAttrHelper, compileWithPartials, equal, equals, ok, precompileEmber, runTextLineSuite, shouldCompileTo, shouldCompileToString, shouldCompileToWithPartials, shouldEmberPrecompileToHelper, shouldThrow, supportsEachHelperDataKeywords, supportsSubexpressions, throws, _equal, _ref, __hasProp = {}.hasOwnProperty; Ember = (typeof window !== "undefined" && window !== null ? window.Emblem : void 0) || this.Emblem || {}; LoadedEmber = LoadedEmber || {}; Ember.Handlebars = LoadedEmber.Handlebars; Ember.warn = LoadedEmber.warn; if (typeof Emblem !== "undefined" && Emblem !== null) { _equal = equal; equals = equal = function(a, b, msg) { return _equal(a, b, msg || ''); }; window.suite = module; } else { Handlebars = require('handlebars'); EmberHandlebars = require('./resources/ember-template-compiler.js').EmberHandlebars; Emblem = require('../lib/emblem'); expect = function() {};; _ref = require("assert"), equal = _ref.equal, equals = _ref.equals, ok = _ref.ok, throws = _ref.throws; } if (typeof CompilerContext === "undefined" || CompilerContext === null) { CompilerContext = { compile: function(template, options) { return Emblem.compile(Handlebars, template, options); } }; } supportsEachHelperDataKeywords = Handlebars.VERSION.slice(0, 3) >= 1.2; supportsSubexpressions = Handlebars.VERSION.slice(0, 3) >= 1.3; precompileEmber = function(emblem) { return Emblem.precompile(EmberHandlebars, emblem).toString(); }; shouldEmberPrecompileToHelper = function(emblem, helper) { var result; if (helper == null) { helper = 'bind-attr'; } result = precompileEmber(emblem); ok((result.match("helpers." + helper)) || (result.match("helpers\\['" + helper + "'\\]"))); return result; }; shouldCompileToString = function(string, hashOrArray, expected) { if (hashOrArray.constructor === String) { return shouldCompileToWithPartials(string, {}, false, hashOrArray, null, true); } else { return shouldCompileToWithPartials(string, hashOrArray, false, expected, null, true); } }; shouldCompileTo = function(string, hashOrArray, expected, message) { if (hashOrArray.constructor === String) { return shouldCompileToWithPartials(string, {}, false, hashOrArray, message); } else { return shouldCompileToWithPartials(string, hashOrArray, false, expected, message); } }; shouldCompileToWithPartials = function(string, hashOrArray, partials, expected, message, strings) { var options, result; options = null; if (strings) { options = {}; options.stringParams = true; } result = compileWithPartials(string, hashOrArray, partials, options); return equal(result, expected, "'" + result + "' should === '" + expected + "': " + message); }; compileWithPartials = function(string, hashOrArray, partials, options) { var ary, helpers, prop, template; if (options == null) { options = {}; } template = CompilerContext.compile(string, options); if (Object.prototype.toString.call(hashOrArray) === "[object Array]") { if (helpers = hashOrArray[1]) { for (prop in Handlebars.helpers) { helpers[prop] = helpers[prop] || Handlebars.helpers[prop]; } } ary = []; ary.push(hashOrArray[0]); ary.push({ helpers: hashOrArray[1], partials: hashOrArray[2] }); } else { ary = [hashOrArray]; } return template.apply(this, ary); }; shouldThrow = function(fn, exMessage) { var caught, e; caught = false; try { fn(); } catch (_error) { e = _error; caught = true; if (exMessage) { ok(e.message.match(exMessage), "exception message matched"); } } return ok(caught, "an exception was thrown"); }; Handlebars.registerHelper('echo', function(param) { return "ECHO " + param; }); suite("html one-liners"); test("element only", function() { return shouldCompileTo("p", "
"); }); test("with text", function() { return shouldCompileTo("p Hello", "Hello
"); }); test("with more complex text", function() { return shouldCompileTo("p Hello, how's it going with you today?", "Hello, how's it going with you today?
"); }); test("with trailing space", function() { return shouldCompileTo("p Hello ", "Hello
"); }); suite("html multi-lines"); test("two lines", function() { var emblem; emblem = "p This is\n pretty cool."; return shouldCompileTo(emblem, "This is pretty cool.
"); }); test("three lines", function() { var emblem; emblem = "p This is\n pretty damn\n cool."; return shouldCompileTo(emblem, "This is pretty damn cool.
"); }); test("three lines w/ embedded html", function() { var emblem; emblem = "p This is\n pretty damn\n cool."; return shouldCompileTo(emblem, "This is pretty damn cool.
"); }); test("indentation doesn't need to match starting inline content's", function() { var emblem; emblem = "span Hello,\n How are you?"; return shouldCompileTo(emblem, "Hello, How are you?"); }); test("indentation may vary between parent/child, must be consistent within inline-block", function() { var emblem; emblem = "div\n span Hello,\n How are you?\n Excellent.\n p asd"; shouldCompileTo(emblem, "asd
Hello,
Hello,
This is pretty cool.
Hello.
"); }); suite('#{} syntax'); test('acts like {{}}', function() { var emblem; emblem = 'span Yo #{foo}, I herd.'; return shouldCompileTo(emblem, { foo: '123' }, "Yo <span>123</span>, I herd."); }); test('can start inline content', function() { var emblem; emblem = 'span #{foo}, I herd.'; return shouldCompileTo(emblem, { foo: "dawg" }, "dawg, I herd."); }); test('can end inline content', function() { var emblem; emblem = 'span I herd #{foo}'; return shouldCompileTo(emblem, { foo: "dawg" }, "I herd dawg"); }); test("doesn't screw up parsing when # used in text nodes", function() { var emblem; emblem = 'span OMG #YOLO'; return shouldCompileTo(emblem, "OMG #YOLO"); }); test("# can be only thing on line", function() { var emblem; emblem = 'span #'; return shouldCompileTo(emblem, "#"); }); /* TODO: this test "can be escaped", -> emblem = ''' span #\\{yes} ''' shouldCompileTo emblem, '#{yes}' */ runTextLineSuite = function(ch) { var sct; sct = function(emblem, obj, expected) { if (expected == null) { expected = obj; obj = {}; } if (ch !== '`') { expected = expected.replace(/\n/g, ""); } if (ch === "'") { expected = expected.replace(/\t/g, " "); } else { expected = expected.replace(/\t/g, ""); } emblem = emblem.replace(/_/g, ch); return shouldCompileTo(emblem, obj, expected); }; suite("text lines starting with '" + ch + "'"); test("basic", function() { return sct("_ What what", "What what\n\t"); }); test("with html", function() { return sct('_ What what!', 'What what!\n\t'); }); test("multiline", function() { var emblem; emblem = "_ Blork\n Snork"; return sct(emblem, "Blork\nSnork\n\t"); }); test("triple multiline", function() { var emblem; emblem = "_ Blork\n Snork\n Bork"; return sct(emblem, "Blork\nSnork\nBork\n\t"); }); test("quadruple multiline", function() { var emblem; emblem = "_ Blork\n Snork\n Bork\n Fork"; return sct(emblem, "Blork\nSnork\nBork\nFork\n\t"); }); test("multiline w/ trailing whitespace", function() { var emblem; emblem = "_ Blork \n Snork"; return sct(emblem, "Blork \nSnork\n\t"); }); test("secondline", function() { var emblem; emblem = "_\n Good"; return sct(emblem, "Good\n\t"); }); test("secondline multiline", function() { var emblem; emblem = "_ \n Good\n Bork"; return sct(emblem, "Good\nBork\n\t"); }); test("with a mustache", function() { var emblem; emblem = "_ Bork {{foo}}!"; return sct(emblem, { foo: "YEAH" }, 'Bork YEAH!\n\t'); }); test("with mustaches", function() { var emblem; emblem = "_ Bork {{foo}} {{{bar}}}!"; return sct(emblem, { foo: "YEAH", bar: "NO" }, 'Bork YEAH NO!\n\t'); }); test("indented, then in a row", function() { var emblem; expect(0); return "PENDING"; emblem = "_ \n Good\n riddance2\n dude\n gnar\n foo"; return sct(emblem, "Good\n riddance2\n dude\n gnar\n foo\n\t"); }); test("indented, then in a row, then indented", function() { var emblem; expect(0); return "PENDING"; emblem = "_ \n Good\n riddance2\n dude\n gnar\n foo\n far\n faz"; return sct(emblem, "Good \n riddance2 \n dude \n gnar \n foo \n far \n faz \n\t"); }); test("uneven indentation megatest", function() { var emblem; expect(0); return "PENDING"; emblem = "_ \n Good\n riddance\n dude"; sct(emblem, "Good\n riddance\ndude\n\t"); emblem = "_ \n Good\n riddance3\n dude"; sct(emblem, "Good\n riddance3\n dude\n\t"); emblem = "_ Good\n riddance\n dude"; return sct(emblem, "Good\nriddance\n dude\n\t"); }); test("on each line", function() { var emblem; emblem = "pre\n _ This\n _ should\n _ hopefully\n _ work, and work well."; return sct(emblem, 'This\n\t should\n\t hopefully\n\t work, and work well.\n\t'); }); return test("with blank", function() { var emblem; emblem = "pre\n _ This\n _ should\n _\n _ hopefully\n _ work, and work well."; return sct(emblem, '
This\n\t should\n\t\n\t hopefully\n\t work, and work well.\n\t'); }); }; runTextLineSuite('|'); runTextLineSuite('`'); runTextLineSuite("'"); suite("text line starting with angle bracket"); test("can start with angle bracket html", function() { var emblem; emblem = "Hello"; return shouldCompileTo(emblem, "Hello"); }); test("can start with angle bracket html and go to multiple lines", function() { var emblem; emblem = "Hello dude, \n what's up?"; return shouldCompileTo(emblem, "Hello dude, what's up?"); }); suite("preprocessor"); test("it strips out preceding whitespace", function() { var emblem; emblem = "\np Hello"; return shouldCompileTo(emblem, "
Hello
"); }); test("it handles preceding indentation", function() { var emblem; emblem = " p Woot\n p Ha"; return shouldCompileTo(emblem, "Woot
Ha
"); }); test("it handles preceding indentation and newlines", function() { var emblem; emblem = "\n p Woot\n p Ha"; return shouldCompileTo(emblem, "Woot
Ha
"); }); test("it handles preceding indentation and newlines pt 2", function() { var emblem; emblem = " \n p Woot\n p Ha"; return shouldCompileTo(emblem, "Woot
Ha
"); }); suite("comments"); test("it strips out single line '/' comments", function() { var emblem; emblem = "p Hello\n\n/ A comment\n\nh1 How are you?"; return shouldCompileTo(emblem, "Hello
Hello
Hello
Hello
Yessir nope.
"); }); test("uneven indentation", function() { var emblem; emblem = "/ nop\n nope\n nope"; return shouldCompileTo(emblem, ""); }); test("uneven indentation 2", function() { var emblem; emblem = "/ n\n no\n nop\n nope"; return shouldCompileTo(emblem, ""); }); test("uneven indentation 3", function() { var emblem; emblem = "/ n\n no\n nop\n nope"; return shouldCompileTo(emblem, ""); }); test("empty first line", function() { var emblem; emblem = "/ \n nop\n nope\n nope\n no"; return shouldCompileTo(emblem, ""); }); test("on same line as html content", function() { var emblem; emblem = ".container / This comment doesn't show up\n .row / Nor does this\n p Hello"; return shouldCompileTo(emblem, 'Hello
Hello p invalid
"); }); test("it throws on half dedent", function() { var emblem; emblem = "p\n span This is ok\n span This aint"; return shouldThrow(function() { return CompilerContext.compile(emblem); }); }); test("new indentation levels don't have to match parents'", function() { var emblem; emblem = "p \n span\n div\n span yes"; return shouldCompileTo(emblem, "asd
"); return shouldCompileTo("p \nspan \n\ndiv\nspan", ""); }); test("spaces after mustaches", function() { return shouldCompileTo("each foo \n p \n span", { foo: [1, 2] }, ""); }); suite("attribute shorthand"); test("id shorthand", function() { shouldCompileTo("#woot", ''); return shouldCompileTo("span#woot", ''); }); test("class shorthand", function() { shouldCompileTo(".woot", ''); shouldCompileTo("span.woot", ''); return shouldCompileTo("span.woot.loot", ''); }); test("class can come first", function() { shouldCompileTo(".woot#hello", ''); shouldCompileTo("span.woot#hello", ''); shouldCompileTo("span.woot.loot#hello", ''); return shouldCompileTo("span.woot.loot#hello.boot", ''); }); suite("full attributes - tags with content"); test("class only", function() { return shouldCompileTo('p class="yes" Blork', 'Blork
'); }); test("id only", function() { return shouldCompileTo('p id="yes" Hyeah', 'Hyeah
'); }); test("class and id", function() { return shouldCompileTo('p id="yes" class="no" Blork', 'Blork
'); }); test("class and id and embedded html one-liner", function() { return shouldCompileTo('p id="yes" class="no" One asd!', 'One asd!
'); }); test("bracketed attributes", function() { var emblem; emblem = "p [\n id=\"yes\"\n class=\"no\" ]\n | Bracketed Attributes FTW!"; return shouldCompileTo(emblem, 'Bracketed Attributes FTW!
'); }); test("bracketed text", function() { var emblem; emblem = "p [ Bracketed text is cool ]"; return shouldCompileTo(emblem, '[ Bracketed text is cool ]
'); }); test("bracketed text indented", function() { var emblem; emblem = "p\n | [ Bracketed text is cool ]"; return shouldCompileTo(emblem, '[ Bracketed text is cool ]
'); }); test("nesting", function() { var emblem; emblem = "p class=\"hello\" data-foo=\"gnarly\"\n span Yes"; return shouldCompileTo(emblem, 'Yes
'); }); suite("full attributes - mixed quotes"); test("single empty", function() { return shouldCompileTo("p class=''", ''); }); test("single full", function() { return shouldCompileTo("p class='woot yeah'", ''); }); test("mixed", function() { return shouldCompileTo("p class='woot \"oof\" yeah'", ''); }); suite("full attributes - tags without content"); test("empty", function() { return shouldCompileTo('p class=""', ''); }); test("class only", function() { return shouldCompileTo('p class="yes"', ''); }); test("id only", function() { return shouldCompileTo('p id="yes"', ''); }); test("class and id", function() { return shouldCompileTo('p id="yes" class="no"', ''); }); suite("full attributes w/ mustaches"); test("with mustache", function() { var emblem; shouldCompileTo('p class="foo {{yes}}"', { yes: "ALEX" }, ''); shouldCompileTo('p class="foo {{yes}}" Hello', { yes: "ALEX" }, 'Hello
'); emblem = "p class=\"foo {{yes}}\"\n | Hello"; return shouldCompileTo(emblem, { yes: "ALEX" }, 'Hello
'); }); test("with mustache calling helper", function() { var emblem; shouldCompileTo('p class="foo {{{echo "YES"}}}"', ''); shouldCompileTo('p class="foo #{echo "NO"} and {{{echo "YES"}}}" Hello', 'Hello
'); emblem = "p class=\"foo {{echo \"BORF\"}}\"\n | Hello"; return shouldCompileTo(emblem, 'Hello
'); }); suite("boolean attributes"); test("static", function() { shouldCompileTo('p borf=true', ''); shouldCompileTo('p borf=true Woot', 'Woot
'); shouldCompileTo('p borf=false', ''); shouldCompileTo('p borf=false Nork', 'Nork
'); return shouldCompileTo('option selected=true Thingeroo', ''); }); suite("html nested"); test("basic", function() { var emblem; emblem = "p\n span Hello\n strong Hi\ndiv\n p Hooray"; return shouldCompileTo(emblem, 'HelloHi
Hooray
'); }); test("empty nest w/ attribute shorthand", function() { var emblem; emblem = "p.woo\n span#yes\n strong.no.yes\n i"; return shouldCompileTo(emblem, '
'); }); suite("simple mustache"); test("various one-liners", function() { var emblem; emblem = "= foo\narf\np = foo\nspan.foo\np data-foo=\"yes\" = goo"; return shouldCompileTo(emblem, { foo: "ASD", arf: "QWE", goo: "WER" }, 'ASDQWE
ASD
WER
'); }); test("double =='s un-escape", function() { var emblem; emblem = "== foo\nfoo\np == foo"; return shouldCompileTo(emblem, { foo: '123' }, '123<span>123</span>123
'); }); test("nested combo syntax", function() { var emblem; emblem = "ul = each items\n li = foo"; return shouldCompileTo(emblem, { items: [ { foo: "YEAH" }, { foo: "BOI" } ] }, 'Hello
Hello
Hello
Bracketed helper attrs!
Yeah erp
'); }); suite("bang syntax defaults to `unbound` helper syntax"); Handlebars.registerHelper('unbound', function() { var content, options, params, stringedParams; options = arguments[arguments.length - 1]; params = Array.prototype.slice.call(arguments, 0, -1); stringedParams = params.join(' '); content = options.fn ? options.fn(this) : stringedParams; return new Handlebars.SafeString("Yeah
'); }); test("else works", function() { var emblem; emblem = "foo?\n p Yeah\nelse\n p No"; return shouldCompileTo(emblem, { foo: false }, 'No
'); }); test("compound", function() { var emblem; emblem = "p = foo? \n | Hooray\nelse\n | No\np = bar? \n | Hooray\nelse\n | No"; return shouldCompileTo(emblem, { foo: true, bar: false }, 'Hooray
No
'); }); test("compound", function() { var emblem; emblem = "p = foo? \n bar\nelse\n baz"; return shouldCompileTo(emblem, { foo: true, bar: "borf", baz: "narsty" }, 'borf
'); }); suite("conditionals"); test("simple if statement", function() { var emblem; emblem = "if foo\n | Foo\nif bar\n | Bar"; return shouldCompileTo(emblem, { foo: true, bar: false }, 'Foo'); }); test("if else ", function() { var emblem; emblem = "if foo\n | Foo\n if bar\n | Bar\n else\n | Woot\nelse\n | WRONG\nif bar\n | WRONG\nelse\n | Hooray"; return shouldCompileTo(emblem, { foo: true, bar: false }, 'FooWootHooray'); }); test("else with preceding `=`", function() { var emblem; emblem = "= if foo\n p Yeah\n= else\n p No\n= if bar\n p Yeah!\n= else\n p No!\n=if bar\n p Yeah!\n=else\n p No!"; return shouldCompileTo(emblem, { foo: true, bar: false }, 'Yeah
No!
No!
'); }); test("unless", function() { var emblem; emblem = "unless bar\n | Foo\n unless foo\n | Bar\n else\n | Woot\nelse\n | WRONG\nunless foo\n | WRONG\nelse\n | Hooray"; return shouldCompileTo(emblem, { foo: true, bar: false }, 'FooWootHooray'); }); test("else followed by newline doesn't gobble else content", function() { var emblem; emblem = "if something\n p something\nelse\n\n if nothing\n p nothing\n else\n p not nothing"; return shouldCompileTo(emblem, {}, 'not nothing
'); }); suite("class shorthand and explicit declaration is coalesced"); test("when literal class is used", function() { return shouldCompileTo('p.foo class="bar"', ''); }); test("when ember expression is used with variable", function() { return shouldCompileTo('p.foo class=bar', { bar: 'baz' }, ''); }); test("when ember expression is used with variable in braces", function() { var result; result = shouldEmberPrecompileToHelper('p.foo class={ bar }'); return ok(-1 !== result.indexOf('\'class\': (":foo bar")')); }); test("when ember expression is used with constant in braces", function() { var result; result = shouldEmberPrecompileToHelper('p.foo class={ :bar }'); return ok(-1 !== result.indexOf('\'class\': (":foo :bar")')); }); test("when ember expression is used with constant and variable in braces", function() { var result; result = shouldEmberPrecompileToHelper('p.foo class={ :bar bar }'); return ok(-1 !== result.indexOf('\'class\': (":foo :bar bar")')); }); test("when ember expression is used with bind-attr", function() { var result; result = shouldEmberPrecompileToHelper('p.foo{ bind-attr class="bar" }'); return ok(-1 !== result.indexOf('\'class\': (":foo bar")')); }); test("when ember expression is used with bind-attr and multiple attrs", function() { var result; result = shouldEmberPrecompileToHelper('p.foo{ bind-attr something=bind class="bar" }'); return ok(-1 !== result.indexOf('\'class\': (":foo bar")')); }); test("only with bind-attr helper", function() { var result; result = shouldEmberPrecompileToHelper('p.foo{ someHelper class="bar" }', 'someHelper'); ok(-1 !== result.indexOf('\'class\': ("bar")')); return ok(-1 !== result.indexOf('class=\\"foo\\"')); }); bindAttrHelper = function() { var bindingString, k, options, param, params, v, _ref1; options = arguments[arguments.length - 1]; params = Array.prototype.slice.call(arguments, 0, -1); bindingString = ""; _ref1 = options.hash; for (k in _ref1) { if (!__hasProp.call(_ref1, k)) continue; v = _ref1[k]; bindingString += " " + k + " to " + v; } if (!bindingString) { bindingString = " narf"; } param = params[0] || 'none'; return "bind-attr" + bindingString; }; Handlebars.registerHelper('bind-attr', bindAttrHelper); EmberHandlebars.registerHelper('bind-attr', bindAttrHelper); suite("bind-attr behavior for unquoted attribute values"); test("basic", function() { var emblem; emblem = 'p class=foo'; shouldCompileTo(emblem, { foo: "YEAH" }, ''); return shouldEmberPrecompileToHelper(emblem); }); test("basic w/ underscore", function() { var emblem; emblem = 'p class=foo_urns'; shouldCompileTo(emblem, { foo_urns: "YEAH" }, ''); return shouldEmberPrecompileToHelper(emblem); }); test("subproperties", function() { var emblem; emblem = 'p class=foo._death.woot'; shouldCompileTo(emblem, { foo: { _death: { woot: "YEAH" } } }, ''); return shouldEmberPrecompileToHelper(emblem); }); test("multiple", function() { return shouldCompileTo('p class=foo id="yup" data-thinger=yeah Hooray', { foo: "FOO", yeah: "YEAH" }, 'Hooray
'); }); test("class bind-attr special syntax", function() { var emblem; emblem = 'p class=foo:bar:baz'; shouldEmberPrecompileToHelper(emblem); return shouldThrow((function() { return CompilerContext.compile(emblem); })); }); test("class bind-attr braced syntax w/ underscores and dashes", function() { var emblem; shouldEmberPrecompileToHelper('p class={f-oo:bar :b_az}'); shouldEmberPrecompileToHelper('p class={ f-oo:bar :b_az }'); shouldEmberPrecompileToHelper('p class={ f-oo:bar :b_az } Hello'); emblem = ".input-prepend class={ filterOn:input-append }\n span.add-on"; return shouldEmberPrecompileToHelper(emblem); }); test("exclamation modifier (vanilla)", function() { var emblem; emblem = 'p class=foo!'; return shouldCompileTo(emblem, { foo: "YEAH" }, ''); }); test("exclamation modifier (ember)", function() { var emblem, result; emblem = 'p class=foo!'; result = precompileEmber(emblem); ok(result.match(/p class/)); return ok(result.match(/helpers\.unbound.*foo/)); }); suite("in-tag explicit mustache"); Handlebars.registerHelper('inTagHelper', function(p) { return p; }); test("single", function() { return shouldCompileTo('p{inTagHelper foo}', { foo: "ALEX" }, ''); }); test("double", function() { return shouldCompileTo('p{inTagHelper foo}', { foo: "ALEX" }, ''); }); test("triple", function() { return shouldCompileTo('p{inTagHelper foo}', { foo: "ALEX" }, ''); }); Handlebars.registerHelper('insertClass', function(p) { return 'class="' + p + '"'; }); test("with singlestache", function() { return shouldCompileTo('p{insertClass foo} Hello', { foo: "yar" }, 'Hello
'); }); test("singlestache can be used in text nodes", function() { return shouldCompileTo('p Hello {dork}', 'Hello {dork}
'); }); test("with doublestache", function() { return shouldCompileTo('p{{insertClass foo}} Hello', { foo: "yar" }, 'Hello
'); }); test("with triplestache", function() { return shouldCompileTo('p{{{insertClass foo}}} Hello', { foo: "yar" }, 'Hello
'); }); test("multiple", function() { return shouldCompileTo('p{{{insertClass foo}}}{{{insertClass boo}}} Hello', { foo: "yar", boo: "nar" }, 'Hello
'); }); test("with nesting", function() { var emblem; emblem = "p{{bind-attr class=\"foo\"}}\n span Hello"; return shouldCompileTo(emblem, { foo: "yar" }, 'Hello
'); }); suite("actions"); Handlebars.registerHelper('action', function() { var hashString, k, options, params, paramsString, v, _ref1; options = arguments[arguments.length - 1]; params = Array.prototype.slice.call(arguments, 0, -1); hashString = ""; paramsString = params.join('|'); _ref1 = options.hash; for (k in _ref1) { if (!__hasProp.call(_ref1, k)) continue; v = _ref1[k]; hashString += " " + k + "=" + v; } if (!hashString) { hashString = " nohash"; } return "action " + paramsString + hashString; }); test("basic (click)", function() { var emblem; emblem = "button click=\"submitComment\" Submit Comment"; return shouldCompileToString(emblem, ''); }); test("basic (click) followed by attr", function() { var emblem; emblem = "button click=\"submitComment\" class=\"foo\" Submit Comment"; shouldCompileToString(emblem, ''); emblem = "button click=\"submitComment 'omg'\" class=\"foo\" Submit Comment"; return shouldCompileToString(emblem, ''); }); test("nested (mouseEnter)", function() { var emblem; emblem = "a mouseEnter='submitComment target=\"view\"'\n | Submit Comment"; return shouldCompileToString(emblem, 'Submit Comment'); }); test("nested (mouseEnter, doublequoted)", function() { var emblem; emblem = "a mouseEnter=\"submitComment target='view'\"\n | Submit Comment"; return shouldCompileToString(emblem, 'Submit Comment'); }); test("manual", function() { var emblem; emblem = "a{action submitComment target=\"view\"} Submit Comment"; return shouldCompileToString(emblem, 'Submit Comment'); }); test("manual nested", function() { var emblem; emblem = "a{action submitComment target=\"view\"}\n p Submit Comment"; return shouldCompileToString(emblem, 'Submit Comment
'); }); suite("haml style"); test("basic", function() { var emblem; emblem = "%borf"; return shouldCompileToString(emblem, 'Hello
LOL!
BORF!
Hello
')); }); suite("old school handlebars"); test("array", function() { var emblem, hash; emblem = 'goodbyes\n | #{text}! \n| cruel #{world}!'; hash = { goodbyes: [ { text: "goodbye" }, { text: "Goodbye" }, { text: "GOODBYE" } ], world: "world" }; shouldCompileToString(emblem, hash, "goodbye! Goodbye! GOODBYE! cruel world!"); hash = { goodbyes: [], world: "world" }; return shouldCompileToString(emblem, hash, "cruel world!"); }); Handlebars.registerPartial('hbPartial', '{{name}}'); test("calling handlebars partial", function() { var emblem; emblem = '> hbPartial\n| Hello #{> hbPartial}'; return shouldCompileToString(emblem, { id: 666, name: "Death" }, 'DeathHello Death'); }); Emblem.registerPartial(Handlebars, 'emblemPartial', 'a href="/people/{{id}}" = name'); Emblem.registerPartial(Handlebars, 'emblemPartialB', 'p Grr'); Emblem.registerPartial(Handlebars, 'emblemPartialC', 'p = a'); test("calling emblem partial", function() { return shouldCompileToString('> emblemPartial', { id: 666, name: "Death" }, 'Death'); }); test("calling emblem partial with context", function() { return shouldCompileToString('> emblemPartialC foo', { foo: { a: "YES" } }, 'YES
'); }); test("partials in mustaches", function() { var emblem; emblem = "| Hello, {{> emblemPartialC foo}}{{>emblemPartialB}}{{>emblemPartialB }}"; return shouldCompileToString(emblem, { foo: { a: "YES" } }, 'Hello,YES
Grr
Grr
'); }); test("handlebars dot-separated paths with segment-literal notation", function() { var emblem; emblem = 'p = articles.[3]'; return shouldCompileTo(emblem, { articles: ['zero', 'one', 'two', 'three'] }, 'three
'); }); test("handlebars dot-separated paths with segment-literal notation, more nesting", function() { var emblem; emblem = 'p = articles.[3].[#comments].[0]'; return shouldCompileTo(emblem, { articles: [ {}, {}, {}, { '#comments': ['bazinga'] } ] }, 'bazinga
'); }); test("../path as inMustacheParam recognized correctly as pathIdNode instead of classShorthand", function() { var emblem; Handlebars.registerHelper('jumpToParent', function(link) { return new Handlebars.SafeString("Jump to parent top"); }); emblem = 'each children\n jumpToParent ../parentLink'; return shouldCompileTo(emblem, { parentLink: '#anchor', children: [{}] }, 'Jump to parent top'); }); test("block as #each", function() { var emblem; emblem = 'thangs\n p Woot #{yeah}'; return shouldCompileToString(emblem, { thangs: [ { yeah: 123 }, { yeah: 456 } ] }, 'Woot 123
Woot 456
'); }); if (supportsEachHelperDataKeywords) { suite("each block helper keywords prefixed by @"); test("#each with @index", function() { var emblem; emblem = 'thangs\n p #{@index} Woot #{yeah}'; return shouldCompileToString(emblem, { thangs: [ { yeah: 123 }, { yeah: 456 } ] }, '0 Woot 123
1 Woot 456
'); }); test("#each with @key", function() { var emblem; emblem = 'each thangs\n p #{@key}: #{this}'; return shouldCompileTo(emblem, { thangs: { '@key': 123, 'works!': 456 } }, '@key: 123
works!: 456
'); }); test("#each with @key, @index", function() { var emblem; emblem = 'each thangs\n p #{@index} #{@key}: #{this}'; return shouldCompileTo(emblem, { thangs: { '@key': 123, 'works!': 456 } }, '0 @key: 123
1 works!: 456
'); }); test("#each with @key, @first", function() { var emblem; emblem = 'each thangs\n if @first\n p First item\n else\n p #{@key}: #{this}'; return shouldCompileTo(emblem, { thangs: { '@key': 123, 'works!': 456 } }, 'First item
works!: 456
'); }); } /* test "partial in block", -> emblem = """ ul = people > link """ data = people: [ { "name": "Alan", "id": 1 } { "name": "Yehuda", "id": 2 } ] shouldCompileToString emblem, data, '\n This be some text\n
This be some text
\nThis be some text\n
This be some text
\n We design and develop ambitious web and mobile applications, \n
\n\n A more official portfolio page is on its way, but in the meantime, \n check out\n
\nWe design and develop ambitious web and mobile applications,
A more official portfolio page is on its way, but in the meantime, check out
Alex
AlexEmily
Emily'); }); suite("colon separator"); test("basic", function() { var emblem; emblem = 'each foo: p Hello, #{this}'; return shouldCompileTo(emblem, { foo: ["Alex", "Emily", "Nicole"] }, 'Hello, Alex
Hello, Emily
Hello, Nicole
'); }); test("html stack", function() { var emblem; emblem = '.container: .row: .span5: span Hello'; return shouldCompileToString(emblem, 'alex
This\n should\n hopefully\n work, and work well.\n'); }); test("mixture", function() { var emblem; emblem = " \n"; emblem += " p Hello\n"; emblem += " p\n"; emblem += " | Woot\n"; emblem += " span yes\n"; return shouldCompileToString(emblem, '
Hello
Woot
yes'); }); test("mixture w/o opening blank", function() { var emblem; emblem = " p Hello\n"; emblem += " p\n"; emblem += " | Woot\n"; emblem += " span yes\n"; return shouldCompileToString(emblem, 'Hello
Woot
yes'); }); test("w/ blank lines", function() { var emblem; emblem = " p Hello\n"; emblem += " p\n"; emblem += "\n"; emblem += " | Woot\n"; emblem += "\n"; emblem += " span yes\n"; return shouldCompileToString(emblem, 'Hello
Woot
yes'); }); test("w/ blank whitespaced lines", function() { var emblem; emblem = " p Hello\n"; emblem += " p\n"; emblem += "\n"; emblem += " | Woot\n"; emblem += " \n"; emblem += " \n"; emblem += " \n"; emblem += "\n"; emblem += " span yes\n"; emblem += "\n"; emblem += " sally\n"; emblem += "\n"; emblem += " \n"; emblem += " | Woot\n"; return shouldCompileToString(emblem, 'Hello
Woot
yesHello, How are you?
I'm fine, thank you.
"); }); suite("misc."); test("end with indent", function() { var emblem; expect(0); return "PENDING"; emblem = "div\n p\n span Butts\n em fpokasd\n iunw\n paosdk"; return shouldCompileToString(emblem, 'Buttsem fpokasdiunw paosdk
Hello
'); }); if (supportsSubexpressions) { suite("subexpressions"); Handlebars.registerHelper('echo', function(param) { return "ECHO " + param; }); Handlebars.registerHelper('echofun', function() { var options; options = Array.prototype.pop.call(arguments); return "FUN = " + options.hash.fun; }); Handlebars.registerHelper('hello', function(param) { return "hello"; }); Handlebars.registerHelper('equal', function(x, y) { return x === y; }); test("arg-less helper", function() { var emblem; emblem = 'p {{echo (hello)}}'; shouldCompileTo(emblem, 'ECHO hello
'); emblem = '= echo (hello)'; return shouldCompileTo(emblem, 'ECHO hello'); }); test("helper w args", function() { var emblem; emblem = 'p {{echo (equal 1 1)}}'; shouldCompileTo(emblem, 'ECHO true
'); emblem = '= echo (equal 1 1)'; return shouldCompileTo(emblem, 'ECHO true'); }); test("supports much nesting", function() { var emblem; emblem = 'p {{echo (equal (equal 1 1) true)}}'; shouldCompileTo(emblem, 'ECHO true
'); emblem = '= echo (equal (equal 1 1) true)'; return shouldCompileTo(emblem, 'ECHO true'); }); test("with hashes", function() { var emblem; emblem = 'p {{echo (equal (equal 1 1) true fun="yes")}}'; shouldCompileTo(emblem, 'ECHO true
'); emblem = '= echo (equal (equal 1 1) true fun="yes")'; return shouldCompileTo(emblem, 'ECHO true'); }); test("as hashes", function() { var emblem; emblem = 'p {{echofun fun=(equal 1 1)}}'; shouldCompileTo(emblem, 'FUN = true
'); emblem = '= echofun fun=(equal 1 1)'; return shouldCompileTo(emblem, 'FUN = true'); }); test("complex expression", function() { var emblem; emblem = 'p {{echofun true (hello how="are" you=false) 1 not=true fun=(equal "ECHO hello" (echo (hello))) win="yes"}}'; shouldCompileTo(emblem, 'FUN = true
'); emblem = '= echofun true (hello how="are" you=false) 1 not=true fun=(equal "ECHO hello" (echo (hello))) win="yes"'; return shouldCompileTo(emblem, 'FUN = true'); }); }