Last active
April 27, 2020 22:53
-
-
Save jbboehr/00b0c336ba81483712706d0db6a13f09 to your computer and use it in GitHub Desktop.
handlebars-spec-translator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var inputFile = process.argv[2] || process.argv[1]; | |
var acorn = require('acorn'); | |
var walk = require('acorn-walk'); | |
var fs = require('fs'); | |
var assert = require('assert'); | |
var escodegen = require('escodegen'); | |
var path = require('path'); | |
var inputText = fs.readFileSync(inputFile).toString(); | |
var ast = acorn.parse(inputText); | |
var entries = []; | |
class SkipError extends Error {} | |
function extractNode(node) { | |
return inputText.substring(node.start, node.end); | |
} | |
function handleEquals(node) { | |
var first = node.arguments[0]; | |
if (first.type !== 'CallExpression' || first.callee.name !== 'astFor') { | |
throw new SkipError(); | |
} | |
assert.strictEqual(node.arguments.length, 2); | |
assert.strictEqual(first.arguments.length, 1); | |
var second = node.arguments[1]; | |
assert.strictEqual(second.type, 'Literal'); | |
var templateNode = first.arguments[0]; | |
if (templateNode.type !== "Literal") { | |
throw new SkipError('Only apply to literals'); | |
} | |
var text = 'expectTemplate(' + escodegen.generate(templateNode) + ')' | |
+ '\n.toParseTo(' + escodegen.generate(second) + ')'; | |
// assert.ok(node.arguments.length >= 3); | |
// var text = handleTemplateNode(node.arguments[0]) | |
// + handleHashOrArrayNode(node.arguments[1], node) | |
// //+ handlePartialsNode(node.arguments[2]) | |
// + handleMessageNode(node.arguments[4] || undefined) | |
// + handleExpectedNode(node.arguments[3]); | |
entries.push({ | |
start: node.start, | |
end: node.end, | |
text: text, | |
}); | |
} | |
function handleShouldThrowBody(node) { | |
assert.strictEqual(node.type, 'CallExpression'); | |
assert.strictEqual(node.callee.name, 'astFor'); | |
assert.strictEqual(node.arguments.length, 1); | |
return 'expectTemplate(' + escodegen.generate(node.arguments[0]) + ')'; | |
} | |
function handleShouldThrow(node) { | |
var n = node.arguments.length; | |
assert.ok(n === 2 || n === 3); | |
var first = node.arguments[0]; | |
var second = node.arguments[1]; | |
var third = node.arguments[2]; | |
assert.strictEqual(1, first.body.body.length) | |
assert.strictEqual(first.body.body[0].type, 'ExpressionStatement'); | |
var text = handleShouldThrowBody(first.body.body[0].expression); | |
text += '.toParseError(' + [ | |
escodegen.generate(second), | |
third ? escodegen.generate(third) : undefined | |
].filter(function (v) { | |
return !!v; | |
}).join(',') + ')'; | |
entries.push({ | |
start: node.start, | |
end: node.end, | |
text: text, | |
}); | |
} | |
walk.simple(ast, { | |
CallExpression: function (node) { | |
try { | |
if (node.callee.name === "equals") { | |
handleEquals(node); | |
} else if (node.callee.name === "shouldThrow") { | |
handleShouldThrow(node); | |
} | |
} catch (e) { | |
if (e instanceof SkipError) { | |
console.warn('skipped', e.message, extractNode(node)); | |
} else { | |
console.warn('incoming exception for:', extractNode(node)); | |
throw e; | |
} | |
} | |
}, | |
}); | |
var outputText = ''; | |
var last = 0; | |
var nReplaced = 0; | |
entries.sort(function (a, b) { | |
return a.start - b.start; | |
}).forEach(function (entry) { | |
outputText += inputText.substring(last, entry.start); | |
outputText += entry.text; | |
// outputText += '/*DEL \n' + inputText.substring(entry.start, entry.end) + '\n DEL*/'; | |
last = entry.end; | |
nReplaced++; | |
}); | |
outputText += inputText.substring(last); | |
process.stdout.write(outputText); | |
console.warn(path.basename(inputFile), 'replaced', nReplaced); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var inputFile = process.argv[2] || process.argv[1]; | |
var acorn = require('acorn'); | |
var walk = require('acorn-walk'); | |
var fs = require('fs'); | |
var assert = require('assert'); | |
var escodegen = require('escodegen'); | |
var path = require('path'); | |
var inputText = fs.readFileSync(inputFile).toString(); | |
var ast = acorn.parse(inputText); | |
var entries = []; | |
class SkipError extends Error {} | |
function extractNode(node) { | |
return inputText.substring(node.start, node.end); | |
} | |
function handleTemplateNode(node) { | |
if (['Literal', 'Identifier', 'BinaryExpression'].indexOf(node.type) !== -1) { | |
return 'expectTemplate(' + escodegen.generate(node) + ')'; | |
} else { | |
assert.fail("Unhandled templateNode type: " + node.type); | |
} | |
} | |
function handleObject(node) { | |
var text = ''; | |
var hashNode; | |
node.properties = node.properties.filter(function (child) { | |
if (child.key.name === 'hash') { | |
hashNode = child.value; | |
return false; | |
} else if (child.key.name === 'helpers') { | |
text += '\n.withHelpers(' + escodegen.generate(child.value) + ')'; | |
return false; | |
} else if (child.key.name === 'partials') { | |
text += '\n.withPartials(' + escodegen.generate(child.value) + ')'; | |
return false; | |
} else if (child.key.name === 'decorators') { | |
text += '\n.withDecorators(' + escodegen.generate(child.value) + ')'; | |
return false; | |
} | |
return true; | |
}); | |
var hashNodeText; | |
if (hashNode) { | |
hashNodeText = escodegen.generate(hashNode); | |
if (hashNodeText !== '{}') { | |
text += '\n.withInput(' + hashNodeText + ')'; | |
} | |
var optionsText = escodegen.generate(node); | |
if (optionsText !== '{}') { | |
text += '\n.withCompileOptions(' + optionsText + ')'; | |
} | |
} else { | |
hashNodeText = escodegen.generate(node); | |
if (hashNodeText !== '{}') { | |
text += '\n.withInput(' + hashNodeText + ')'; | |
} | |
} | |
return text; | |
} | |
function handleOptions(node, hadHelpers, hadPartials, compileOptions) { | |
if (node.type === "Literal") { | |
compileOptions['compat'] = escodegen.generate(node); | |
return ''; | |
} else if (node.type === "ObjectExpression") { | |
// fallthrough | |
} else { | |
assert.fail("Unhandled runtimeOptionsNode type: " + node.type); | |
} | |
var text = ''; | |
node.properties = node.properties.filter(function (child) { | |
if (child.key.name === 'helpers') { | |
if (hadHelpers) { | |
throw new SkipError("can't handle two helpers keys"); | |
} | |
text += '\n.withHelpers(' + escodegen.generate(child.value) + ')'; | |
return false; | |
} else if (child.key.name === 'partials') { | |
if (hadPartials) { | |
throw new SkipError("can't handle two partials keys"); | |
} | |
text += '\n.withPartials(' + escodegen.generate(child.value) + ')'; | |
return false; | |
} | |
return true; | |
}); | |
node.properties.forEach(function (child) { | |
compileOptions[child.key.name] = escodegen.generate(child.value); | |
}); | |
return text; | |
} | |
function handleArray(node) { | |
var n = node.elements.length; | |
assert.ok(n >= 1); | |
var hadHelpers = false; | |
var hadPartials = false; | |
var text = ''; | |
if (n >= 1 && node.elements[0]) { | |
var hashText = escodegen.generate(node.elements[0]); | |
if (hashText !== '{}') { | |
text += '\n.withInput(' + escodegen.generate(node.elements[0]) + ')'; | |
} | |
} else { | |
text += '\n.withInput(undefined)'; | |
} | |
if (n >= 2 && node.elements[1] && !(node.elements[1].type === 'Identifier' && node.elements[1].name === 'undefined') ) { | |
hadHelpers = true; | |
var helperText = escodegen.generate(node.elements[1]); | |
if (helperText !== '{}') { | |
text += '\n.withHelpers(' + helperText + ')'; | |
} | |
} | |
if (n >= 3 && node.elements[2] && !(node.elements[2].type === 'Identifier' && node.elements[2].name === 'undefined')) { | |
hadPartials = true; | |
var partialText = escodegen.generate(node.elements[2]); | |
if (partialText !== '{}') { | |
text += '\n.withPartials(' + partialText + ')'; | |
} | |
} | |
var compileOptions = {}; | |
if (n >= 5) { | |
var compileOptionsText = escodegen.generate(node.elements[4]); | |
if (node.elements[4].type === 'Literal') { | |
compileOptions['data'] = compileOptionsText; | |
} else if (compileOptionsText) { | |
compileOptions['data'] = 'true'; | |
} | |
text += '\n.withRuntimeOptions({ data: ' + escodegen.generate(node.elements[4]) + ' })'; | |
} | |
if (n >= 4 && node.elements[3]) { | |
text += handleOptions(node.elements[3], hadHelpers, hadPartials, compileOptions); | |
} | |
if (compileOptions && Object.keys(compileOptions).length > 0) { | |
text += '\n.withCompileOptions({ '; | |
Object.keys(compileOptions).forEach(function (key) { | |
text += key + ': ' + compileOptions[key] + ','; | |
}); | |
text = text.substring(0, text.length - 1); | |
text += ' })'; | |
} | |
return text; | |
} | |
function handleHashOrArrayNode(node, parent) { | |
if (node.type === "Literal") { | |
return '\n.withInput(' + node.raw + ')'; | |
} else if (node.type === "Identifier" && node.name === 'undefined') { | |
return '\n.withInput(undefined)'; | |
} else if (node.type === 'Identifier') { | |
return '\n.withInput(' + escodegen.generate(node) + ')'; | |
} else if (node.type === 'ObjectExpression') { | |
return handleObject(node); | |
} else if (node.type === 'ArrayExpression') { | |
return handleArray(node); | |
} else { | |
assert.fail("Unhandled hashOrArrayNode type: " + node.type); | |
} | |
} | |
function handleExpectedNode(node) { | |
if (['Literal', 'Identifier', 'BinaryExpression', 'CallExpression'].indexOf(node.type) !== -1) { | |
return '\n.toCompileTo(' + escodegen.generate(node) + ')'; | |
} else { | |
assert.fail("Unhandled expectedNode type: " + node.type); | |
} | |
} | |
function handleMessageNode(node) { | |
if (!node) return ''; | |
if (node.type === 'Literal') { | |
return '\n.withMessage(' + node.raw + ')'; | |
} else if (node.type === 'Identifier') { | |
return '\n.withMessage(' + node.name + ')'; | |
} else { | |
assert.fail("Unhandled messageNode type: " + node.type); | |
} | |
} | |
function handleShouldCompileTo(node) { | |
assert.ok(node.arguments.length >= 3); | |
var text = handleTemplateNode(node.arguments[0]) | |
+ handleHashOrArrayNode(node.arguments[1], node) | |
+ handleMessageNode(node.arguments[3] || undefined) | |
+ handleExpectedNode(node.arguments[2]); | |
entries.push({ | |
start: node.start, | |
end: node.end, | |
text: text, | |
}); | |
} | |
function handleShouldCompileToWithPartials(node) { | |
assert.ok(node.arguments.length >= 3); | |
var text = handleTemplateNode(node.arguments[0]) | |
+ handleHashOrArrayNode(node.arguments[1], node) | |
//+ handlePartialsNode(node.arguments[2]) | |
+ handleMessageNode(node.arguments[4] || undefined) | |
+ handleExpectedNode(node.arguments[3]); | |
entries.push({ | |
start: node.start, | |
end: node.end, | |
text: text, | |
}); | |
} | |
walk.simple(ast, { | |
CallExpression: function (node) { | |
try { | |
if (node.callee.name === "shouldCompileTo") { | |
handleShouldCompileTo(node); | |
} else if (node.callee.name === 'shouldCompileToWithPartials') { | |
handleShouldCompileToWithPartials(node); | |
} | |
} catch (e) { | |
if (e instanceof SkipError) { | |
console.warn('skipped', e.message, extractNode(node)); | |
} else { | |
console.warn('incoming exception for:', extractNode(node)); | |
throw e; | |
} | |
} | |
}, | |
}); | |
var outputText = ''; | |
var last = 0; | |
var nReplaced = 0; | |
entries.sort(function (a, b) { | |
return a.start - b.start; | |
}).forEach(function (entry) { | |
outputText += inputText.substring(last, entry.start); | |
outputText += entry.text; | |
// outputText += '/*DEL \n' + inputText.substring(entry.start, entry.end) + '\n DEL*/'; | |
last = entry.end; | |
nReplaced++; | |
}); | |
outputText += inputText.substring(last); | |
process.stdout.write(outputText); | |
console.warn(path.basename(inputFile), 'replaced', nReplaced); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "handlebars-spec-translator", | |
"version": "0.1.0", | |
"lockfileVersion": 1, | |
"requires": true, | |
"dependencies": { | |
"acorn": { | |
"version": "7.1.1", | |
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", | |
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" | |
}, | |
"acorn-walk": { | |
"version": "7.1.1", | |
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", | |
"integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==" | |
}, | |
"deep-is": { | |
"version": "0.1.3", | |
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", | |
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" | |
}, | |
"escodegen": { | |
"version": "1.14.1", | |
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", | |
"integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", | |
"requires": { | |
"esprima": "^4.0.1", | |
"estraverse": "^4.2.0", | |
"esutils": "^2.0.2", | |
"optionator": "^0.8.1", | |
"source-map": "~0.6.1" | |
} | |
}, | |
"esprima": { | |
"version": "4.0.1", | |
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", | |
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" | |
}, | |
"estraverse": { | |
"version": "4.3.0", | |
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", | |
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" | |
}, | |
"esutils": { | |
"version": "2.0.3", | |
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", | |
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" | |
}, | |
"fast-levenshtein": { | |
"version": "2.0.6", | |
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", | |
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" | |
}, | |
"levn": { | |
"version": "0.3.0", | |
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", | |
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", | |
"requires": { | |
"prelude-ls": "~1.1.2", | |
"type-check": "~0.3.2" | |
} | |
}, | |
"optionator": { | |
"version": "0.8.3", | |
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", | |
"integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", | |
"requires": { | |
"deep-is": "~0.1.3", | |
"fast-levenshtein": "~2.0.6", | |
"levn": "~0.3.0", | |
"prelude-ls": "~1.1.2", | |
"type-check": "~0.3.2", | |
"word-wrap": "~1.2.3" | |
} | |
}, | |
"prelude-ls": { | |
"version": "1.1.2", | |
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", | |
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" | |
}, | |
"source-map": { | |
"version": "0.6.1", | |
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", | |
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", | |
"optional": true | |
}, | |
"type-check": { | |
"version": "0.3.2", | |
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", | |
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", | |
"requires": { | |
"prelude-ls": "~1.1.2" | |
} | |
}, | |
"word-wrap": { | |
"version": "1.2.3", | |
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", | |
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "handlebars-spec-translator", | |
"version": "0.1.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "", | |
"license": "GPL-2.0", | |
"dependencies": { | |
"acorn": "^7.1.1", | |
"acorn-walk": "^7.1.1", | |
"escodegen": "^1.14.1" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/spec/env/common.js b/spec/env/common.js | |
index a122f4d..1827265 100644 | |
--- a/spec/env/common.js | |
+++ b/spec/env/common.js | |
@@ -237,3 +237,21 @@ HandlebarsTestBench.prototype._combineRuntimeOptions = function() { | |
combinedRuntimeOptions.decorators = this.decorators; | |
return combinedRuntimeOptions; | |
}; | |
+ | |
+HandlebarsTestBench.prototype.toParseTo = function(expectedOutputAsString) { | |
+ expect(this._parseAndPrint()).to.equal( | |
+ expectedOutputAsString, | |
+ this.message | |
+ ); | |
+}; | |
+ | |
+HandlebarsTestBench.prototype.toParseError = function(errorLike, errMsgMatcher) { | |
+ var self = this; | |
+ expect(function() { | |
+ self._parseAndPrint(); | |
+ }).to.throw(errorLike, errMsgMatcher, this.message); | |
+}; | |
+ | |
+HandlebarsTestBench.prototype._parseAndPrint = function() { | |
+ return Handlebars.print(Handlebars.parse(this.templateAsString)); | |
+}; | |
diff --git a/spec/parser.js b/spec/parser.js | |
index 2aa7e39..626491a 100644 | |
--- a/spec/parser.js | |
+++ b/spec/parser.js | |
@@ -1,432 +1,317 @@ | |
-describe('parser', function() { | |
+describe('parser', function () { | |
if (!Handlebars.print) { | |
return; | |
} | |
- function astFor(template) { | |
- var ast = Handlebars.parse(template); | |
- return Handlebars.print(ast); | |
- } | |
- | |
- it('parses simple mustaches', function() { | |
- equals(astFor('{{123}}'), '{{ NUMBER{123} [] }}\n'); | |
- equals(astFor('{{"foo"}}'), '{{ "foo" [] }}\n'); | |
- equals(astFor('{{false}}'), '{{ BOOLEAN{false} [] }}\n'); | |
- equals(astFor('{{true}}'), '{{ BOOLEAN{true} [] }}\n'); | |
- equals(astFor('{{foo}}'), '{{ PATH:foo [] }}\n'); | |
- equals(astFor('{{foo?}}'), '{{ PATH:foo? [] }}\n'); | |
- equals(astFor('{{foo_}}'), '{{ PATH:foo_ [] }}\n'); | |
- equals(astFor('{{foo-}}'), '{{ PATH:foo- [] }}\n'); | |
- equals(astFor('{{foo:}}'), '{{ PATH:foo: [] }}\n'); | |
+ it('parses simple mustaches', function () { | |
+ expectTemplate('{{123}}') | |
+ .toParseTo('{{ NUMBER{123} [] }}\n'); | |
+ expectTemplate('{{"foo"}}') | |
+ .toParseTo('{{ "foo" [] }}\n'); | |
+ expectTemplate('{{false}}') | |
+ .toParseTo('{{ BOOLEAN{false} [] }}\n'); | |
+ expectTemplate('{{true}}') | |
+ .toParseTo('{{ BOOLEAN{true} [] }}\n'); | |
+ expectTemplate('{{foo}}') | |
+ .toParseTo('{{ PATH:foo [] }}\n'); | |
+ expectTemplate('{{foo?}}') | |
+ .toParseTo('{{ PATH:foo? [] }}\n'); | |
+ expectTemplate('{{foo_}}') | |
+ .toParseTo('{{ PATH:foo_ [] }}\n'); | |
+ expectTemplate('{{foo-}}') | |
+ .toParseTo('{{ PATH:foo- [] }}\n'); | |
+ expectTemplate('{{foo:}}') | |
+ .toParseTo('{{ PATH:foo: [] }}\n'); | |
}); | |
- it('parses simple mustaches with data', function() { | |
- equals(astFor('{{@foo}}'), '{{ @PATH:foo [] }}\n'); | |
+ it('parses simple mustaches with data', function () { | |
+ expectTemplate('{{@foo}}') | |
+ .toParseTo('{{ @PATH:foo [] }}\n'); | |
}); | |
- it('parses simple mustaches with data paths', function() { | |
- equals(astFor('{{@../foo}}'), '{{ @PATH:foo [] }}\n'); | |
+ it('parses simple mustaches with data paths', function () { | |
+ expectTemplate('{{@../foo}}') | |
+ .toParseTo('{{ @PATH:foo [] }}\n'); | |
}); | |
- it('parses mustaches with paths', function() { | |
- equals(astFor('{{foo/bar}}'), '{{ PATH:foo/bar [] }}\n'); | |
+ it('parses mustaches with paths', function () { | |
+ expectTemplate('{{foo/bar}}') | |
+ .toParseTo('{{ PATH:foo/bar [] }}\n'); | |
}); | |
- it('parses mustaches with this/foo', function() { | |
- equals(astFor('{{this/foo}}'), '{{ PATH:foo [] }}\n'); | |
+ it('parses mustaches with this/foo', function () { | |
+ expectTemplate('{{this/foo}}') | |
+ .toParseTo('{{ PATH:foo [] }}\n'); | |
}); | |
- it('parses mustaches with - in a path', function() { | |
- equals(astFor('{{foo-bar}}'), '{{ PATH:foo-bar [] }}\n'); | |
+ it('parses mustaches with - in a path', function () { | |
+ expectTemplate('{{foo-bar}}') | |
+ .toParseTo('{{ PATH:foo-bar [] }}\n'); | |
}); | |
- it('parses mustaches with escaped [] in a path', function() { | |
- equals(astFor('{{[foo[\\]]}}'), '{{ PATH:foo[] [] }}\n'); | |
+ it('parses mustaches with escaped [] in a path', function () { | |
+ expectTemplate('{{[foo[\\]]}}') | |
+ .toParseTo('{{ PATH:foo[] [] }}\n'); | |
}); | |
- it('parses escaped \\\\ in path', function() { | |
- equals(astFor('{{[foo\\\\]}}'), '{{ PATH:foo\\ [] }}\n'); | |
+ it('parses escaped \\\\ in path', function () { | |
+ expectTemplate('{{[foo\\\\]}}') | |
+ .toParseTo('{{ PATH:foo\\ [] }}\n'); | |
}); | |
- it('parses mustaches with parameters', function() { | |
- equals(astFor('{{foo bar}}'), '{{ PATH:foo [PATH:bar] }}\n'); | |
+ it('parses mustaches with parameters', function () { | |
+ expectTemplate('{{foo bar}}') | |
+ .toParseTo('{{ PATH:foo [PATH:bar] }}\n'); | |
}); | |
- it('parses mustaches with string parameters', function() { | |
- equals(astFor('{{foo bar "baz" }}'), '{{ PATH:foo [PATH:bar, "baz"] }}\n'); | |
+ it('parses mustaches with string parameters', function () { | |
+ expectTemplate('{{foo bar "baz" }}') | |
+ .toParseTo('{{ PATH:foo [PATH:bar, "baz"] }}\n'); | |
}); | |
- it('parses mustaches with NUMBER parameters', function() { | |
- equals(astFor('{{foo 1}}'), '{{ PATH:foo [NUMBER{1}] }}\n'); | |
+ it('parses mustaches with NUMBER parameters', function () { | |
+ expectTemplate('{{foo 1}}') | |
+ .toParseTo('{{ PATH:foo [NUMBER{1}] }}\n'); | |
}); | |
- it('parses mustaches with BOOLEAN parameters', function() { | |
- equals(astFor('{{foo true}}'), '{{ PATH:foo [BOOLEAN{true}] }}\n'); | |
- equals(astFor('{{foo false}}'), '{{ PATH:foo [BOOLEAN{false}] }}\n'); | |
+ it('parses mustaches with BOOLEAN parameters', function () { | |
+ expectTemplate('{{foo true}}') | |
+ .toParseTo('{{ PATH:foo [BOOLEAN{true}] }}\n'); | |
+ expectTemplate('{{foo false}}') | |
+ .toParseTo('{{ PATH:foo [BOOLEAN{false}] }}\n'); | |
}); | |
- it('parses mustaches with undefined and null paths', function() { | |
- equals(astFor('{{undefined}}'), '{{ UNDEFINED [] }}\n'); | |
- equals(astFor('{{null}}'), '{{ NULL [] }}\n'); | |
+ it('parses mustaches with undefined and null paths', function () { | |
+ expectTemplate('{{undefined}}') | |
+ .toParseTo('{{ UNDEFINED [] }}\n'); | |
+ expectTemplate('{{null}}') | |
+ .toParseTo('{{ NULL [] }}\n'); | |
}); | |
- it('parses mustaches with undefined and null parameters', function() { | |
- equals( | |
- astFor('{{foo undefined null}}'), | |
- '{{ PATH:foo [UNDEFINED, NULL] }}\n' | |
- ); | |
+ it('parses mustaches with undefined and null parameters', function () { | |
+ expectTemplate('{{foo undefined null}}') | |
+ .toParseTo('{{ PATH:foo [UNDEFINED, NULL] }}\n'); | |
}); | |
- it('parses mustaches with DATA parameters', function() { | |
- equals(astFor('{{foo @bar}}'), '{{ PATH:foo [@PATH:bar] }}\n'); | |
+ it('parses mustaches with DATA parameters', function () { | |
+ expectTemplate('{{foo @bar}}') | |
+ .toParseTo('{{ PATH:foo [@PATH:bar] }}\n'); | |
}); | |
- it('parses mustaches with hash arguments', function() { | |
- equals(astFor('{{foo bar=baz}}'), '{{ PATH:foo [] HASH{bar=PATH:baz} }}\n'); | |
- equals(astFor('{{foo bar=1}}'), '{{ PATH:foo [] HASH{bar=NUMBER{1}} }}\n'); | |
- equals( | |
- astFor('{{foo bar=true}}'), | |
- '{{ PATH:foo [] HASH{bar=BOOLEAN{true}} }}\n' | |
- ); | |
- equals( | |
- astFor('{{foo bar=false}}'), | |
- '{{ PATH:foo [] HASH{bar=BOOLEAN{false}} }}\n' | |
- ); | |
- equals( | |
- astFor('{{foo bar=@baz}}'), | |
- '{{ PATH:foo [] HASH{bar=@PATH:baz} }}\n' | |
- ); | |
+ it('parses mustaches with hash arguments', function () { | |
+ expectTemplate('{{foo bar=baz}}') | |
+ .toParseTo('{{ PATH:foo [] HASH{bar=PATH:baz} }}\n'); | |
+ expectTemplate('{{foo bar=1}}') | |
+ .toParseTo('{{ PATH:foo [] HASH{bar=NUMBER{1}} }}\n'); | |
+ expectTemplate('{{foo bar=true}}') | |
+ .toParseTo('{{ PATH:foo [] HASH{bar=BOOLEAN{true}} }}\n'); | |
+ expectTemplate('{{foo bar=false}}') | |
+ .toParseTo('{{ PATH:foo [] HASH{bar=BOOLEAN{false}} }}\n'); | |
+ expectTemplate('{{foo bar=@baz}}') | |
+ .toParseTo('{{ PATH:foo [] HASH{bar=@PATH:baz} }}\n'); | |
- equals( | |
- astFor('{{foo bar=baz bat=bam}}'), | |
- '{{ PATH:foo [] HASH{bar=PATH:baz, bat=PATH:bam} }}\n' | |
- ); | |
- equals( | |
- astFor('{{foo bar=baz bat="bam"}}'), | |
- '{{ PATH:foo [] HASH{bar=PATH:baz, bat="bam"} }}\n' | |
- ); | |
+ expectTemplate('{{foo bar=baz bat=bam}}') | |
+ .toParseTo('{{ PATH:foo [] HASH{bar=PATH:baz, bat=PATH:bam} }}\n'); | |
+ expectTemplate('{{foo bar=baz bat="bam"}}') | |
+ .toParseTo('{{ PATH:foo [] HASH{bar=PATH:baz, bat="bam"} }}\n'); | |
- equals(astFor("{{foo bat='bam'}}"), '{{ PATH:foo [] HASH{bat="bam"} }}\n'); | |
+ expectTemplate('{{foo bat=\'bam\'}}') | |
+ .toParseTo('{{ PATH:foo [] HASH{bat="bam"} }}\n'); | |
- equals( | |
- astFor('{{foo omg bar=baz bat="bam"}}'), | |
- '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam"} }}\n' | |
- ); | |
- equals( | |
- astFor('{{foo omg bar=baz bat="bam" baz=1}}'), | |
- '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=NUMBER{1}} }}\n' | |
- ); | |
- equals( | |
- astFor('{{foo omg bar=baz bat="bam" baz=true}}'), | |
- '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{true}} }}\n' | |
- ); | |
- equals( | |
- astFor('{{foo omg bar=baz bat="bam" baz=false}}'), | |
- '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{false}} }}\n' | |
- ); | |
+ expectTemplate('{{foo omg bar=baz bat="bam"}}') | |
+ .toParseTo('{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam"} }}\n'); | |
+ expectTemplate('{{foo omg bar=baz bat="bam" baz=1}}') | |
+ .toParseTo('{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=NUMBER{1}} }}\n'); | |
+ expectTemplate('{{foo omg bar=baz bat="bam" baz=true}}') | |
+ .toParseTo('{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{true}} }}\n'); | |
+ expectTemplate('{{foo omg bar=baz bat="bam" baz=false}}') | |
+ .toParseTo('{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{false}} }}\n'); | |
}); | |
- it('parses contents followed by a mustache', function() { | |
- equals( | |
- astFor('foo bar {{baz}}'), | |
- "CONTENT[ 'foo bar ' ]\n{{ PATH:baz [] }}\n" | |
- ); | |
+ it('parses contents followed by a mustache', function () { | |
+ expectTemplate('foo bar {{baz}}') | |
+ .toParseTo('CONTENT[ \'foo bar \' ]\n{{ PATH:baz [] }}\n'); | |
}); | |
- it('parses a partial', function() { | |
- equals(astFor('{{> foo }}'), '{{> PARTIAL:foo }}\n'); | |
- equals(astFor('{{> "foo" }}'), '{{> PARTIAL:foo }}\n'); | |
- equals(astFor('{{> 1 }}'), '{{> PARTIAL:1 }}\n'); | |
+ it('parses a partial', function () { | |
+ expectTemplate('{{> foo }}') | |
+ .toParseTo('{{> PARTIAL:foo }}\n'); | |
+ expectTemplate('{{> "foo" }}') | |
+ .toParseTo('{{> PARTIAL:foo }}\n'); | |
+ expectTemplate('{{> 1 }}') | |
+ .toParseTo('{{> PARTIAL:1 }}\n'); | |
}); | |
- it('parses a partial with context', function() { | |
- equals(astFor('{{> foo bar}}'), '{{> PARTIAL:foo PATH:bar }}\n'); | |
+ it('parses a partial with context', function () { | |
+ expectTemplate('{{> foo bar}}') | |
+ .toParseTo('{{> PARTIAL:foo PATH:bar }}\n'); | |
}); | |
- it('parses a partial with hash', function() { | |
- equals( | |
- astFor('{{> foo bar=bat}}'), | |
- '{{> PARTIAL:foo HASH{bar=PATH:bat} }}\n' | |
- ); | |
+ it('parses a partial with hash', function () { | |
+ expectTemplate('{{> foo bar=bat}}') | |
+ .toParseTo('{{> PARTIAL:foo HASH{bar=PATH:bat} }}\n'); | |
}); | |
- it('parses a partial with context and hash', function() { | |
- equals( | |
- astFor('{{> foo bar bat=baz}}'), | |
- '{{> PARTIAL:foo PATH:bar HASH{bat=PATH:baz} }}\n' | |
- ); | |
+ it('parses a partial with context and hash', function () { | |
+ expectTemplate('{{> foo bar bat=baz}}') | |
+ .toParseTo('{{> PARTIAL:foo PATH:bar HASH{bat=PATH:baz} }}\n'); | |
}); | |
- it('parses a partial with a complex name', function() { | |
- equals( | |
- astFor('{{> shared/partial?.bar}}'), | |
- '{{> PARTIAL:shared/partial?.bar }}\n' | |
- ); | |
+ it('parses a partial with a complex name', function () { | |
+ expectTemplate('{{> shared/partial?.bar}}') | |
+ .toParseTo('{{> PARTIAL:shared/partial?.bar }}\n'); | |
}); | |
- it('parsers partial blocks', function() { | |
- equals( | |
- astFor('{{#> foo}}bar{{/foo}}'), | |
- "{{> PARTIAL BLOCK:foo PROGRAM:\n CONTENT[ 'bar' ]\n }}\n" | |
- ); | |
+ it('parsers partial blocks', function () { | |
+ expectTemplate('{{#> foo}}bar{{/foo}}') | |
+ .toParseTo('{{> PARTIAL BLOCK:foo PROGRAM:\n CONTENT[ \'bar\' ]\n }}\n'); | |
}); | |
- it('should handle parser block mismatch', function() { | |
- shouldThrow( | |
- function() { | |
- astFor('{{#> goodbyes}}{{/hellos}}'); | |
- }, | |
- Error, | |
- /goodbyes doesn't match hellos/ | |
- ); | |
+ it('should handle parser block mismatch', function () { | |
+ expectTemplate('{{#> goodbyes}}{{/hellos}}').toParseError(Error, /goodbyes doesn't match hellos/); | |
}); | |
- it('parsers partial blocks with arguments', function() { | |
- equals( | |
- astFor('{{#> foo context hash=value}}bar{{/foo}}'), | |
- "{{> PARTIAL BLOCK:foo PATH:context HASH{hash=PATH:value} PROGRAM:\n CONTENT[ 'bar' ]\n }}\n" | |
- ); | |
+ it('parsers partial blocks with arguments', function () { | |
+ expectTemplate('{{#> foo context hash=value}}bar{{/foo}}') | |
+ .toParseTo('{{> PARTIAL BLOCK:foo PATH:context HASH{hash=PATH:value} PROGRAM:\n CONTENT[ \'bar\' ]\n }}\n'); | |
}); | |
- it('parses a comment', function() { | |
- equals( | |
- astFor('{{! this is a comment }}'), | |
- "{{! ' this is a comment ' }}\n" | |
- ); | |
+ it('parses a comment', function () { | |
+ expectTemplate('{{! this is a comment }}') | |
+ .toParseTo('{{! \' this is a comment \' }}\n'); | |
}); | |
- it('parses a multi-line comment', function() { | |
- equals( | |
- astFor('{{!\nthis is a multi-line comment\n}}'), | |
- "{{! '\nthis is a multi-line comment\n' }}\n" | |
- ); | |
+ it('parses a multi-line comment', function () { | |
+ expectTemplate('{{!\nthis is a multi-line comment\n}}') | |
+ .toParseTo('{{! \'\nthis is a multi-line comment\n\' }}\n'); | |
}); | |
- it('parses an inverse section', function() { | |
- equals( | |
- astFor('{{#foo}} bar {{^}} baz {{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]\n" | |
- ); | |
+ it('parses an inverse section', function () { | |
+ expectTemplate('{{#foo}} bar {{^}} baz {{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ \' bar \' ]\n {{^}}\n CONTENT[ \' baz \' ]\n'); | |
}); | |
- it('parses an inverse (else-style) section', function() { | |
- equals( | |
- astFor('{{#foo}} bar {{else}} baz {{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]\n" | |
- ); | |
+ it('parses an inverse (else-style) section', function () { | |
+ expectTemplate('{{#foo}} bar {{else}} baz {{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ \' bar \' ]\n {{^}}\n CONTENT[ \' baz \' ]\n'); | |
}); | |
- it('parses multiple inverse sections', function() { | |
- equals( | |
- astFor('{{#foo}} bar {{else if bar}}{{else}} baz {{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n BLOCK:\n PATH:if [PATH:bar]\n PROGRAM:\n {{^}}\n CONTENT[ ' baz ' ]\n" | |
- ); | |
+ it('parses multiple inverse sections', function () { | |
+ expectTemplate('{{#foo}} bar {{else if bar}}{{else}} baz {{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ \' bar \' ]\n {{^}}\n BLOCK:\n PATH:if [PATH:bar]\n PROGRAM:\n {{^}}\n CONTENT[ \' baz \' ]\n'); | |
}); | |
- it('parses empty blocks', function() { | |
- equals(astFor('{{#foo}}{{/foo}}'), 'BLOCK:\n PATH:foo []\n PROGRAM:\n'); | |
+ it('parses empty blocks', function () { | |
+ expectTemplate('{{#foo}}{{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n'); | |
}); | |
- it('parses empty blocks with empty inverse section', function() { | |
- equals( | |
- astFor('{{#foo}}{{^}}{{/foo}}'), | |
- 'BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n' | |
- ); | |
+ it('parses empty blocks with empty inverse section', function () { | |
+ expectTemplate('{{#foo}}{{^}}{{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n'); | |
}); | |
- it('parses empty blocks with empty inverse (else-style) section', function() { | |
- equals( | |
- astFor('{{#foo}}{{else}}{{/foo}}'), | |
- 'BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n' | |
- ); | |
+ it('parses empty blocks with empty inverse (else-style) section', function () { | |
+ expectTemplate('{{#foo}}{{else}}{{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n'); | |
}); | |
- it('parses non-empty blocks with empty inverse section', function() { | |
- equals( | |
- astFor('{{#foo}} bar {{^}}{{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n" | |
- ); | |
+ it('parses non-empty blocks with empty inverse section', function () { | |
+ expectTemplate('{{#foo}} bar {{^}}{{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ \' bar \' ]\n {{^}}\n'); | |
}); | |
- it('parses non-empty blocks with empty inverse (else-style) section', function() { | |
- equals( | |
- astFor('{{#foo}} bar {{else}}{{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n" | |
- ); | |
+ it('parses non-empty blocks with empty inverse (else-style) section', function () { | |
+ expectTemplate('{{#foo}} bar {{else}}{{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ \' bar \' ]\n {{^}}\n'); | |
}); | |
- it('parses empty blocks with non-empty inverse section', function() { | |
- equals( | |
- astFor('{{#foo}}{{^}} bar {{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]\n" | |
- ); | |
+ it('parses empty blocks with non-empty inverse section', function () { | |
+ expectTemplate('{{#foo}}{{^}} bar {{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ \' bar \' ]\n'); | |
}); | |
- it('parses empty blocks with non-empty inverse (else-style) section', function() { | |
- equals( | |
- astFor('{{#foo}}{{else}} bar {{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]\n" | |
- ); | |
+ it('parses empty blocks with non-empty inverse (else-style) section', function () { | |
+ expectTemplate('{{#foo}}{{else}} bar {{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ \' bar \' ]\n'); | |
}); | |
- it('parses a standalone inverse section', function() { | |
- equals( | |
- astFor('{{^foo}}bar{{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n {{^}}\n CONTENT[ 'bar' ]\n" | |
- ); | |
+ it('parses a standalone inverse section', function () { | |
+ expectTemplate('{{^foo}}bar{{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n {{^}}\n CONTENT[ \'bar\' ]\n'); | |
}); | |
- it('throws on old inverse section', function() { | |
- shouldThrow(function() { | |
- astFor('{{else foo}}bar{{/foo}}'); | |
- }, Error); | |
+ it('throws on old inverse section', function () { | |
+ expectTemplate('{{else foo}}bar{{/foo}}').toParseError(Error); | |
}); | |
- it('parses block with block params', function() { | |
- equals( | |
- astFor('{{#foo as |bar baz|}}content{{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n" | |
- ); | |
+ it('parses block with block params', function () { | |
+ expectTemplate('{{#foo as |bar baz|}}content{{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ \'content\' ]\n'); | |
}); | |
- it('parses inverse block with block params', function() { | |
- equals( | |
- astFor('{{^foo as |bar baz|}}content{{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n {{^}}\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n" | |
- ); | |
+ it('parses inverse block with block params', function () { | |
+ expectTemplate('{{^foo as |bar baz|}}content{{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n {{^}}\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ \'content\' ]\n'); | |
}); | |
- it('parses chained inverse block with block params', function() { | |
- equals( | |
- astFor('{{#foo}}{{else foo as |bar baz|}}content{{/foo}}'), | |
- "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n" | |
- ); | |
+ it('parses chained inverse block with block params', function () { | |
+ expectTemplate('{{#foo}}{{else foo as |bar baz|}}content{{/foo}}') | |
+ .toParseTo('BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ \'content\' ]\n'); | |
}); | |
- it("raises if there's a Parse error", function() { | |
- shouldThrow( | |
- function() { | |
- astFor('foo{{^}}bar'); | |
- }, | |
- Error, | |
- /Parse error on line 1/ | |
- ); | |
- shouldThrow( | |
- function() { | |
- astFor('{{foo}'); | |
- }, | |
- Error, | |
- /Parse error on line 1/ | |
- ); | |
- shouldThrow( | |
- function() { | |
- astFor('{{foo &}}'); | |
- }, | |
- Error, | |
- /Parse error on line 1/ | |
- ); | |
- shouldThrow( | |
- function() { | |
- astFor('{{#goodbyes}}{{/hellos}}'); | |
- }, | |
- Error, | |
- /goodbyes doesn't match hellos/ | |
- ); | |
+ it("raises if there's a Parse error", function () { | |
+ expectTemplate('foo{{^}}bar').toParseError(Error, /Parse error on line 1/); | |
+ expectTemplate('{{foo}').toParseError(Error, /Parse error on line 1/); | |
+ expectTemplate('{{foo &}}').toParseError(Error, /Parse error on line 1/); | |
+ expectTemplate('{{#goodbyes}}{{/hellos}}').toParseError(Error, /goodbyes doesn't match hellos/); | |
- shouldThrow( | |
- function() { | |
- astFor('{{{{goodbyes}}}} {{{{/hellos}}}}'); | |
- }, | |
- Error, | |
- /goodbyes doesn't match hellos/ | |
- ); | |
+ expectTemplate('{{{{goodbyes}}}} {{{{/hellos}}}}').toParseError(Error, /goodbyes doesn't match hellos/); | |
}); | |
- it('should handle invalid paths', function() { | |
- shouldThrow( | |
- function() { | |
- astFor('{{foo/../bar}}'); | |
- }, | |
- Error, | |
- /Invalid path: foo\/\.\. - 1:2/ | |
- ); | |
- shouldThrow( | |
- function() { | |
- astFor('{{foo/./bar}}'); | |
- }, | |
- Error, | |
- /Invalid path: foo\/\. - 1:2/ | |
- ); | |
- shouldThrow( | |
- function() { | |
- astFor('{{foo/this/bar}}'); | |
- }, | |
- Error, | |
- /Invalid path: foo\/this - 1:2/ | |
- ); | |
+ it('should handle invalid paths', function () { | |
+ expectTemplate('{{foo/../bar}}').toParseError(Error, /Invalid path: foo\/\.\. - 1:2/); | |
+ expectTemplate('{{foo/./bar}}').toParseError(Error, /Invalid path: foo\/\. - 1:2/); | |
+ expectTemplate('{{foo/this/bar}}').toParseError(Error, /Invalid path: foo\/this - 1:2/); | |
}); | |
- it('knows how to report the correct line number in errors', function() { | |
- shouldThrow( | |
- function() { | |
- astFor('hello\nmy\n{{foo}'); | |
- }, | |
- Error, | |
- /Parse error on line 3/ | |
- ); | |
- shouldThrow( | |
- function() { | |
- astFor('hello\n\nmy\n\n{{foo}'); | |
- }, | |
- Error, | |
- /Parse error on line 5/ | |
- ); | |
+ it('knows how to report the correct line number in errors', function () { | |
+ expectTemplate('hello\nmy\n{{foo}').toParseError(Error, /Parse error on line 3/); | |
+ expectTemplate('hello\n\nmy\n\n{{foo}').toParseError(Error, /Parse error on line 5/); | |
}); | |
- it('knows how to report the correct line number in errors when the first character is a newline', function() { | |
- shouldThrow( | |
- function() { | |
- astFor('\n\nhello\n\nmy\n\n{{foo}'); | |
- }, | |
- Error, | |
- /Parse error on line 7/ | |
- ); | |
+ it('knows how to report the correct line number in errors when the first character is a newline', function () { | |
+ expectTemplate('\n\nhello\n\nmy\n\n{{foo}').toParseError(Error, /Parse error on line 7/); | |
}); | |
- describe('externally compiled AST', function() { | |
- it('can pass through an already-compiled AST', function() { | |
- equals( | |
- astFor({ | |
- type: 'Program', | |
- body: [{ type: 'ContentStatement', value: 'Hello' }] | |
- }), | |
- "CONTENT[ 'Hello' ]\n" | |
- ); | |
+ describe('externally compiled AST', function () { | |
+ it('can pass through an already-compiled AST', function () { | |
+ expectTemplate({ | |
+ type: 'Program', | |
+ body: [{ | |
+ type: 'ContentStatement', | |
+ value: 'Hello' | |
+ }] | |
+ }) | |
+ .toParseTo('CONTENT[ \'Hello\' ]\n'); | |
}); | |
}); | |
- describe('directives', function() { | |
- it('should parse block directives', function() { | |
- equals( | |
- astFor('{{#* foo}}{{/foo}}'), | |
- 'DIRECTIVE BLOCK:\n PATH:foo []\n PROGRAM:\n' | |
- ); | |
+ describe('directives', function () { | |
+ it('should parse block directives', function () { | |
+ expectTemplate('{{#* foo}}{{/foo}}') | |
+ .toParseTo('DIRECTIVE BLOCK:\n PATH:foo []\n PROGRAM:\n'); | |
}); | |
- it('should parse directives', function() { | |
- equals(astFor('{{* foo}}'), '{{ DIRECTIVE PATH:foo [] }}\n'); | |
+ it('should parse directives', function () { | |
+ expectTemplate('{{* foo}}') | |
+ .toParseTo('{{ DIRECTIVE PATH:foo [] }}\n'); | |
}); | |
- it('should fail if directives have inverse', function() { | |
- shouldThrow( | |
- function() { | |
- astFor('{{#* foo}}{{^}}{{/foo}}'); | |
- }, | |
- Error, | |
- /Unexpected inverse/ | |
- ); | |
+ it('should fail if directives have inverse', function () { | |
+ expectTemplate('{{#* foo}}{{^}}{{/foo}}').toParseError(Error, /Unexpected inverse/); | |
}); | |
}); | |
- it('GH1024 - should track program location properly', function() { | |
+ it('GH1024 - should track program location properly', function () { | |
var p = Handlebars.parse( | |
'\n' + | |
- ' {{#if foo}}\n' + | |
- ' {{bar}}\n' + | |
- ' {{else}} {{baz}}\n' + | |
- '\n' + | |
- ' {{/if}}\n' + | |
- ' ' | |
+ ' {{#if foo}}\n' + | |
+ ' {{bar}}\n' + | |
+ ' {{else}} {{baz}}\n' + | |
+ '\n' + | |
+ ' {{/if}}\n' + | |
+ ' ' | |
); | |
// We really need a deep equals but for now this should be stable... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/usr/bin/env bash | |
src=${1:-.} | |
dest=${2:-./out} | |
mkdir -p $dest | |
for x in basic blocks builtins data helpers javascript-compiler partials regressions security strict string-params subexpressions track-ids utils whitespace-control; do | |
node convert.js $src/$x.js > tmp.js | |
mv tmp.js $dest/$x.js | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment