19bdace85a
Extracts the parser to `@handlebars/parser`, where it can be shared between different implementations. This means that e.g. Glimmer/Ember will be able to iterate on new features without forcing Handlebars to adopt them immediately, and vice versa. All implementors will be able to absorb changes as it makes sense for them.
185 lines
5.4 KiB
JavaScript
185 lines
5.4 KiB
JavaScript
describe('ast', function() {
|
|
if (!Handlebars.AST) {
|
|
return;
|
|
}
|
|
|
|
var AST = Handlebars.AST;
|
|
|
|
describe('BlockStatement', function() {
|
|
it('should throw on mustache mismatch', function() {
|
|
shouldThrow(
|
|
function() {
|
|
handlebarsEnv.parse('\n {{#foo}}{{/bar}}');
|
|
},
|
|
Handlebars.Exception,
|
|
"foo doesn't match bar - 2:5"
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('helpers', function() {
|
|
describe('#helperExpression', function() {
|
|
it('should handle mustache statements', function() {
|
|
equals(
|
|
AST.helpers.helperExpression({
|
|
type: 'MustacheStatement',
|
|
params: [],
|
|
hash: undefined
|
|
}),
|
|
false
|
|
);
|
|
equals(
|
|
AST.helpers.helperExpression({
|
|
type: 'MustacheStatement',
|
|
params: [1],
|
|
hash: undefined
|
|
}),
|
|
true
|
|
);
|
|
equals(
|
|
AST.helpers.helperExpression({
|
|
type: 'MustacheStatement',
|
|
params: [],
|
|
hash: {}
|
|
}),
|
|
true
|
|
);
|
|
});
|
|
it('should handle block statements', function() {
|
|
equals(
|
|
AST.helpers.helperExpression({
|
|
type: 'BlockStatement',
|
|
params: [],
|
|
hash: undefined
|
|
}),
|
|
false
|
|
);
|
|
equals(
|
|
AST.helpers.helperExpression({
|
|
type: 'BlockStatement',
|
|
params: [1],
|
|
hash: undefined
|
|
}),
|
|
true
|
|
);
|
|
equals(
|
|
AST.helpers.helperExpression({
|
|
type: 'BlockStatement',
|
|
params: [],
|
|
hash: {}
|
|
}),
|
|
true
|
|
);
|
|
});
|
|
it('should handle subexpressions', function() {
|
|
equals(AST.helpers.helperExpression({ type: 'SubExpression' }), true);
|
|
});
|
|
it('should work with non-helper nodes', function() {
|
|
equals(AST.helpers.helperExpression({ type: 'Program' }), false);
|
|
|
|
equals(
|
|
AST.helpers.helperExpression({ type: 'PartialStatement' }),
|
|
false
|
|
);
|
|
equals(
|
|
AST.helpers.helperExpression({ type: 'ContentStatement' }),
|
|
false
|
|
);
|
|
equals(
|
|
AST.helpers.helperExpression({ type: 'CommentStatement' }),
|
|
false
|
|
);
|
|
|
|
equals(AST.helpers.helperExpression({ type: 'PathExpression' }), false);
|
|
|
|
equals(AST.helpers.helperExpression({ type: 'StringLiteral' }), false);
|
|
equals(AST.helpers.helperExpression({ type: 'NumberLiteral' }), false);
|
|
equals(AST.helpers.helperExpression({ type: 'BooleanLiteral' }), false);
|
|
equals(
|
|
AST.helpers.helperExpression({ type: 'UndefinedLiteral' }),
|
|
false
|
|
);
|
|
equals(AST.helpers.helperExpression({ type: 'NullLiteral' }), false);
|
|
|
|
equals(AST.helpers.helperExpression({ type: 'Hash' }), false);
|
|
equals(AST.helpers.helperExpression({ type: 'HashPair' }), false);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Line Numbers', function() {
|
|
var ast, body;
|
|
|
|
function testColumns(node, firstLine, lastLine, firstColumn, lastColumn) {
|
|
equals(node.loc.start.line, firstLine);
|
|
equals(node.loc.start.column, firstColumn);
|
|
equals(node.loc.end.line, lastLine);
|
|
equals(node.loc.end.column, lastColumn);
|
|
}
|
|
|
|
/* eslint-disable no-multi-spaces */
|
|
ast = Handlebars.parse(
|
|
'line 1 {{line1Token}}\n' + // 1
|
|
' line 2 {{line2token}}\n' + // 2
|
|
' line 3 {{#blockHelperOnLine3}}\n' + // 3
|
|
'line 4{{line4token}}\n' + // 4
|
|
'line5{{else}}\n' + // 5
|
|
'{{line6Token}}\n' + // 6
|
|
'{{/blockHelperOnLine3}}\n' + // 7
|
|
'{{#open}}\n' + // 8
|
|
'{{else inverse}}\n' + // 9
|
|
'{{else}}\n' + // 10
|
|
'{{/open}}'
|
|
); // 11
|
|
/* eslint-enable no-multi-spaces */
|
|
body = ast.body;
|
|
|
|
it('gets ContentNode line numbers', function() {
|
|
var contentNode = body[0];
|
|
testColumns(contentNode, 1, 1, 0, 7);
|
|
});
|
|
|
|
it('gets MustacheStatement line numbers', function() {
|
|
var mustacheNode = body[1];
|
|
testColumns(mustacheNode, 1, 1, 7, 21);
|
|
});
|
|
|
|
it('gets line numbers correct when newlines appear', function() {
|
|
testColumns(body[2], 1, 2, 21, 8);
|
|
});
|
|
|
|
it('gets MustacheStatement line numbers correct across newlines', function() {
|
|
var secondMustacheStatement = body[3];
|
|
testColumns(secondMustacheStatement, 2, 2, 8, 22);
|
|
});
|
|
|
|
it('gets the block helper information correct', function() {
|
|
var blockHelperNode = body[5];
|
|
testColumns(blockHelperNode, 3, 7, 8, 23);
|
|
});
|
|
|
|
it('correctly records the line numbers the program of a block helper', function() {
|
|
var blockHelperNode = body[5],
|
|
program = blockHelperNode.program;
|
|
|
|
testColumns(program, 3, 5, 31, 5);
|
|
});
|
|
|
|
it('correctly records the line numbers of an inverse of a block helper', function() {
|
|
var blockHelperNode = body[5],
|
|
inverse = blockHelperNode.inverse;
|
|
|
|
testColumns(inverse, 5, 7, 13, 0);
|
|
});
|
|
|
|
it('correctly records the line number of chained inverses', function() {
|
|
var chainInverseNode = body[7];
|
|
|
|
testColumns(chainInverseNode.program, 8, 9, 9, 0);
|
|
testColumns(chainInverseNode.inverse, 9, 10, 16, 0);
|
|
testColumns(chainInverseNode.inverse.body[0].program, 9, 10, 16, 0);
|
|
testColumns(chainInverseNode.inverse.body[0].inverse, 10, 11, 8, 0);
|
|
});
|
|
});
|
|
});
|