d4cfe90959
Fixes #472
277 lines
8.8 KiB
JavaScript
277 lines
8.8 KiB
JavaScript
/*global Handlebars, handlebarsEnv, shouldThrow */
|
|
describe('ast', function() {
|
|
if (!Handlebars.AST) {
|
|
return;
|
|
}
|
|
|
|
var LOCATION_INFO = {
|
|
last_line: 0,
|
|
first_line: 0,
|
|
first_column: 0,
|
|
last_column: 0
|
|
};
|
|
|
|
function testLocationInfoStorage(node){
|
|
var properties = [ 'firstLine', 'lastLine', 'firstColumn', 'lastColumn' ],
|
|
property,
|
|
propertiesLen = properties.length,
|
|
i;
|
|
|
|
for (i = 0; i < propertiesLen; i++){
|
|
property = properties[0];
|
|
equals(node[property], 0);
|
|
}
|
|
}
|
|
|
|
describe('MustacheNode', function() {
|
|
function testEscape(open, expected) {
|
|
var mustache = new handlebarsEnv.AST.MustacheNode([{}], {}, open, false);
|
|
equals(mustache.escaped, expected);
|
|
}
|
|
|
|
it('should store args', function() {
|
|
var id = {isSimple: true},
|
|
hash = {},
|
|
mustache = new handlebarsEnv.AST.MustacheNode([id, 'param1'], hash, '', false, LOCATION_INFO);
|
|
equals(mustache.type, 'mustache');
|
|
equals(mustache.hash, hash);
|
|
equals(mustache.escaped, true);
|
|
equals(mustache.id, id);
|
|
equals(mustache.params.length, 1);
|
|
equals(mustache.params[0], 'param1');
|
|
equals(!!mustache.isHelper, true);
|
|
testLocationInfoStorage(mustache);
|
|
});
|
|
it('should accept token for escape', function() {
|
|
testEscape('{{', true);
|
|
testEscape('{{~', true);
|
|
testEscape('{{#', true);
|
|
testEscape('{{~#', true);
|
|
testEscape('{{/', true);
|
|
testEscape('{{~/', true);
|
|
testEscape('{{^', true);
|
|
testEscape('{{~^', true);
|
|
testEscape('{', true);
|
|
testEscape('{', true);
|
|
|
|
testEscape('{{&', false);
|
|
testEscape('{{~&', false);
|
|
testEscape('{{{', false);
|
|
testEscape('{{~{', false);
|
|
});
|
|
it('should accept boolean for escape', function() {
|
|
testEscape(true, true);
|
|
testEscape({}, true);
|
|
|
|
testEscape(false, false);
|
|
testEscape(undefined, false);
|
|
});
|
|
});
|
|
describe('BlockNode', function() {
|
|
it('should throw on mustache mismatch (old sexpr-less version)', function() {
|
|
shouldThrow(function() {
|
|
var mustacheNode = new handlebarsEnv.AST.MustacheNode([{ original: 'foo'}], null, '{{', {});
|
|
new handlebarsEnv.AST.BlockNode(mustacheNode, {}, {}, {path: {original: 'bar'}});
|
|
}, Handlebars.Exception, "foo doesn't match bar");
|
|
});
|
|
it('should throw on mustache mismatch', function() {
|
|
shouldThrow(function() {
|
|
var sexprNode = new handlebarsEnv.AST.SexprNode([{ original: 'foo'}], null);
|
|
var mustacheNode = new handlebarsEnv.AST.MustacheNode(sexprNode, null, '{{', {});
|
|
new handlebarsEnv.AST.BlockNode(mustacheNode, {}, {}, {path: {original: 'bar'}}, {first_line: 2, first_column: 2});
|
|
}, Handlebars.Exception, "foo doesn't match bar - 2:2");
|
|
});
|
|
|
|
it('stores location info', function(){
|
|
var sexprNode = new handlebarsEnv.AST.SexprNode([{ original: 'foo'}], null);
|
|
var mustacheNode = new handlebarsEnv.AST.MustacheNode(sexprNode, null, '{{', {});
|
|
var block = new handlebarsEnv.AST.BlockNode(mustacheNode,
|
|
{strip: {}}, {strip: {}},
|
|
{
|
|
strip: {},
|
|
path: {original: 'foo'}
|
|
},
|
|
LOCATION_INFO);
|
|
testLocationInfoStorage(block);
|
|
});
|
|
});
|
|
describe('IdNode', function() {
|
|
it('should throw on invalid path', function() {
|
|
shouldThrow(function() {
|
|
new handlebarsEnv.AST.IdNode([
|
|
{part: 'foo'},
|
|
{part: '..'},
|
|
{part: 'bar'}
|
|
], {first_line: 1, first_column: 1});
|
|
}, Handlebars.Exception, "Invalid path: foo.. - 1:1");
|
|
shouldThrow(function() {
|
|
new handlebarsEnv.AST.IdNode([
|
|
{part: 'foo'},
|
|
{part: '.'},
|
|
{part: 'bar'}
|
|
], {first_line: 1, first_column: 1});
|
|
}, Handlebars.Exception, "Invalid path: foo. - 1:1");
|
|
shouldThrow(function() {
|
|
new handlebarsEnv.AST.IdNode([
|
|
{part: 'foo'},
|
|
{part: 'this'},
|
|
{part: 'bar'}
|
|
], {first_line: 1, first_column: 1});
|
|
}, Handlebars.Exception, "Invalid path: foothis - 1:1");
|
|
});
|
|
|
|
it('stores location info', function(){
|
|
var idNode = new handlebarsEnv.AST.IdNode([], LOCATION_INFO);
|
|
testLocationInfoStorage(idNode);
|
|
});
|
|
});
|
|
|
|
describe("HashNode", function(){
|
|
|
|
it('stores location info', function(){
|
|
var hash = new handlebarsEnv.AST.HashNode([], LOCATION_INFO);
|
|
testLocationInfoStorage(hash);
|
|
});
|
|
});
|
|
|
|
describe("ContentNode", function(){
|
|
|
|
it('stores location info', function(){
|
|
var content = new handlebarsEnv.AST.ContentNode("HI", LOCATION_INFO);
|
|
testLocationInfoStorage(content);
|
|
});
|
|
});
|
|
|
|
describe("CommentNode", function(){
|
|
|
|
it('stores location info', function(){
|
|
var comment = new handlebarsEnv.AST.CommentNode("HI", LOCATION_INFO);
|
|
testLocationInfoStorage(comment);
|
|
});
|
|
});
|
|
|
|
describe("NumberNode", function(){
|
|
|
|
it('stores location info', function(){
|
|
var integer = new handlebarsEnv.AST.NumberNode("6", LOCATION_INFO);
|
|
testLocationInfoStorage(integer);
|
|
});
|
|
});
|
|
|
|
describe("StringNode", function(){
|
|
|
|
it('stores location info', function(){
|
|
var string = new handlebarsEnv.AST.StringNode("6", LOCATION_INFO);
|
|
testLocationInfoStorage(string);
|
|
});
|
|
});
|
|
|
|
describe("BooleanNode", function(){
|
|
|
|
it('stores location info', function(){
|
|
var bool = new handlebarsEnv.AST.BooleanNode("true", LOCATION_INFO);
|
|
testLocationInfoStorage(bool);
|
|
});
|
|
});
|
|
|
|
describe("DataNode", function(){
|
|
|
|
it('stores location info', function(){
|
|
var data = new handlebarsEnv.AST.DataNode("YES", LOCATION_INFO);
|
|
testLocationInfoStorage(data);
|
|
});
|
|
});
|
|
|
|
describe("PartialNameNode", function(){
|
|
|
|
it('stores location info', function(){
|
|
var pnn = new handlebarsEnv.AST.PartialNameNode({original: "YES"}, LOCATION_INFO);
|
|
testLocationInfoStorage(pnn);
|
|
});
|
|
});
|
|
|
|
describe("PartialNode", function(){
|
|
|
|
it('stores location info', function(){
|
|
var pn = new handlebarsEnv.AST.PartialNode("so_partial", {}, {}, {}, LOCATION_INFO);
|
|
testLocationInfoStorage(pn);
|
|
});
|
|
});
|
|
describe("ProgramNode", function(){
|
|
|
|
describe("storing location info", function(){
|
|
it("stores when `inverse` argument isn't passed", function(){
|
|
var pn = new handlebarsEnv.AST.ProgramNode([], LOCATION_INFO);
|
|
testLocationInfoStorage(pn);
|
|
});
|
|
|
|
it("stores when `inverse` or `stripInverse` arguments passed", function(){
|
|
var pn = new handlebarsEnv.AST.ProgramNode([], {strip: {}}, undefined, LOCATION_INFO);
|
|
testLocationInfoStorage(pn);
|
|
|
|
var clone = {
|
|
strip: {},
|
|
firstLine: 0,
|
|
lastLine: 0,
|
|
firstColumn: 0,
|
|
lastColumn: 0
|
|
};
|
|
pn = new handlebarsEnv.AST.ProgramNode([], {strip: {}}, [ clone ], LOCATION_INFO);
|
|
testLocationInfoStorage(pn);
|
|
|
|
// Assert that the newly created ProgramNode has the same location
|
|
// information as the inverse
|
|
testLocationInfoStorage(pn.inverse);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("Line Numbers", function(){
|
|
var ast, statements;
|
|
|
|
function testColumns(node, firstLine, lastLine, firstColumn, lastColumn){
|
|
equals(node.firstLine, firstLine);
|
|
equals(node.lastLine, lastLine);
|
|
equals(node.firstColumn, firstColumn);
|
|
equals(node.lastColumn, lastColumn);
|
|
}
|
|
|
|
ast = Handlebars.parse("line 1 {{line1Token}}\n line 2 {{line2token}}\n line 3 {{#blockHelperOnLine3}}\nline 4{{line4token}}\n" +
|
|
"line5{{else}}\n{{line6Token}}\n{{/blockHelperOnLine3}}");
|
|
statements = ast.statements;
|
|
|
|
it('gets ContentNode line numbers', function(){
|
|
var contentNode = statements[0];
|
|
testColumns(contentNode, 1, 1, 0, 7);
|
|
});
|
|
|
|
it('gets MustacheNode line numbers', function(){
|
|
var mustacheNode = statements[1];
|
|
testColumns(mustacheNode, 1, 1, 7, 21);
|
|
});
|
|
|
|
it('gets line numbers correct when newlines appear', function(){
|
|
var secondContentNode = statements[2];
|
|
testColumns(secondContentNode, 1, 2, 21, 8);
|
|
});
|
|
|
|
it('gets MustacheNode line numbers correct across newlines', function(){
|
|
var secondMustacheNode = statements[3];
|
|
testColumns(secondMustacheNode, 2, 2, 8, 22);
|
|
});
|
|
|
|
it('gets the block helper information correct', function(){
|
|
var blockHelperNode = statements[5];
|
|
testColumns(blockHelperNode, 3, 7, 8, 23);
|
|
});
|
|
|
|
it('correctly records the line numbers of an inverse of a block helper', function(){
|
|
var blockHelperNode = statements[5],
|
|
inverse = blockHelperNode.inverse;
|
|
|
|
testColumns(inverse, 5, 6, 13, 0);
|
|
});
|
|
});
|
|
});
|
|
|