mirror of
https://github.com/thedjinn/js303.git
synced 2025-08-17 15:58:13 +02:00
1919 lines
57 KiB
JavaScript
1919 lines
57 KiB
JavaScript
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", "<p></p>");
|
|
});
|
|
|
|
test("with text", function() {
|
|
return shouldCompileTo("p Hello", "<p>Hello</p>");
|
|
});
|
|
|
|
test("with more complex text", function() {
|
|
return shouldCompileTo("p Hello, how's it going with you today?", "<p>Hello, how's it going with you today?</p>");
|
|
});
|
|
|
|
test("with trailing space", function() {
|
|
return shouldCompileTo("p Hello ", "<p>Hello </p>");
|
|
});
|
|
|
|
suite("html multi-lines");
|
|
|
|
test("two lines", function() {
|
|
var emblem;
|
|
emblem = "p This is\n pretty cool.";
|
|
return shouldCompileTo(emblem, "<p>This is pretty cool.</p>");
|
|
});
|
|
|
|
test("three lines", function() {
|
|
var emblem;
|
|
emblem = "p This is\n pretty damn\n cool.";
|
|
return shouldCompileTo(emblem, "<p>This is pretty damn cool.</p>");
|
|
});
|
|
|
|
test("three lines w/ embedded html", function() {
|
|
var emblem;
|
|
emblem = "p This is\n pretty <span>damn</span>\n cool.";
|
|
return shouldCompileTo(emblem, "<p>This is pretty <span>damn</span> cool.</p>");
|
|
});
|
|
|
|
test("indentation doesn't need to match starting inline content's", function() {
|
|
var emblem;
|
|
emblem = "span Hello,\n How are you?";
|
|
return shouldCompileTo(emblem, "<span>Hello, How are you?</span>");
|
|
});
|
|
|
|
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, "<div><span>Hello, How are you? Excellent.</span><p>asd</p></div>");
|
|
emblem = "div\n span Hello,\n How are you?\n Excellent.";
|
|
return shouldThrow(function() {
|
|
return CompilerContext.compile(emblem);
|
|
});
|
|
});
|
|
|
|
test("indentation may vary between parent/child, must be consistent within inline-block pt 2", function() {
|
|
var emblem;
|
|
emblem = "div\n span Hello,\n How are you?\n Excellent.";
|
|
return shouldCompileTo(emblem, "<div><span>Hello, How are you? Excellent.</span></div>");
|
|
});
|
|
|
|
test("w/ mustaches", function() {
|
|
var emblem;
|
|
emblem = "div\n span Hello,\n {{foo}} are you?\n Excellent.";
|
|
return shouldCompileTo(emblem, {
|
|
foo: "YEAH"
|
|
}, "<div><span>Hello, YEAH are you? Excellent.</span></div>");
|
|
});
|
|
|
|
test("w/ block mustaches", function() {
|
|
var emblem;
|
|
emblem = 'p Hello, #{ sally | Hello},\n and {{sally: span Hello}}!';
|
|
shouldCompileTo(emblem, '<p>Hello, <sally class="none">Hello</sally>, and <sally class="none"><span>Hello</span></sally>!</p>');
|
|
emblem = 'p Hello, #{ sally: span: a Hello}!';
|
|
return shouldCompileTo(emblem, '<p>Hello, <sally class="none"><span><a>Hello</a></span></sally>!</p>');
|
|
});
|
|
|
|
test("with followup", function() {
|
|
var emblem;
|
|
emblem = "p This is\n pretty cool.\np Hello.";
|
|
return shouldCompileTo(emblem, "<p>This is pretty cool.</p><p>Hello.</p>");
|
|
});
|
|
|
|
suite('#{} syntax');
|
|
|
|
test('acts like {{}}', function() {
|
|
var emblem;
|
|
emblem = 'span Yo #{foo}, I herd.';
|
|
return shouldCompileTo(emblem, {
|
|
foo: '<span>123</span>'
|
|
}, "<span>Yo <span>123</span>, I herd.</span>");
|
|
});
|
|
|
|
test('can start inline content', function() {
|
|
var emblem;
|
|
emblem = 'span #{foo}, I herd.';
|
|
return shouldCompileTo(emblem, {
|
|
foo: "dawg"
|
|
}, "<span>dawg, I herd.</span>");
|
|
});
|
|
|
|
test('can end inline content', function() {
|
|
var emblem;
|
|
emblem = 'span I herd #{foo}';
|
|
return shouldCompileTo(emblem, {
|
|
foo: "dawg"
|
|
}, "<span>I herd dawg</span>");
|
|
});
|
|
|
|
test("doesn't screw up parsing when # used in text nodes", function() {
|
|
var emblem;
|
|
emblem = 'span OMG #YOLO';
|
|
return shouldCompileTo(emblem, "<span>OMG #YOLO</span>");
|
|
});
|
|
|
|
test("# can be only thing on line", function() {
|
|
var emblem;
|
|
emblem = 'span #';
|
|
return shouldCompileTo(emblem, "<span>#</span>");
|
|
});
|
|
|
|
/* TODO: this
|
|
test "can be escaped", ->
|
|
emblem =
|
|
'''
|
|
span #\\{yes}
|
|
'''
|
|
shouldCompileTo emblem, '<span>#{yes}</span>'
|
|
*/
|
|
|
|
|
|
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 <span id="woot" data-t="oof" class="f">what</span>!', 'What <span id="woot" data-t="oof" class="f">what</span>!\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: "<span>NO</span>"
|
|
}, 'Bork YEAH <span>NO</span>!\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, '<pre>This\n\t should\n\t hopefully\n\t work, and work well.\n\t</pre>');
|
|
});
|
|
return test("with blank", function() {
|
|
var emblem;
|
|
emblem = "pre\n _ This\n _ should\n _\n _ hopefully\n _ work, and work well.";
|
|
return sct(emblem, '<pre>This\n\t should\n\t\n\t hopefully\n\t work, and work well.\n\t</pre>');
|
|
});
|
|
};
|
|
|
|
runTextLineSuite('|');
|
|
|
|
runTextLineSuite('`');
|
|
|
|
runTextLineSuite("'");
|
|
|
|
suite("text line starting with angle bracket");
|
|
|
|
test("can start with angle bracket html", function() {
|
|
var emblem;
|
|
emblem = "<span>Hello</span>";
|
|
return shouldCompileTo(emblem, "<span>Hello</span>");
|
|
});
|
|
|
|
test("can start with angle bracket html and go to multiple lines", function() {
|
|
var emblem;
|
|
emblem = "<span>Hello dude, \n what's up?</span>";
|
|
return shouldCompileTo(emblem, "<span>Hello dude, what's up?</span>");
|
|
});
|
|
|
|
suite("preprocessor");
|
|
|
|
test("it strips out preceding whitespace", function() {
|
|
var emblem;
|
|
emblem = "\np Hello";
|
|
return shouldCompileTo(emblem, "<p>Hello</p>");
|
|
});
|
|
|
|
test("it handles preceding indentation", function() {
|
|
var emblem;
|
|
emblem = " p Woot\n p Ha";
|
|
return shouldCompileTo(emblem, "<p>Woot</p><p>Ha</p>");
|
|
});
|
|
|
|
test("it handles preceding indentation and newlines", function() {
|
|
var emblem;
|
|
emblem = "\n p Woot\n p Ha";
|
|
return shouldCompileTo(emblem, "<p>Woot</p><p>Ha</p>");
|
|
});
|
|
|
|
test("it handles preceding indentation and newlines pt 2", function() {
|
|
var emblem;
|
|
emblem = " \n p Woot\n p Ha";
|
|
return shouldCompileTo(emblem, "<p>Woot</p><p>Ha</p>");
|
|
});
|
|
|
|
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, "<p>Hello</p><h1>How are you?</h1>");
|
|
});
|
|
|
|
test("it strips out multi-line '/' comments", function() {
|
|
var emblem;
|
|
emblem = "p Hello\n\n/ A comment\n that goes on to two lines\n even three!\n\nh1 How are you?";
|
|
return shouldCompileTo(emblem, "<p>Hello</p><h1>How are you?</h1>");
|
|
});
|
|
|
|
test("it strips out multi-line '/' comments without text on the first line", function() {
|
|
var emblem;
|
|
emblem = "p Hello\n\n/ \n A comment\n that goes on to two lines\n even three!\n\nh1 How are you?";
|
|
return shouldCompileTo(emblem, "<p>Hello</p><h1>How are you?</h1>");
|
|
});
|
|
|
|
test("mix and match with various indentation", function() {
|
|
var emblem;
|
|
emblem = "/ A test\np Hello\n\nspan\n / This is gnarly\n p Yessir nope.\n\n/ Nothin but comments\n so many comments.\n\n/\n p Should not show up";
|
|
return shouldCompileTo(emblem, "<p>Hello</p><span><p>Yessir nope.</p></span>");
|
|
});
|
|
|
|
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, '<div class="container"><div class="row"><p>Hello</p></div></div>');
|
|
});
|
|
|
|
test("on same line as mustache content", function() {
|
|
return shouldCompileTo('frank text="YES" text2="NO" / omg', 'WOO: YES NO');
|
|
});
|
|
|
|
test("on same line as colon syntax", function() {
|
|
var emblem;
|
|
emblem = "ul: li: span / omg\n | Hello";
|
|
return shouldCompileTo(emblem, '<ul><li><span>Hello</span></li></ul>');
|
|
});
|
|
|
|
suite("indentation");
|
|
|
|
test("it doesn't throw when indenting after a line with inline content", function() {
|
|
var emblem;
|
|
emblem = "p Hello\n p invalid";
|
|
return shouldCompileTo(emblem, "<p>Hello p invalid</p>");
|
|
});
|
|
|
|
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, "<p><span><div><span>yes</span></div></span></p>");
|
|
});
|
|
|
|
suite("whitespace fussiness");
|
|
|
|
test("spaces after html elements", function() {
|
|
shouldCompileTo("p \n span asd", "<p><span>asd</span></p>");
|
|
return shouldCompileTo("p \nspan \n\ndiv\nspan", "<p></p><span></span><div></div><span></span>");
|
|
});
|
|
|
|
test("spaces after mustaches", function() {
|
|
return shouldCompileTo("each foo \n p \n span", {
|
|
foo: [1, 2]
|
|
}, "<p></p><span></span><p></p><span></span>");
|
|
});
|
|
|
|
suite("attribute shorthand");
|
|
|
|
test("id shorthand", function() {
|
|
shouldCompileTo("#woot", '<div id="woot"></div>');
|
|
return shouldCompileTo("span#woot", '<span id="woot"></span>');
|
|
});
|
|
|
|
test("class shorthand", function() {
|
|
shouldCompileTo(".woot", '<div class="woot"></div>');
|
|
shouldCompileTo("span.woot", '<span class="woot"></span>');
|
|
return shouldCompileTo("span.woot.loot", '<span class="woot loot"></span>');
|
|
});
|
|
|
|
test("class can come first", function() {
|
|
shouldCompileTo(".woot#hello", '<div id="hello" class="woot"></div>');
|
|
shouldCompileTo("span.woot#hello", '<span id="hello" class="woot"></span>');
|
|
shouldCompileTo("span.woot.loot#hello", '<span id="hello" class="woot loot"></span>');
|
|
return shouldCompileTo("span.woot.loot#hello.boot", '<span id="hello" class="woot loot boot"></span>');
|
|
});
|
|
|
|
suite("full attributes - tags with content");
|
|
|
|
test("class only", function() {
|
|
return shouldCompileTo('p class="yes" Blork', '<p class="yes">Blork</p>');
|
|
});
|
|
|
|
test("id only", function() {
|
|
return shouldCompileTo('p id="yes" Hyeah', '<p id="yes">Hyeah</p>');
|
|
});
|
|
|
|
test("class and id", function() {
|
|
return shouldCompileTo('p id="yes" class="no" Blork', '<p id="yes" class="no">Blork</p>');
|
|
});
|
|
|
|
test("class and id and embedded html one-liner", function() {
|
|
return shouldCompileTo('p id="yes" class="no" One <b>asd</b>!', '<p id="yes" class="no">One <b>asd</b>!</p>');
|
|
});
|
|
|
|
test("bracketed attributes", function() {
|
|
var emblem;
|
|
emblem = "p [\n id=\"yes\"\n class=\"no\" ]\n | Bracketed Attributes FTW!";
|
|
return shouldCompileTo(emblem, '<p id="yes" class="no">Bracketed Attributes FTW!</p>');
|
|
});
|
|
|
|
test("bracketed text", function() {
|
|
var emblem;
|
|
emblem = "p [ Bracketed text is cool ]";
|
|
return shouldCompileTo(emblem, '<p>[ Bracketed text is cool ]</p>');
|
|
});
|
|
|
|
test("bracketed text indented", function() {
|
|
var emblem;
|
|
emblem = "p\n | [ Bracketed text is cool ]";
|
|
return shouldCompileTo(emblem, '<p>[ Bracketed text is cool ]</p>');
|
|
});
|
|
|
|
test("nesting", function() {
|
|
var emblem;
|
|
emblem = "p class=\"hello\" data-foo=\"gnarly\"\n span Yes";
|
|
return shouldCompileTo(emblem, '<p class="hello" data-foo="gnarly"><span>Yes</span></p>');
|
|
});
|
|
|
|
suite("full attributes - mixed quotes");
|
|
|
|
test("single empty", function() {
|
|
return shouldCompileTo("p class=''", '<p class=""></p>');
|
|
});
|
|
|
|
test("single full", function() {
|
|
return shouldCompileTo("p class='woot yeah'", '<p class="woot yeah"></p>');
|
|
});
|
|
|
|
test("mixed", function() {
|
|
return shouldCompileTo("p class='woot \"oof\" yeah'", '<p class="woot "oof" yeah"></p>');
|
|
});
|
|
|
|
suite("full attributes - tags without content");
|
|
|
|
test("empty", function() {
|
|
return shouldCompileTo('p class=""', '<p class=""></p>');
|
|
});
|
|
|
|
test("class only", function() {
|
|
return shouldCompileTo('p class="yes"', '<p class="yes"></p>');
|
|
});
|
|
|
|
test("id only", function() {
|
|
return shouldCompileTo('p id="yes"', '<p id="yes"></p>');
|
|
});
|
|
|
|
test("class and id", function() {
|
|
return shouldCompileTo('p id="yes" class="no"', '<p id="yes" class="no"></p>');
|
|
});
|
|
|
|
suite("full attributes w/ mustaches");
|
|
|
|
test("with mustache", function() {
|
|
var emblem;
|
|
shouldCompileTo('p class="foo {{yes}}"', {
|
|
yes: "ALEX"
|
|
}, '<p class="foo ALEX"></p>');
|
|
shouldCompileTo('p class="foo {{yes}}" Hello', {
|
|
yes: "ALEX"
|
|
}, '<p class="foo ALEX">Hello</p>');
|
|
emblem = "p class=\"foo {{yes}}\"\n | Hello";
|
|
return shouldCompileTo(emblem, {
|
|
yes: "ALEX"
|
|
}, '<p class="foo ALEX">Hello</p>');
|
|
});
|
|
|
|
test("with mustache calling helper", function() {
|
|
var emblem;
|
|
shouldCompileTo('p class="foo {{{echo "YES"}}}"', '<p class="foo ECHO YES"></p>');
|
|
shouldCompileTo('p class="foo #{echo "NO"} and {{{echo "YES"}}}" Hello', '<p class="foo ECHO NO and ECHO YES">Hello</p>');
|
|
emblem = "p class=\"foo {{echo \"BORF\"}}\"\n | Hello";
|
|
return shouldCompileTo(emblem, '<p class="foo ECHO BORF">Hello</p>');
|
|
});
|
|
|
|
suite("boolean attributes");
|
|
|
|
test("static", function() {
|
|
shouldCompileTo('p borf=true', '<p borf></p>');
|
|
shouldCompileTo('p borf=true Woot', '<p borf>Woot</p>');
|
|
shouldCompileTo('p borf=false', '<p></p>');
|
|
shouldCompileTo('p borf=false Nork', '<p>Nork</p>');
|
|
return shouldCompileTo('option selected=true Thingeroo', '<option selected>Thingeroo</option>');
|
|
});
|
|
|
|
suite("html nested");
|
|
|
|
test("basic", function() {
|
|
var emblem;
|
|
emblem = "p\n span Hello\n strong Hi\ndiv\n p Hooray";
|
|
return shouldCompileTo(emblem, '<p><span>Hello</span><strong>Hi</strong></p><div><p>Hooray</p></div>');
|
|
});
|
|
|
|
test("empty nest", function() {
|
|
var emblem;
|
|
emblem = "p\n span\n strong\n i";
|
|
return shouldCompileTo(emblem, '<p><span><strong><i></i></strong></span></p>');
|
|
});
|
|
|
|
test("empty nest w/ attribute shorthand", function() {
|
|
var emblem;
|
|
emblem = "p.woo\n span#yes\n strong.no.yes\n i";
|
|
return shouldCompileTo(emblem, '<p class="woo"><span id="yes"><strong class="no yes"><i></i></strong></span></p>');
|
|
});
|
|
|
|
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<p>ASD</p><span class="foo"></span><p data-foo="yes">WER</p>');
|
|
});
|
|
|
|
test("double =='s un-escape", function() {
|
|
var emblem;
|
|
emblem = "== foo\nfoo\np == foo";
|
|
return shouldCompileTo(emblem, {
|
|
foo: '<span>123</span>'
|
|
}, '<span>123</span><span>123</span><p><span>123</span></p>');
|
|
});
|
|
|
|
test("nested combo syntax", function() {
|
|
var emblem;
|
|
emblem = "ul = each items\n li = foo";
|
|
return shouldCompileTo(emblem, {
|
|
items: [
|
|
{
|
|
foo: "YEAH"
|
|
}, {
|
|
foo: "BOI"
|
|
}
|
|
]
|
|
}, '<ul><li>YEAH</li><li>BOI</li></ul>');
|
|
});
|
|
|
|
suite("mustache helpers");
|
|
|
|
Handlebars.registerHelper('booltest', function(options) {
|
|
var hash, result;
|
|
hash = options.hash;
|
|
result = hash.what === true ? "true" : hash.what === false ? "false" : "neither";
|
|
return result;
|
|
});
|
|
|
|
Handlebars.registerHelper('hashtypetest', function(options) {
|
|
var hash;
|
|
hash = options.hash;
|
|
return typeof hash.what;
|
|
});
|
|
|
|
Handlebars.registerHelper('typetest', function(num, options) {
|
|
return typeof num;
|
|
});
|
|
|
|
Handlebars.registerHelper('frank', function() {
|
|
var options;
|
|
options = arguments[arguments.length - 1];
|
|
return "WOO: " + options.hash.text + " " + options.hash.text2;
|
|
});
|
|
|
|
Handlebars.registerHelper('sally', function() {
|
|
var content, options, param, params;
|
|
options = arguments[arguments.length - 1];
|
|
params = Array.prototype.slice.call(arguments, 0, -1);
|
|
param = params[0] || 'none';
|
|
if (options.fn) {
|
|
content = options.fn(this);
|
|
return new Handlebars.SafeString("<sally class=\"" + param + "\">" + content + "</sally>");
|
|
} else {
|
|
content = param;
|
|
return new Handlebars.SafeString("<sally class=\"" + param + "\">" + content + "</sally>");
|
|
}
|
|
});
|
|
|
|
test("basic", function() {
|
|
return shouldCompileTo('echo foo', {
|
|
foo: "YES"
|
|
}, 'ECHO YES');
|
|
});
|
|
|
|
test("hashed parameters should work", function() {
|
|
return shouldCompileTo('frank text="YES" text2="NO"', 'WOO: YES NO');
|
|
});
|
|
|
|
Handlebars.registerHelper('concatenator', function() {
|
|
var key, options, value;
|
|
options = arguments[arguments.length - 1];
|
|
return new Handlebars.SafeString(((function() {
|
|
var _ref1, _results;
|
|
_ref1 = options.hash;
|
|
_results = [];
|
|
for (key in _ref1) {
|
|
value = _ref1[key];
|
|
_results.push("'" + key + "'='" + value + "'");
|
|
}
|
|
return _results;
|
|
})()).sort().join(" "));
|
|
});
|
|
|
|
test("negative integers should work", function() {
|
|
return shouldCompileTo('concatenator positive=100 negative=-100', "'negative'='-100' 'positive'='100'");
|
|
});
|
|
|
|
test("booleans", function() {
|
|
shouldCompileToString('typetest true', 'boolean');
|
|
shouldCompileToString('typetest false', 'boolean');
|
|
shouldCompileTo('booltest what=false', 'false');
|
|
shouldCompileTo('booltest what=true', 'true');
|
|
shouldCompileTo('booltest what="false"', 'neither');
|
|
return shouldCompileTo('booltest what="true"', 'neither');
|
|
});
|
|
|
|
test("integers", function() {
|
|
shouldCompileToString('typetest 200', 'number');
|
|
shouldCompileTo('hashtypetest what=1', 'number');
|
|
return shouldCompileTo('hashtypetest what=200', 'number');
|
|
});
|
|
|
|
test("nesting", function() {
|
|
var emblem;
|
|
emblem = "sally\n p Hello";
|
|
return shouldCompileTo(emblem, '<sally class="none"><p>Hello</p></sally>');
|
|
});
|
|
|
|
test("recursive nesting", function() {
|
|
var emblem;
|
|
emblem = "sally\n sally\n p Hello";
|
|
return shouldCompileTo(emblem, '<sally class="none"><sally class="none"><p>Hello</p></sally></sally>');
|
|
});
|
|
|
|
test("recursive nesting pt 2", function() {
|
|
var emblem;
|
|
emblem = "sally\n sally thing\n p Hello";
|
|
return shouldCompileTo(emblem, {
|
|
thing: "woot"
|
|
}, '<sally class="none"><sally class="woot"><p>Hello</p></sally></sally>');
|
|
});
|
|
|
|
test("bracketed nested statement", function() {
|
|
var emblem;
|
|
emblem = "sally [\n 'foo'\n something=\"false\" ]\n | Bracketed helper attrs!";
|
|
return shouldCompileTo(emblem, '<sally class="foo">Bracketed helper attrs!</sally>');
|
|
});
|
|
|
|
test("bracketed nested block", function() {
|
|
var emblem;
|
|
emblem = "sally [\n 'foo'\n something=\"false\" ]\n p Bracketed helper attrs!";
|
|
return shouldCompileTo(emblem, '<sally class="foo"><p>Bracketed helper attrs!</p></sally>');
|
|
});
|
|
|
|
Handlebars.registerHelper('view', function(param, a, b, c) {
|
|
var content, hashString, k, options, v, _ref1;
|
|
options = arguments[arguments.length - 1];
|
|
content = param;
|
|
if (options.fn) {
|
|
content = options.fn(this);
|
|
}
|
|
hashString = "";
|
|
_ref1 = options.hash;
|
|
for (k in _ref1) {
|
|
if (!__hasProp.call(_ref1, k)) continue;
|
|
v = _ref1[k];
|
|
hashString += " " + k + "=" + v;
|
|
}
|
|
if (!hashString) {
|
|
hashString = " nohash";
|
|
}
|
|
return new Handlebars.SafeString("<" + param + hashString + ">" + content + "</" + param + ">");
|
|
});
|
|
|
|
suite("capitalized line-starter");
|
|
|
|
test("should invoke `view` helper by default", function() {
|
|
var emblem;
|
|
emblem = "SomeView";
|
|
return shouldEmberPrecompileToHelper(emblem, 'view');
|
|
});
|
|
|
|
test("should not invoke `view` helper for vanilla HB", function() {
|
|
var emblem;
|
|
emblem = "SomeView";
|
|
return shouldCompileToString(emblem, {
|
|
SomeView: "ALEX"
|
|
}, 'ALEX');
|
|
});
|
|
|
|
test("should support block mode", function() {
|
|
var emblem;
|
|
emblem = "SomeView\n p View content";
|
|
return shouldEmberPrecompileToHelper(emblem, 'view');
|
|
});
|
|
|
|
test("should not kick in if preceded by equal sign", function() {
|
|
var emblem;
|
|
emblem = "= SomeView";
|
|
return shouldCompileTo(emblem, {
|
|
SomeView: 'erp'
|
|
}, 'erp');
|
|
});
|
|
|
|
test("should not kick in explicit {{mustache}}", function() {
|
|
var emblem;
|
|
emblem = "p Yeah {{SomeView}}";
|
|
return shouldCompileTo(emblem, {
|
|
SomeView: 'erp'
|
|
}, '<p>Yeah erp</p>');
|
|
});
|
|
|
|
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("<unbound class=\"" + stringedParams + "\">" + content + "</unbound>");
|
|
});
|
|
|
|
test("bang helper defaults to `unbound` invocation", function() {
|
|
var emblem;
|
|
emblem = "foo! Yar\n= foo!";
|
|
return shouldCompileToString(emblem, '<unbound class="foo Yar">foo Yar</unbound><unbound class="foo">foo</unbound>');
|
|
});
|
|
|
|
test("bang helper works with blocks", function() {
|
|
var emblem;
|
|
emblem = "hey! you suck\n = foo!";
|
|
return shouldCompileToString(emblem, '<unbound class="hey you suck"><unbound class="foo">foo</unbound></unbound>');
|
|
});
|
|
|
|
suite("question mark syntax defaults to `if` helper syntax");
|
|
|
|
test("? helper defaults to `if` invocation", function() {
|
|
var emblem;
|
|
emblem = "foo?\n p Yeah";
|
|
return shouldCompileTo(emblem, {
|
|
foo: true
|
|
}, '<p>Yeah</p>');
|
|
});
|
|
|
|
test("else works", function() {
|
|
var emblem;
|
|
emblem = "foo?\n p Yeah\nelse\n p No";
|
|
return shouldCompileTo(emblem, {
|
|
foo: false
|
|
}, '<p>No</p>');
|
|
});
|
|
|
|
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
|
|
}, '<p>Hooray</p><p>No</p>');
|
|
});
|
|
|
|
test("compound", function() {
|
|
var emblem;
|
|
emblem = "p = foo? \n bar\nelse\n baz";
|
|
return shouldCompileTo(emblem, {
|
|
foo: true,
|
|
bar: "borf",
|
|
baz: "narsty"
|
|
}, '<p>borf</p>');
|
|
});
|
|
|
|
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
|
|
}, '<p>Yeah</p><p>No!</p><p>No!</p>');
|
|
});
|
|
|
|
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, {}, '<p>not nothing</p>');
|
|
});
|
|
|
|
suite("class shorthand and explicit declaration is coalesced");
|
|
|
|
test("when literal class is used", function() {
|
|
return shouldCompileTo('p.foo class="bar"', '<p class="foo bar"></p>');
|
|
});
|
|
|
|
test("when ember expression is used with variable", function() {
|
|
return shouldCompileTo('p.foo class=bar', {
|
|
bar: 'baz'
|
|
}, '<p bind-attr class to :foo bar></p>');
|
|
});
|
|
|
|
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"
|
|
}, '<p class="YEAH"></p>');
|
|
return shouldEmberPrecompileToHelper(emblem);
|
|
});
|
|
|
|
test("basic w/ underscore", function() {
|
|
var emblem;
|
|
emblem = 'p class=foo_urns';
|
|
shouldCompileTo(emblem, {
|
|
foo_urns: "YEAH"
|
|
}, '<p class="YEAH"></p>');
|
|
return shouldEmberPrecompileToHelper(emblem);
|
|
});
|
|
|
|
test("subproperties", function() {
|
|
var emblem;
|
|
emblem = 'p class=foo._death.woot';
|
|
shouldCompileTo(emblem, {
|
|
foo: {
|
|
_death: {
|
|
woot: "YEAH"
|
|
}
|
|
}
|
|
}, '<p class="YEAH"></p>');
|
|
return shouldEmberPrecompileToHelper(emblem);
|
|
});
|
|
|
|
test("multiple", function() {
|
|
return shouldCompileTo('p class=foo id="yup" data-thinger=yeah Hooray', {
|
|
foo: "FOO",
|
|
yeah: "YEAH"
|
|
}, '<p class="FOO" id="yup" data-thinger="YEAH">Hooray</p>');
|
|
});
|
|
|
|
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"
|
|
}, '<p class="YEAH"></p>');
|
|
});
|
|
|
|
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"
|
|
}, '<p ALEX></p>');
|
|
});
|
|
|
|
test("double", function() {
|
|
return shouldCompileTo('p{inTagHelper foo}', {
|
|
foo: "ALEX"
|
|
}, '<p ALEX></p>');
|
|
});
|
|
|
|
test("triple", function() {
|
|
return shouldCompileTo('p{inTagHelper foo}', {
|
|
foo: "ALEX"
|
|
}, '<p ALEX></p>');
|
|
});
|
|
|
|
Handlebars.registerHelper('insertClass', function(p) {
|
|
return 'class="' + p + '"';
|
|
});
|
|
|
|
test("with singlestache", function() {
|
|
return shouldCompileTo('p{insertClass foo} Hello', {
|
|
foo: "yar"
|
|
}, '<p class="yar">Hello</p>');
|
|
});
|
|
|
|
test("singlestache can be used in text nodes", function() {
|
|
return shouldCompileTo('p Hello {dork}', '<p>Hello {dork}</p>');
|
|
});
|
|
|
|
test("with doublestache", function() {
|
|
return shouldCompileTo('p{{insertClass foo}} Hello', {
|
|
foo: "yar"
|
|
}, '<p class="yar">Hello</p>');
|
|
});
|
|
|
|
test("with triplestache", function() {
|
|
return shouldCompileTo('p{{{insertClass foo}}} Hello', {
|
|
foo: "yar"
|
|
}, '<p class="yar">Hello</p>');
|
|
});
|
|
|
|
test("multiple", function() {
|
|
return shouldCompileTo('p{{{insertClass foo}}}{{{insertClass boo}}} Hello', {
|
|
foo: "yar",
|
|
boo: "nar"
|
|
}, '<p class="yar" class="nar">Hello</p>');
|
|
});
|
|
|
|
test("with nesting", function() {
|
|
var emblem;
|
|
emblem = "p{{bind-attr class=\"foo\"}}\n span Hello";
|
|
return shouldCompileTo(emblem, {
|
|
foo: "yar"
|
|
}, '<p bind-attr class to foo><span>Hello</span></p>');
|
|
});
|
|
|
|
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, '<button action submitComment on=click>Submit Comment</button>');
|
|
});
|
|
|
|
test("basic (click) followed by attr", function() {
|
|
var emblem;
|
|
emblem = "button click=\"submitComment\" class=\"foo\" Submit Comment";
|
|
shouldCompileToString(emblem, '<button action submitComment on=click class="foo">Submit Comment</button>');
|
|
emblem = "button click=\"submitComment 'omg'\" class=\"foo\" Submit Comment";
|
|
return shouldCompileToString(emblem, '<button action submitComment|omg on=click class="foo">Submit Comment</button>');
|
|
});
|
|
|
|
test("nested (mouseEnter)", function() {
|
|
var emblem;
|
|
emblem = "a mouseEnter='submitComment target=\"view\"'\n | Submit Comment";
|
|
return shouldCompileToString(emblem, '<a action submitComment target=view on=mouseEnter>Submit Comment</a>');
|
|
});
|
|
|
|
test("nested (mouseEnter, doublequoted)", function() {
|
|
var emblem;
|
|
emblem = "a mouseEnter=\"submitComment target='view'\"\n | Submit Comment";
|
|
return shouldCompileToString(emblem, '<a action submitComment target=view on=mouseEnter>Submit Comment</a>');
|
|
});
|
|
|
|
test("manual", function() {
|
|
var emblem;
|
|
emblem = "a{action submitComment target=\"view\"} Submit Comment";
|
|
return shouldCompileToString(emblem, '<a action submitComment target=view>Submit Comment</a>');
|
|
});
|
|
|
|
test("manual nested", function() {
|
|
var emblem;
|
|
emblem = "a{action submitComment target=\"view\"}\n p Submit Comment";
|
|
return shouldCompileToString(emblem, '<a action submitComment target=view><p>Submit Comment</p></a>');
|
|
});
|
|
|
|
suite("haml style");
|
|
|
|
test("basic", function() {
|
|
var emblem;
|
|
emblem = "%borf";
|
|
return shouldCompileToString(emblem, '<borf></borf>');
|
|
});
|
|
|
|
test("nested", function() {
|
|
var emblem;
|
|
emblem = "%borf\n %sporf Hello";
|
|
return shouldCompileToString(emblem, '<borf><sporf>Hello</sporf></borf>');
|
|
});
|
|
|
|
test("capitalized", function() {
|
|
var emblem;
|
|
emblem = "%Alex alex\n%Alex\n %Woot";
|
|
return shouldCompileToString(emblem, '<Alex>alex</Alex><Alex><Woot></Woot></Alex>');
|
|
});
|
|
|
|
test("funky chars", function() {
|
|
var emblem;
|
|
emblem = "%borf:narf\n%borf:narf Hello, {{foo}}.\n%alex = foo";
|
|
return shouldCompileToString(emblem, {
|
|
foo: "Alex"
|
|
}, '<borf:narf></borf:narf><borf:narf>Hello, Alex.</borf:narf><alex>Alex</alex>');
|
|
});
|
|
|
|
suite("line-based errors");
|
|
|
|
test("line number is provided for pegjs error", function() {
|
|
var emblem;
|
|
emblem = "p Hello\np Hello {{narf}";
|
|
return shouldThrow((function() {
|
|
return CompilerContext.compile(emblem);
|
|
}), "line 2");
|
|
});
|
|
|
|
test("single quote test", function() {
|
|
var emblem;
|
|
emblem = "button click='p' Frank\n \n/ form s='d target=\"App\"'\n label I'm a label!";
|
|
return shouldCompileToString(emblem, '<button action p on=click>Frank</button>');
|
|
});
|
|
|
|
test("double quote test", function() {
|
|
var emblem;
|
|
emblem = "button click=\"p\" Frank\n \n/ form s='d target=\"App\"'\n label I'm a label!";
|
|
return shouldCompileToString(emblem, '<button action p on=click>Frank</button>');
|
|
});
|
|
|
|
test("no quote test", function() {
|
|
var emblem;
|
|
emblem = "button click=p Frank\n \n/ form s='d target=\"App\"'\n label I'm a label!";
|
|
return shouldCompileToString(emblem, '<button action p on=click>Frank</button>');
|
|
});
|
|
|
|
suite("mustache DOM attribute shorthand");
|
|
|
|
test("tagName w/o space", function() {
|
|
var emblem, result;
|
|
emblem = "App.FunView%span";
|
|
result = precompileEmber(emblem);
|
|
ok(result.match(/helpers\.view/));
|
|
ok(result.match(/App\.FunView/));
|
|
return ok(result.match(/tagName.*span/));
|
|
});
|
|
|
|
test("tagName w/ space", function() {
|
|
var emblem, result;
|
|
emblem = "App.FunView %span";
|
|
result = precompileEmber(emblem);
|
|
ok(result.match(/helpers\.view/));
|
|
ok(result.match(/App\.FunView/));
|
|
return ok(result.match(/tagName.*span/));
|
|
});
|
|
|
|
test("tagName block", function() {
|
|
var emblem;
|
|
emblem = "view App.FunView%span\n p Hello";
|
|
return shouldCompileToString(emblem, '<App.FunView tagName=span><p>Hello</p></App.FunView>');
|
|
});
|
|
|
|
test("class w/ space (needs space)", function() {
|
|
var emblem, result;
|
|
emblem = "App.FunView .bork";
|
|
result = precompileEmber(emblem);
|
|
ok(result.match(/helpers\.view/));
|
|
ok(result.match(/App\.FunView/));
|
|
return ok(result.match(/class.*bork/));
|
|
});
|
|
|
|
test("multiple classes", function() {
|
|
var emblem, result;
|
|
emblem = "App.FunView .bork.snork";
|
|
result = precompileEmber(emblem);
|
|
ok(result.match(/helpers\.view/));
|
|
ok(result.match(/App\.FunView/));
|
|
return ok(result.match(/class.*bork.*snork/));
|
|
});
|
|
|
|
test("elementId", function() {
|
|
var emblem, result;
|
|
emblem = "App.FunView#ohno";
|
|
result = precompileEmber(emblem);
|
|
ok(result.match(/helpers\.view/));
|
|
ok(result.match(/App\.FunView/));
|
|
return ok(result.match(/elementId.*ohno/));
|
|
});
|
|
|
|
test("mixed w/ hash`", function() {
|
|
var emblem, result;
|
|
emblem = "App.FunView .bork.snork funbags=\"yeah\"";
|
|
result = precompileEmber(emblem);
|
|
ok(result.match(/helpers\.view/));
|
|
ok(result.match(/App\.FunView/));
|
|
ok(result.match(/class.*bork.*snork/));
|
|
ok(result.match(/hash/));
|
|
ok(result.match(/funbags/));
|
|
return ok(result.match(/yeah/));
|
|
});
|
|
|
|
test("mixture of all`", function() {
|
|
var emblem, result;
|
|
emblem = "App.FunView%alex#hell.bork.snork funbags=\"yeah\"";
|
|
result = precompileEmber(emblem);
|
|
ok(result.match(/helpers\.view/));
|
|
ok(result.match(/App\.FunView/));
|
|
ok(result.match(/tagName.*alex/));
|
|
ok(result.match(/elementId.*hell/));
|
|
ok(result.match(/class.*bork.*snork/));
|
|
ok(result.match(/hash/));
|
|
ok(result.match(/funbags/));
|
|
return ok(result.match(/yeah/));
|
|
});
|
|
|
|
suite("self-closing html tags");
|
|
|
|
test("br", function() {
|
|
var emblem;
|
|
emblem = "br";
|
|
return shouldCompileToString(emblem, '<br />');
|
|
});
|
|
|
|
test("br paragraph example", function() {
|
|
var emblem;
|
|
emblem = "p\n | LOL!\n br\n | BORF!";
|
|
return shouldCompileToString(emblem, '<p>LOL!<br />BORF!</p>');
|
|
});
|
|
|
|
test("input", function() {
|
|
var emblem;
|
|
emblem = "input type=\"text\"";
|
|
return shouldCompileToString(emblem, '<input type="text" />');
|
|
});
|
|
|
|
suite("ember.");
|
|
|
|
test("should precompile with EmberHandlebars", function() {
|
|
var emblem, result;
|
|
emblem = "input type=\"text\"";
|
|
result = Emblem.precompile(EmberHandlebars, 'p Hello').toString();
|
|
return ok(result.match('<p>Hello</p>'));
|
|
});
|
|
|
|
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', '<a href="/people/{{id}}">{{name}}</a>');
|
|
|
|
test("calling handlebars partial", function() {
|
|
var emblem;
|
|
emblem = '> hbPartial\n| Hello #{> hbPartial}';
|
|
return shouldCompileToString(emblem, {
|
|
id: 666,
|
|
name: "Death"
|
|
}, '<a href="/people/666">Death</a>Hello <a href="/people/666">Death</a>');
|
|
});
|
|
|
|
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"
|
|
}, '<a href="/people/666">Death</a>');
|
|
});
|
|
|
|
test("calling emblem partial with context", function() {
|
|
return shouldCompileToString('> emblemPartialC foo', {
|
|
foo: {
|
|
a: "YES"
|
|
}
|
|
}, '<p>YES</p>');
|
|
});
|
|
|
|
test("partials in mustaches", function() {
|
|
var emblem;
|
|
emblem = "| Hello, {{> emblemPartialC foo}}{{>emblemPartialB}}{{>emblemPartialB }}";
|
|
return shouldCompileToString(emblem, {
|
|
foo: {
|
|
a: "YES"
|
|
}
|
|
}, 'Hello, <p>YES</p><p>Grr</p><p>Grr</p>');
|
|
});
|
|
|
|
test("handlebars dot-separated paths with segment-literal notation", function() {
|
|
var emblem;
|
|
emblem = 'p = articles.[3]';
|
|
return shouldCompileTo(emblem, {
|
|
articles: ['zero', 'one', 'two', 'three']
|
|
}, '<p>three</p>');
|
|
});
|
|
|
|
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']
|
|
}
|
|
]
|
|
}, '<p>bazinga</p>');
|
|
});
|
|
|
|
test("../path as inMustacheParam recognized correctly as pathIdNode instead of classShorthand", function() {
|
|
var emblem;
|
|
Handlebars.registerHelper('jumpToParent', function(link) {
|
|
return new Handlebars.SafeString("<a href='" + link + "'>Jump to parent top</a>");
|
|
});
|
|
emblem = 'each children\n jumpToParent ../parentLink';
|
|
return shouldCompileTo(emblem, {
|
|
parentLink: '#anchor',
|
|
children: [{}]
|
|
}, '<a href=\'#anchor\'>Jump to parent top</a>');
|
|
});
|
|
|
|
test("block as #each", function() {
|
|
var emblem;
|
|
emblem = 'thangs\n p Woot #{yeah}';
|
|
return shouldCompileToString(emblem, {
|
|
thangs: [
|
|
{
|
|
yeah: 123
|
|
}, {
|
|
yeah: 456
|
|
}
|
|
]
|
|
}, '<p>Woot 123</p><p>Woot 456</p>');
|
|
});
|
|
|
|
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
|
|
}
|
|
]
|
|
}, '<p>0 Woot 123</p><p>1 Woot 456</p>');
|
|
});
|
|
test("#each with @key", function() {
|
|
var emblem;
|
|
emblem = 'each thangs\n p #{@key}: #{this}';
|
|
return shouldCompileTo(emblem, {
|
|
thangs: {
|
|
'@key': 123,
|
|
'works!': 456
|
|
}
|
|
}, '<p>@key: 123</p><p>works!: 456</p>');
|
|
});
|
|
test("#each with @key, @index", function() {
|
|
var emblem;
|
|
emblem = 'each thangs\n p #{@index} #{@key}: #{this}';
|
|
return shouldCompileTo(emblem, {
|
|
thangs: {
|
|
'@key': 123,
|
|
'works!': 456
|
|
}
|
|
}, '<p>0 @key: 123</p><p>1 works!: 456</p>');
|
|
});
|
|
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
|
|
}
|
|
}, '<p>First item</p><p>works!: 456</p>');
|
|
});
|
|
}
|
|
|
|
/*
|
|
test "partial in block", ->
|
|
emblem =
|
|
"""
|
|
ul = people
|
|
> link
|
|
"""
|
|
data =
|
|
people: [
|
|
{ "name": "Alan", "id": 1 }
|
|
{ "name": "Yehuda", "id": 2 }
|
|
]
|
|
shouldCompileToString emblem, data, '<ul><a href="/people/1">Alan</a><a href="/people/2">Yehuda</a><ul>'
|
|
*/
|
|
|
|
|
|
suite("inline block helper");
|
|
|
|
test("text only", function() {
|
|
var emblem;
|
|
emblem = "view SomeView | Hello";
|
|
return shouldCompileToString(emblem, '<SomeView nohash>Hello</SomeView>');
|
|
});
|
|
|
|
test("multiline", function() {
|
|
var emblem;
|
|
emblem = "view SomeView | Hello, \n How are you? \n Sup?";
|
|
return shouldCompileToString(emblem, '<SomeView nohash>Hello, How are you? Sup?</SomeView>');
|
|
});
|
|
|
|
test("more complicated", function() {
|
|
var emblem;
|
|
emblem = "view SomeView borf=\"yes\" | Hello, \n How are you? \n Sup?";
|
|
return shouldCompileToString(emblem, '<SomeView borf=yes>Hello, How are you? Sup?</SomeView>');
|
|
});
|
|
|
|
suite("copy paste html");
|
|
|
|
test("indented", function() {
|
|
var emblem;
|
|
emblem = "<p>\n <span>This be some text</span>\n <title>Basic HTML Sample Page</title>\n</p>";
|
|
return shouldCompileToString(emblem, '<p><span>This be some text</span><title>Basic HTML Sample Page</title></p>');
|
|
});
|
|
|
|
test("flatlina", function() {
|
|
var emblem;
|
|
emblem = "<p>\n<span>This be some text</span>\n<title>Basic HTML Sample Page</title>\n</p>";
|
|
return shouldCompileToString(emblem, '<p><span>This be some text</span><title>Basic HTML Sample Page</title></p>');
|
|
});
|
|
|
|
test("bigass", function() {
|
|
var emblem, expected;
|
|
expect(0);
|
|
return "PENDING";
|
|
emblem = "<div class=\"content\">\n <p>\n We design and develop ambitious web and mobile applications, \n </p>\n <p>\n A more official portfolio page is on its way, but in the meantime, \n check out\n </p>\n</div>";
|
|
expected = '<div class="content"><p> We design and develop ambitious web and mobile applications, </p><p> A more official portfolio page is on its way, but in the meantime, check out</p></div>';
|
|
return shouldCompileToString(emblem, expected);
|
|
});
|
|
|
|
suite("`this` keyword");
|
|
|
|
test("basic", function() {
|
|
var emblem;
|
|
emblem = 'each foo\n p = this\n this';
|
|
return shouldCompileTo(emblem, {
|
|
foo: ["Alex", "Emily"]
|
|
}, '<p>Alex</p>Alex<p>Emily</p>Emily');
|
|
});
|
|
|
|
suite("colon separator");
|
|
|
|
test("basic", function() {
|
|
var emblem;
|
|
emblem = 'each foo: p Hello, #{this}';
|
|
return shouldCompileTo(emblem, {
|
|
foo: ["Alex", "Emily", "Nicole"]
|
|
}, '<p>Hello, Alex</p><p>Hello, Emily</p><p>Hello, Nicole</p>');
|
|
});
|
|
|
|
test("html stack", function() {
|
|
var emblem;
|
|
emblem = '.container: .row: .span5: span Hello';
|
|
return shouldCompileToString(emblem, '<div class="container"><div class="row"><div class="span5"><span>Hello</span></div></div></div>');
|
|
});
|
|
|
|
test("epic", function() {
|
|
var emblem;
|
|
emblem = '.container: .row: .span5\n ul#list data-foo="yes": each foo: li\n span: this';
|
|
return shouldCompileTo(emblem, {
|
|
foo: ["a", "b"]
|
|
}, '<div class="container"><div class="row"><div class="span5"><ul id="list" data-foo="yes"><li><span>a</span></li><li><span>b</span></li></ul></div></div></div>');
|
|
});
|
|
|
|
test("html stack elements only", function() {
|
|
var emblem;
|
|
emblem = 'p: span: div: p: foo';
|
|
return shouldCompileToString(emblem, {
|
|
foo: "alex"
|
|
}, '<p><span><div><p>alex</p></div></span></p>');
|
|
});
|
|
|
|
test("mixed separators", function() {
|
|
var emblem;
|
|
emblem = '.fun = each foo: %nork = this';
|
|
return shouldCompileTo(emblem, {
|
|
foo: ["Alex", "Emily", "Nicole"]
|
|
}, '<div class="fun"><nork>Alex</nork><nork>Emily</nork><nork>Nicole</nork></div>');
|
|
});
|
|
|
|
test("mixed separators rewritten", function() {
|
|
var emblem;
|
|
emblem = '.fun: each foo: %nork: this';
|
|
return shouldCompileTo(emblem, {
|
|
foo: ["Alex", "Emily", "Nicole"]
|
|
}, '<div class="fun"><nork>Alex</nork><nork>Emily</nork><nork>Nicole</nork></div>');
|
|
});
|
|
|
|
test("with text terminator", function() {
|
|
var emblem;
|
|
emblem = '.fun: view SomeView | Hello';
|
|
return shouldCompileToString(emblem, '<div class="fun"><SomeView nohash>Hello</SomeView></div>');
|
|
});
|
|
|
|
test("test from heartsentwined", function() {
|
|
shouldCompileTo('li data-foo=bar: a', {
|
|
bar: "abc"
|
|
}, '<li data-foo="abc"><a></a></li>');
|
|
return shouldCompileTo("li data-foo='bar': a", '<li data-foo="bar"><a></a></li>');
|
|
});
|
|
|
|
test("mixture of colon and indentation", function() {
|
|
var emblem;
|
|
emblem = "li data-foo=bar: a\n baz";
|
|
return shouldCompileTo(emblem, {
|
|
bar: "abc",
|
|
baz: "Hello"
|
|
}, '<li data-foo="abc"><a>Hello</a></li>');
|
|
});
|
|
|
|
test("mixture of colon and indentation pt.2", function() {
|
|
var emblem, result;
|
|
emblem = "ul\n li data-foo=bar: a quux\n li data-foo='bar': a quux\n li data-foo=bar href='#': a quux";
|
|
result = precompileEmber(emblem);
|
|
return ok(!result.match("a quux"));
|
|
});
|
|
|
|
suite("base indent / predent");
|
|
|
|
test("predent", function() {
|
|
var emblem, s;
|
|
emblem = " \n";
|
|
s = "pre\n ` This\n ` should\n ` hopefully\n ` work, and work well.\n";
|
|
emblem += s;
|
|
return shouldCompileToString(emblem, '<pre>This\n should\n hopefully\n work, and work well.\n</pre>');
|
|
});
|
|
|
|
test("mixture", function() {
|
|
var emblem;
|
|
emblem = " \n";
|
|
emblem += " p Hello\n";
|
|
emblem += " p\n";
|
|
emblem += " | Woot\n";
|
|
emblem += " span yes\n";
|
|
return shouldCompileToString(emblem, '<p>Hello</p><p>Woot</p><span>yes</span>');
|
|
});
|
|
|
|
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, '<p>Hello</p><p>Woot</p><span>yes</span>');
|
|
});
|
|
|
|
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, '<p>Hello</p><p>Woot</p><span>yes</span>');
|
|
});
|
|
|
|
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, '<p>Hello</p><p>Woot</p><span>yes</span><sally class="none">Woot</sally>');
|
|
});
|
|
|
|
suite("EOL Whitespace");
|
|
|
|
test("shouldn't be necessary to insert a space", function() {
|
|
var emblem;
|
|
emblem = "p Hello,\n How are you?\np I'm fine, thank you.";
|
|
return shouldCompileToString(emblem, "<p>Hello, How are you?</p><p>I'm fine, thank you.</p>");
|
|
});
|
|
|
|
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, '<div><p><span>Buttsem fpokasdiunw paosdk</span></p></div>');
|
|
});
|
|
|
|
test("capitalized view helper should not kick in if suffix modifiers present", function() {
|
|
var emblem;
|
|
emblem = "Foo!";
|
|
return shouldCompileToString(emblem, '<unbound class="Foo">Foo</unbound>');
|
|
});
|
|
|
|
test("GH-26: no need for space before equal sign", function() {
|
|
var emblem;
|
|
emblem = "span= foo";
|
|
shouldCompileToString(emblem, {
|
|
foo: "YEAH"
|
|
}, '<span>YEAH</span>');
|
|
emblem = "span.foo= foo";
|
|
shouldCompileToString(emblem, {
|
|
foo: "YEAH"
|
|
}, '<span class="foo">YEAH</span>');
|
|
emblem = "span#hooray.foo= foo";
|
|
shouldCompileToString(emblem, {
|
|
foo: "YEAH"
|
|
}, '<span id="hooray" class="foo">YEAH</span>');
|
|
emblem = "#hooray= foo";
|
|
shouldCompileToString(emblem, {
|
|
foo: "YEAH"
|
|
}, '<div id="hooray">YEAH</div>');
|
|
emblem = ".hooray= foo";
|
|
return shouldCompileToString(emblem, {
|
|
foo: "YEAH"
|
|
}, '<div class="hooray">YEAH</div>');
|
|
});
|
|
|
|
test("numbers in shorthand", function() {
|
|
shouldCompileToString('#4a', '<div id="4a"></div>');
|
|
shouldCompileToString('.4a', '<div class="4a"></div>');
|
|
shouldCompileToString('.4', '<div class="4"></div>');
|
|
shouldCompileToString('#4', '<div id="4"></div>');
|
|
shouldCompileToString('%4', '<4></4>');
|
|
shouldCompileToString('%4 ermagerd', '<4>ermagerd</4>');
|
|
return shouldCompileToString('%4#4.4 ermagerd', '<4 id="4" class="4">ermagerd</4>');
|
|
});
|
|
|
|
test("Emblem has a VERSION defined", function() {
|
|
return ok(Emblem.VERSION, "Emblem.VERSION should be defined");
|
|
});
|
|
|
|
test("Windows line endings", function() {
|
|
var emblem;
|
|
emblem = ".navigation\r\n p Hello\r\n#main\r\n | hi";
|
|
return shouldCompileToString(emblem, '<div class="navigation"><p>Hello</p></div><div id="main">hi</div>');
|
|
});
|
|
|
|
test("backslash doesn't cause infinite loop", function() {
|
|
var emblem;
|
|
emblem = '| \\';
|
|
return shouldCompileTo(emblem, "\\");
|
|
});
|
|
|
|
test("backslash doesn't cause infinite loop with letter", function() {
|
|
var emblem;
|
|
emblem = '| \\a';
|
|
return shouldCompileTo(emblem, "\\a");
|
|
});
|
|
|
|
test("self closing tag with forward slash", function() {
|
|
var emblem;
|
|
emblem = 'p/\n%bork/\n.omg/\n#hello.boo/\np/ class="asdasd"';
|
|
return shouldCompileTo(emblem, '<p /><bork /><div class="omg" /><div id="hello" class="boo" /><p class="asdasd" />');
|
|
});
|
|
|
|
test("tagnames and attributes with colons", function() {
|
|
var emblem;
|
|
emblem = '%al:ex match:neer="snork" Hello!';
|
|
return shouldCompileTo(emblem, '<al:ex match:neer="snork">Hello!</al:ex>');
|
|
});
|
|
|
|
test("windows newlines", function() {
|
|
var emblem;
|
|
emblem = "\r\n \r\n p Hello\r\n\r\n";
|
|
return shouldCompileTo(emblem, '<p>Hello</p>');
|
|
});
|
|
|
|
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, '<p>ECHO hello</p>');
|
|
emblem = '= echo (hello)';
|
|
return shouldCompileTo(emblem, 'ECHO hello');
|
|
});
|
|
test("helper w args", function() {
|
|
var emblem;
|
|
emblem = 'p {{echo (equal 1 1)}}';
|
|
shouldCompileTo(emblem, '<p>ECHO true</p>');
|
|
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, '<p>ECHO true</p>');
|
|
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, '<p>ECHO true</p>');
|
|
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, '<p>FUN = true</p>');
|
|
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, '<p>FUN = true</p>');
|
|
emblem = '= echofun true (hello how="are" you=false) 1 not=true fun=(equal "ECHO hello" (echo (hello))) win="yes"';
|
|
return shouldCompileTo(emblem, 'FUN = true');
|
|
});
|
|
}
|