Remove deprecated helpers and fix release script (#2128)

* Remove deprecated helpers
* Use more idiomatic assertions
* Fix release script
This commit is contained in:
Igor Savin
2026-03-03 22:52:28 +02:00
committed by GitHub
parent d65683434d
commit 169ef75066
18 changed files with 340 additions and 543 deletions
+1 -1
View File
@@ -76,7 +76,7 @@
"scripts": { "scripts": {
"build": "grunt build", "build": "grunt build",
"release": "grunt release", "release": "grunt release",
"publish:aws": "npm run test:tasks && grunt && grunt publish-to-aws", "publish:aws": "grunt && npm run test:tasks && grunt publish-to-aws",
"format": "prettier --write '**/*.{js,css,json,md}' && eslint --fix .", "format": "prettier --write '**/*.{js,css,json,md}' && eslint --fix .",
"lint": "npm run lint:eslint && npm run lint:prettier && npm run lint:types", "lint": "npm run lint:eslint && npm run lint:prettier && npm run lint:types",
"lint:eslint": "eslint --max-warnings 0 .", "lint:eslint": "eslint --max-warnings 0 .",
-6
View File
@@ -3,14 +3,8 @@ module.exports = {
CompilerContext: true, CompilerContext: true,
Handlebars: true, Handlebars: true,
handlebarsEnv: true, handlebarsEnv: true,
shouldCompileTo: true,
shouldCompileToWithPartials: true,
shouldThrow: true,
expectTemplate: true, expectTemplate: true,
compileWithPartials: true,
suite: true, suite: true,
equal: true,
equals: true,
test: true, test: true,
testBoth: true, testBoth: true,
raises: true, raises: true,
+51 -53
View File
@@ -7,102 +7,100 @@ describe('ast', function () {
describe('BlockStatement', function () { describe('BlockStatement', function () {
it('should throw on mustache mismatch', function () { it('should throw on mustache mismatch', function () {
shouldThrow( expect(function () {
function () { handlebarsEnv.parse('\n {{#foo}}{{/bar}}');
handlebarsEnv.parse('\n {{#foo}}{{/bar}}'); }).toThrow("foo doesn't match bar - 2:5");
},
Handlebars.Exception,
"foo doesn't match bar - 2:5"
);
}); });
}); });
describe('helpers', function () { describe('helpers', function () {
describe('#helperExpression', function () { describe('#helperExpression', function () {
it('should handle mustache statements', function () { it('should handle mustache statements', function () {
equals( expect(
AST.helpers.helperExpression({ AST.helpers.helperExpression({
type: 'MustacheStatement', type: 'MustacheStatement',
params: [], params: [],
hash: undefined, hash: undefined,
}), })
false ).toBe(false);
); expect(
equals(
AST.helpers.helperExpression({ AST.helpers.helperExpression({
type: 'MustacheStatement', type: 'MustacheStatement',
params: [1], params: [1],
hash: undefined, hash: undefined,
}), })
true ).toBe(true);
); expect(
equals(
AST.helpers.helperExpression({ AST.helpers.helperExpression({
type: 'MustacheStatement', type: 'MustacheStatement',
params: [], params: [],
hash: {}, hash: {},
}), })
true ).toBe(true);
);
}); });
it('should handle block statements', function () { it('should handle block statements', function () {
equals( expect(
AST.helpers.helperExpression({ AST.helpers.helperExpression({
type: 'BlockStatement', type: 'BlockStatement',
params: [], params: [],
hash: undefined, hash: undefined,
}), })
false ).toBe(false);
); expect(
equals(
AST.helpers.helperExpression({ AST.helpers.helperExpression({
type: 'BlockStatement', type: 'BlockStatement',
params: [1], params: [1],
hash: undefined, hash: undefined,
}), })
true ).toBe(true);
); expect(
equals(
AST.helpers.helperExpression({ AST.helpers.helperExpression({
type: 'BlockStatement', type: 'BlockStatement',
params: [], params: [],
hash: {}, hash: {},
}), })
).toBe(true);
});
it('should handle subexpressions', function () {
expect(AST.helpers.helperExpression({ type: 'SubExpression' })).toBe(
true true
); );
}); });
it('should handle subexpressions', function () {
equals(AST.helpers.helperExpression({ type: 'SubExpression' }), true);
});
it('should work with non-helper nodes', function () { it('should work with non-helper nodes', function () {
equals(AST.helpers.helperExpression({ type: 'Program' }), false); expect(AST.helpers.helperExpression({ type: 'Program' })).toBe(false);
equals( expect(AST.helpers.helperExpression({ type: 'PartialStatement' })).toBe(
AST.helpers.helperExpression({ type: 'PartialStatement' }),
false false
); );
equals( expect(AST.helpers.helperExpression({ type: 'ContentStatement' })).toBe(
AST.helpers.helperExpression({ type: 'ContentStatement' }),
false false
); );
equals( expect(AST.helpers.helperExpression({ type: 'CommentStatement' })).toBe(
AST.helpers.helperExpression({ type: 'CommentStatement' }),
false false
); );
equals(AST.helpers.helperExpression({ type: 'PathExpression' }), false); expect(AST.helpers.helperExpression({ type: 'PathExpression' })).toBe(
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 false
); );
equals(AST.helpers.helperExpression({ type: 'NullLiteral' }), false);
equals(AST.helpers.helperExpression({ type: 'Hash' }), false); expect(AST.helpers.helperExpression({ type: 'StringLiteral' })).toBe(
equals(AST.helpers.helperExpression({ type: 'HashPair' }), false); false
);
expect(AST.helpers.helperExpression({ type: 'NumberLiteral' })).toBe(
false
);
expect(AST.helpers.helperExpression({ type: 'BooleanLiteral' })).toBe(
false
);
expect(AST.helpers.helperExpression({ type: 'UndefinedLiteral' })).toBe(
false
);
expect(AST.helpers.helperExpression({ type: 'NullLiteral' })).toBe(
false
);
expect(AST.helpers.helperExpression({ type: 'Hash' })).toBe(false);
expect(AST.helpers.helperExpression({ type: 'HashPair' })).toBe(false);
}); });
}); });
}); });
@@ -111,10 +109,10 @@ describe('ast', function () {
var ast, body; var ast, body;
function testColumns(node, firstLine, lastLine, firstColumn, lastColumn) { function testColumns(node, firstLine, lastLine, firstColumn, lastColumn) {
equals(node.loc.start.line, firstLine); expect(node.loc.start.line).toBe(firstLine);
equals(node.loc.start.column, firstColumn); expect(node.loc.start.column).toBe(firstColumn);
equals(node.loc.end.line, lastLine); expect(node.loc.end.line).toBe(lastLine);
equals(node.loc.end.column, lastColumn); expect(node.loc.end.column).toBe(lastColumn);
} }
/* eslint-disable no-multi-spaces */ /* eslint-disable no-multi-spaces */
+22 -26
View File
@@ -381,26 +381,26 @@ describe('blocks', function () {
var run; var run;
expectTemplate('{{*decorator "success"}}') expectTemplate('{{*decorator "success"}}')
.withDecorator('decorator', function (fn, props, container, options) { .withDecorator('decorator', function (fn, props, container, options) {
equals(options.args[0], 'success'); expect(options.args[0]).toBe('success');
run = true; run = true;
return fn; return fn;
}) })
.withInput({ foo: 'success' }) .withInput({ foo: 'success' })
.toCompileTo(''); .toCompileTo('');
equals(run, true); expect(run).toBe(true);
}); });
it('should fail when accessing variables from root', function () { it('should fail when accessing variables from root', function () {
var run; var run;
expectTemplate('{{*decorator foo}}') expectTemplate('{{*decorator foo}}')
.withDecorator('decorator', function (fn, props, container, options) { .withDecorator('decorator', function (fn, props, container, options) {
equals(options.args[0], undefined); expect(options.args[0]).toBeUndefined();
run = true; run = true;
return fn; return fn;
}) })
.withInput({ foo: 'fail' }) .withInput({ foo: 'fail' })
.toCompileTo(''); .toCompileTo('');
equals(run, true); expect(run).toBe(true);
}); });
describe('registration', function () { describe('registration', function () {
@@ -411,9 +411,9 @@ describe('blocks', function () {
return 'fail'; return 'fail';
}); });
equals(!!handlebarsEnv.decorators.foo, true); expect(handlebarsEnv.decorators.foo).toBeTruthy();
handlebarsEnv.unregisterDecorator('foo'); handlebarsEnv.unregisterDecorator('foo');
equals(handlebarsEnv.decorators.foo, undefined); expect(handlebarsEnv.decorators.foo).toBeUndefined();
}); });
it('allows multiple globals', function () { it('allows multiple globals', function () {
@@ -424,32 +424,28 @@ describe('blocks', function () {
bar: function () {}, bar: function () {},
}); });
equals(!!handlebarsEnv.decorators.foo, true); expect(handlebarsEnv.decorators.foo).toBeTruthy();
equals(!!handlebarsEnv.decorators.bar, true); expect(handlebarsEnv.decorators.bar).toBeTruthy();
handlebarsEnv.unregisterDecorator('foo'); handlebarsEnv.unregisterDecorator('foo');
handlebarsEnv.unregisterDecorator('bar'); handlebarsEnv.unregisterDecorator('bar');
equals(handlebarsEnv.decorators.foo, undefined); expect(handlebarsEnv.decorators.foo).toBeUndefined();
equals(handlebarsEnv.decorators.bar, undefined); expect(handlebarsEnv.decorators.bar).toBeUndefined();
}); });
it('fails with multiple and args', function () { it('fails with multiple and args', function () {
shouldThrow( expect(function () {
function () { handlebarsEnv.registerDecorator(
handlebarsEnv.registerDecorator( {
{ world: function () {
world: function () { return 'world!';
return 'world!';
},
testHelper: function () {
return 'found it!';
},
}, },
{} testHelper: function () {
); return 'found it!';
}, },
Error, },
'Arg not supported with multiple decorators' {}
); );
}).toThrow('Arg not supported with multiple decorators');
}); });
}); });
}); });
+23 -27
View File
@@ -257,17 +257,13 @@ describe('builtin helpers', function () {
// Object property iteration order is undefined according to ECMA spec, // Object property iteration order is undefined according to ECMA spec,
// so we need to check both possible orders // so we need to check both possible orders
// @see http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop // @see http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop
var actual = compileWithPartials(string, hash); var actual = CompilerContext.compile(string)(hash);
var expected1 = var expected1 =
'<b>#1</b>. goodbye! 2. GOODBYE! cruel world!'; '<b>#1</b>. goodbye! 2. GOODBYE! cruel world!';
var expected2 = var expected2 =
'2. GOODBYE! <b>#1</b>. goodbye! cruel world!'; '2. GOODBYE! <b>#1</b>. goodbye! cruel world!';
equals( expect([expected1, expected2]).toContain(actual);
actual === expected1 || actual === expected2,
true,
'each with object argument iterates over the contents when not empty'
);
expectTemplate(string) expectTemplate(string)
.withInput({ .withInput({
@@ -630,8 +626,8 @@ describe('builtin helpers', function () {
.withInput({ blah: 'whee' }) .withInput({ blah: 'whee' })
.withMessage('log should not display') .withMessage('log should not display')
.toCompileTo(''); .toCompileTo('');
equals(1, levelArg, 'should call log with 1'); expect(levelArg).toBe(1);
equals('whee', logArg, "should call log with 'whee'"); expect(logArg).toBe('whee');
}); });
it('should call logger at data level', function () { it('should call logger at data level', function () {
@@ -646,21 +642,21 @@ describe('builtin helpers', function () {
.withRuntimeOptions({ data: { level: '03' } }) .withRuntimeOptions({ data: { level: '03' } })
.withCompileOptions({ data: true }) .withCompileOptions({ data: true })
.toCompileTo(''); .toCompileTo('');
equals('03', levelArg); expect(levelArg).toBe('03');
equals('whee', logArg); expect(logArg).toBe('whee');
}); });
it('should output to info', function () { it('should output to info', function () {
var called; var called;
console.info = function (info) { console.info = function (info) {
equals('whee', info); expect(info).toBe('whee');
called = true; called = true;
console.info = $info; console.info = $info;
console.log = $log; console.log = $log;
}; };
console.log = function (log) { console.log = function (log) {
equals('whee', log); expect(log).toBe('whee');
called = true; called = true;
console.info = $info; console.info = $info;
console.log = $log; console.log = $log;
@@ -669,14 +665,14 @@ describe('builtin helpers', function () {
expectTemplate('{{log blah}}') expectTemplate('{{log blah}}')
.withInput({ blah: 'whee' }) .withInput({ blah: 'whee' })
.toCompileTo(''); .toCompileTo('');
equals(true, called); expect(called).toBe(true);
}); });
it('should log at data level', function () { it('should log at data level', function () {
var called; var called;
console.error = function (log) { console.error = function (log) {
equals('whee', log); expect(log).toBe('whee');
called = true; called = true;
console.error = $error; console.error = $error;
}; };
@@ -686,7 +682,7 @@ describe('builtin helpers', function () {
.withRuntimeOptions({ data: { level: '03' } }) .withRuntimeOptions({ data: { level: '03' } })
.withCompileOptions({ data: true }) .withCompileOptions({ data: true })
.toCompileTo(''); .toCompileTo('');
equals(true, called); expect(called).toBe(true);
}); });
it('should handle missing logger', function () { it('should handle missing logger', function () {
@@ -694,7 +690,7 @@ describe('builtin helpers', function () {
console.error = undefined; console.error = undefined;
console.log = function (log) { console.log = function (log) {
equals('whee', log); expect(log).toBe('whee');
called = true; called = true;
console.log = $log; console.log = $log;
}; };
@@ -704,14 +700,14 @@ describe('builtin helpers', function () {
.withRuntimeOptions({ data: { level: '03' } }) .withRuntimeOptions({ data: { level: '03' } })
.withCompileOptions({ data: true }) .withCompileOptions({ data: true })
.toCompileTo(''); .toCompileTo('');
equals(true, called); expect(called).toBe(true);
}); });
it('should handle string log levels', function () { it('should handle string log levels', function () {
var called; var called;
console.error = function (log) { console.error = function (log) {
equals('whee', log); expect(log).toBe('whee');
called = true; called = true;
}; };
@@ -720,7 +716,7 @@ describe('builtin helpers', function () {
.withRuntimeOptions({ data: { level: 'error' } }) .withRuntimeOptions({ data: { level: 'error' } })
.withCompileOptions({ data: true }) .withCompileOptions({ data: true })
.toCompileTo(''); .toCompileTo('');
equals(true, called); expect(called).toBe(true);
called = false; called = false;
@@ -729,21 +725,21 @@ describe('builtin helpers', function () {
.withRuntimeOptions({ data: { level: 'ERROR' } }) .withRuntimeOptions({ data: { level: 'ERROR' } })
.withCompileOptions({ data: true }) .withCompileOptions({ data: true })
.toCompileTo(''); .toCompileTo('');
equals(true, called); expect(called).toBe(true);
}); });
it('should handle hash log levels', function () { it('should handle hash log levels', function () {
var called; var called;
console.error = function (log) { console.error = function (log) {
equals('whee', log); expect(log).toBe('whee');
called = true; called = true;
}; };
expectTemplate('{{log blah level="error"}}') expectTemplate('{{log blah level="error"}}')
.withInput({ blah: 'whee' }) .withInput({ blah: 'whee' })
.toCompileTo(''); .toCompileTo('');
equals(true, called); expect(called).toBe(true);
}); });
it('should handle hash log levels', function () { it('should handle hash log levels', function () {
@@ -761,16 +757,16 @@ describe('builtin helpers', function () {
expectTemplate('{{log blah level="debug"}}') expectTemplate('{{log blah level="debug"}}')
.withInput({ blah: 'whee' }) .withInput({ blah: 'whee' })
.toCompileTo(''); .toCompileTo('');
equals(false, called); expect(called).toBe(false);
}); });
it('should pass multiple log arguments', function () { it('should pass multiple log arguments', function () {
var called; var called;
console.info = console.log = function (log1, log2, log3) { console.info = console.log = function (log1, log2, log3) {
equals('whee', log1); expect(log1).toBe('whee');
equals('foo', log2); expect(log2).toBe('foo');
equals(1, log3); expect(log3).toBe(1);
called = true; called = true;
console.log = $log; console.log = $log;
}; };
@@ -778,7 +774,7 @@ describe('builtin helpers', function () {
expectTemplate('{{log blah "foo" 1}}') expectTemplate('{{log blah "foo" 1}}')
.withInput({ blah: 'whee' }) .withInput({ blah: 'whee' })
.toCompileTo(''); .toCompileTo('');
equals(true, called); expect(called).toBe(true);
}); });
it('should pass zero log arguments', function () { it('should pass zero log arguments', function () {
+65 -110
View File
@@ -10,69 +10,56 @@ describe('compiler', function () {
} }
it('should treat as equal', function () { it('should treat as equal', function () {
equal(compile('foo').equals(compile('foo')), true); expect(compile('foo').equals(compile('foo'))).toBe(true);
equal(compile('{{foo}}').equals(compile('{{foo}}')), true); expect(compile('{{foo}}').equals(compile('{{foo}}'))).toBe(true);
equal(compile('{{foo.bar}}').equals(compile('{{foo.bar}}')), true); expect(compile('{{foo.bar}}').equals(compile('{{foo.bar}}'))).toBe(true);
equal( expect(
compile('{{foo.bar baz "foo" true false bat=1}}').equals( compile('{{foo.bar baz "foo" true false bat=1}}').equals(
compile('{{foo.bar baz "foo" true false bat=1}}') compile('{{foo.bar baz "foo" true false bat=1}}')
), )
true ).toBe(true);
); expect(
equal(
compile('{{foo.bar (baz bat=1)}}').equals( compile('{{foo.bar (baz bat=1)}}').equals(
compile('{{foo.bar (baz bat=1)}}') compile('{{foo.bar (baz bat=1)}}')
), )
true ).toBe(true);
); expect(
equal( compile('{{#foo}} {{/foo}}').equals(compile('{{#foo}} {{/foo}}'))
compile('{{#foo}} {{/foo}}').equals(compile('{{#foo}} {{/foo}}')), ).toBe(true);
true
);
}); });
it('should treat as not equal', function () { it('should treat as not equal', function () {
equal(compile('foo').equals(compile('bar')), false); expect(compile('foo').equals(compile('bar'))).toBe(false);
equal(compile('{{foo}}').equals(compile('{{bar}}')), false); expect(compile('{{foo}}').equals(compile('{{bar}}'))).toBe(false);
equal(compile('{{foo.bar}}').equals(compile('{{bar.bar}}')), false); expect(compile('{{foo.bar}}').equals(compile('{{bar.bar}}'))).toBe(false);
equal( expect(
compile('{{foo.bar baz bat=1}}').equals( compile('{{foo.bar baz bat=1}}').equals(
compile('{{foo.bar bar bat=1}}') compile('{{foo.bar bar bat=1}}')
), )
false ).toBe(false);
); expect(
equal(
compile('{{foo.bar (baz bat=1)}}').equals( compile('{{foo.bar (baz bat=1)}}').equals(
compile('{{foo.bar (bar bat=1)}}') compile('{{foo.bar (bar bat=1)}}')
), )
false ).toBe(false);
); expect(
equal( compile('{{#foo}} {{/foo}}').equals(compile('{{#bar}} {{/bar}}'))
compile('{{#foo}} {{/foo}}').equals(compile('{{#bar}} {{/bar}}')), ).toBe(false);
false expect(
); compile('{{#foo}} {{/foo}}').equals(compile('{{#foo}} {{foo}}{{/foo}}'))
equal( ).toBe(false);
compile('{{#foo}} {{/foo}}').equals(
compile('{{#foo}} {{foo}}{{/foo}}')
),
false
);
}); });
}); });
describe('#compile', function () { describe('#compile', function () {
it('should fail with invalid input', function () { it('should fail with invalid input', function () {
shouldThrow( expect(function () {
function () { Handlebars.compile(null);
Handlebars.compile(null); }).toThrow(
},
Error,
'You must pass a string or Handlebars AST to Handlebars.compile. You passed null' 'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
); );
shouldThrow( expect(function () {
function () { Handlebars.compile({});
Handlebars.compile({}); }).toThrow(
},
Error,
'You must pass a string or Handlebars AST to Handlebars.compile. You passed [object Object]' 'You must pass a string or Handlebars AST to Handlebars.compile. You passed [object Object]'
); );
}); });
@@ -80,71 +67,52 @@ describe('compiler', function () {
it('should include the location in the error (row and column)', function () { it('should include the location in the error (row and column)', function () {
try { try {
Handlebars.compile(' \n {{#if}}\n{{/def}}')(); Handlebars.compile(' \n {{#if}}\n{{/def}}')();
equal( expect.unreachable('Statement must throw exception');
true,
false,
'Statement must throw exception. This line should not be executed.'
);
} catch (err) { } catch (err) {
equal( expect(err.message).toBe("if doesn't match def - 2:5");
err.message,
"if doesn't match def - 2:5",
'Checking error message'
);
if (Object.getOwnPropertyDescriptor(err, 'column').writable) { if (Object.getOwnPropertyDescriptor(err, 'column').writable) {
// In Safari 8, the column-property is read-only. This means that even if it is set with defineProperty, // In Safari 8, the column-property is read-only. This means that even if it is set with defineProperty,
// its value won't change (https://github.com/jquery/esprima/issues/1290#issuecomment-132455482) // its value won't change (https://github.com/jquery/esprima/issues/1290#issuecomment-132455482)
// Since this was neither working in Handlebars 3 nor in 4.0.5, we only check the column for other browsers. // Since this was neither working in Handlebars 3 nor in 4.0.5, we only check the column for other browsers.
equal(err.column, 5, 'Checking error column'); expect(err.column).toBe(5);
} }
equal(err.lineNumber, 2, 'Checking error row'); expect(err.lineNumber).toBe(2);
} }
}); });
it('should include the location as enumerable property', function () { it('should include the location as enumerable property', function () {
try { try {
Handlebars.compile(' \n {{#if}}\n{{/def}}')(); Handlebars.compile(' \n {{#if}}\n{{/def}}')();
equal( expect.unreachable('Statement must throw exception');
true,
false,
'Statement must throw exception. This line should not be executed.'
);
} catch (err) { } catch (err) {
equal( expect(Object.prototype.propertyIsEnumerable.call(err, 'column')).toBe(
Object.prototype.propertyIsEnumerable.call(err, 'column'), true
true,
'Checking error column'
); );
} }
}); });
it('can utilize AST instance', function () { it('can utilize AST instance', function () {
equal( expect(
Handlebars.compile({ Handlebars.compile({
type: 'Program', type: 'Program',
body: [{ type: 'ContentStatement', value: 'Hello' }], body: [{ type: 'ContentStatement', value: 'Hello' }],
})(), })()
'Hello' ).toBe('Hello');
);
}); });
it('can pass through an empty string', function () { it('can pass through an empty string', function () {
equal(Handlebars.compile('')(), ''); expect(Handlebars.compile('')()).toBe('');
}); });
it('throws on desupported options', function () { it('throws on desupported options', function () {
shouldThrow( expect(function () {
function () { Handlebars.compile('Dudes', { trackIds: true });
Handlebars.compile('Dudes', { trackIds: true }); }).toThrow(
},
Error,
'TrackIds and stringParams are no longer supported. See Github #1145' 'TrackIds and stringParams are no longer supported. See Github #1145'
); );
shouldThrow( expect(function () {
function () { Handlebars.compile('Dudes', { stringParams: true });
Handlebars.compile('Dudes', { stringParams: true }); }).toThrow(
},
Error,
'TrackIds and stringParams are no longer supported. See Github #1145' 'TrackIds and stringParams are no longer supported. See Github #1145'
); );
}); });
@@ -152,54 +120,41 @@ describe('compiler', function () {
it('should not modify the options.data property(GH-1327)', function () { it('should not modify the options.data property(GH-1327)', function () {
var options = { data: [{ a: 'foo' }, { a: 'bar' }] }; var options = { data: [{ a: 'foo' }, { a: 'bar' }] };
Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)(); Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
equal( expect(options).toStrictEqual({ data: [{ a: 'foo' }, { a: 'bar' }] });
JSON.stringify(options, 0, 2),
JSON.stringify({ data: [{ a: 'foo' }, { a: 'bar' }] }, 0, 2)
);
}); });
it('should not modify the options.knownHelpers property(GH-1327)', function () { it('should not modify the options.knownHelpers property(GH-1327)', function () {
var options = { knownHelpers: {} }; var options = { knownHelpers: {} };
Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)(); Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
equal( expect(options).toStrictEqual({ knownHelpers: {} });
JSON.stringify(options, 0, 2),
JSON.stringify({ knownHelpers: {} }, 0, 2)
);
}); });
}); });
describe('#precompile', function () { describe('#precompile', function () {
it('should fail with invalid input', function () { it('should fail with invalid input', function () {
shouldThrow( expect(function () {
function () { Handlebars.precompile(null);
Handlebars.precompile(null); }).toThrow(
},
Error,
'You must pass a string or Handlebars AST to Handlebars.compile. You passed null' 'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
); );
shouldThrow( expect(function () {
function () { Handlebars.precompile({});
Handlebars.precompile({}); }).toThrow(
},
Error,
'You must pass a string or Handlebars AST to Handlebars.compile. You passed [object Object]' 'You must pass a string or Handlebars AST to Handlebars.compile. You passed [object Object]'
); );
}); });
it('can utilize AST instance', function () { it('can utilize AST instance', function () {
equal( expect(
/return "Hello"/.test( Handlebars.precompile({
Handlebars.precompile({ type: 'Program',
type: 'Program', body: [{ type: 'ContentStatement', value: 'Hello' }],
body: [{ type: 'ContentStatement', value: 'Hello' }], })
}) ).toMatch(/return "Hello"/);
),
true
);
}); });
it('can pass through an empty string', function () { it('can pass through an empty string', function () {
equal(/return ""/.test(Handlebars.precompile('')), true); expect(Handlebars.precompile('')).toMatch(/return ""/);
}); });
}); });
}); });
-91
View File
@@ -1,96 +1,5 @@
var global = globalThis; var global = globalThis;
/**
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
*/
global.shouldCompileTo = function (string, hashOrArray, expected, message) {
shouldCompileToWithPartials(string, hashOrArray, false, expected, message);
};
/**
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
*/
global.shouldCompileToWithPartials = function shouldCompileToWithPartials(
string,
hashOrArray,
partials,
expected,
message // eslint-disable-line no-unused-vars
) {
var result = compileWithPartials(string, hashOrArray, partials);
expect(result).toBe(expected);
};
/**
* @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
*/
global.compileWithPartials = function (string, hashOrArray, partials) {
var template, ary, options;
if (hashOrArray && hashOrArray.hash) {
ary = [hashOrArray.hash, hashOrArray];
delete hashOrArray.hash;
} else if (Object.prototype.toString.call(hashOrArray) === '[object Array]') {
ary = [];
ary.push(hashOrArray[0]); // input
ary.push({ helpers: hashOrArray[1], partials: hashOrArray[2] });
options =
typeof hashOrArray[3] === 'object'
? hashOrArray[3]
: { compat: hashOrArray[3] };
if (hashOrArray[4] != null) {
options.data = !!hashOrArray[4];
ary[1].data = hashOrArray[4];
}
} else {
ary = [hashOrArray];
}
template = CompilerContext[partials ? 'compileWithPartial' : 'compile'](
string,
options
);
return template.apply(this, ary);
};
/**
* @deprecated Use vitest's expect API instead
*/
// eslint-disable-next-line no-unused-vars
global.equals = global.equal = function equals(a, b, msg) {
expect(a).toBe(b);
};
/**
* @deprecated Use vitest's expect API instead
*/
global.shouldThrow = function (callback, type, msg) {
var failed;
try {
callback();
failed = true;
} catch (caught) {
if (type && !(caught instanceof type)) {
throw new Error('Type failure: ' + caught);
}
if (
msg &&
!(msg.test ? msg.test(caught.message) : msg === caught.message)
) {
throw new Error(
'Throw mismatch: Expected ' +
caught.message +
' to match ' +
msg +
'\n\n' +
caught.stack
);
}
}
if (failed) {
throw new Error('It failed to throw');
}
};
global.expectTemplate = function (templateAsString) { global.expectTemplate = function (templateAsString) {
return new HandlebarsTestBench(templateAsString); return new HandlebarsTestBench(templateAsString);
}; };
+17 -21
View File
@@ -392,7 +392,7 @@ describe('helpers', function () {
return 'fail'; return 'fail';
}); });
handlebarsEnv.unregisterHelper('foo'); handlebarsEnv.unregisterHelper('foo');
equals(handlebarsEnv.helpers.foo, undefined); expect(handlebarsEnv.helpers.foo).toBeUndefined();
}); });
it('allows multiple globals', function () { it('allows multiple globals', function () {
@@ -417,23 +417,19 @@ describe('helpers', function () {
}); });
it('fails with multiple and args', function () { it('fails with multiple and args', function () {
shouldThrow( expect(function () {
function () { handlebarsEnv.registerHelper(
handlebarsEnv.registerHelper( {
{ world: function () {
world: function () { return 'world!';
return 'world!';
},
testHelper: function () {
return 'found it!';
},
}, },
{} testHelper: function () {
); return 'found it!';
}, },
Error, },
'Arg not supported with multiple helpers' {}
); );
}).toThrow('Arg not supported with multiple helpers');
}); });
}); });
@@ -920,7 +916,7 @@ describe('helpers', function () {
expectTemplate('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}') expectTemplate('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}')
.withInput({ value: 'foo' }) .withInput({ value: 'foo' })
.withHelper('goodbyes', function (options) { .withHelper('goodbyes', function (options) {
equals(options.fn.blockParams, 1); expect(options.fn.blockParams).toBe(1);
return options.fn({ value: 'bar' }, { blockParams: [1, 2] }); return options.fn({ value: 'bar' }, { blockParams: [1, 2] });
}) })
.toCompileTo('1foo'); .toCompileTo('1foo');
@@ -932,7 +928,7 @@ describe('helpers', function () {
return 'foo'; return 'foo';
}) })
.withHelper('goodbyes', function (options) { .withHelper('goodbyes', function (options) {
equals(options.fn.blockParams, 1); expect(options.fn.blockParams).toBe(1);
return options.fn({}, { blockParams: [1, 2] }); return options.fn({}, { blockParams: [1, 2] });
}) })
.toCompileTo('1foo'); .toCompileTo('1foo');
@@ -947,7 +943,7 @@ describe('helpers', function () {
return 'foo'; return 'foo';
}) })
.withHelper('goodbyes', function (options) { .withHelper('goodbyes', function (options) {
equals(options.fn.blockParams, 1); expect(options.fn.blockParams).toBe(1);
return options.fn(this, { blockParams: [1, 2] }); return options.fn(this, { blockParams: [1, 2] });
}) })
.toCompileTo('barfoo'); .toCompileTo('barfoo');
@@ -977,7 +973,7 @@ describe('helpers', function () {
) )
.withInput({ value: 'foo' }) .withInput({ value: 'foo' })
.withHelper('goodbyes', function (options) { .withHelper('goodbyes', function (options) {
equals(options.fn.blockParams, 1); expect(options.fn.blockParams).toBe(1);
return options.fn({ value: 'bar' }, { blockParams: [1, 2] }); return options.fn({ value: 'bar' }, { blockParams: [1, 2] });
}) })
.toCompileTo('1foo'); .toCompileTo('1foo');
+6 -8
View File
@@ -164,12 +164,10 @@ describe('partials', function () {
}); });
it('registering undefined partial throws an exception', function () { it('registering undefined partial throws an exception', function () {
shouldThrow( expect(function () {
function () { var undef;
var undef; handlebarsEnv.registerPartial('undefined_test', undef);
handlebarsEnv.registerPartial('undefined_test', undef); }).toThrow(
},
Handlebars.Exception,
'Attempting to register a partial called "undefined_test" as undefined' 'Attempting to register a partial called "undefined_test" as undefined'
); );
}); });
@@ -231,7 +229,7 @@ describe('partials', function () {
.toCompileTo('Dudes: Jeepers Creepers'); .toCompileTo('Dudes: Jeepers Creepers');
handlebarsEnv.unregisterPartial('globalTest'); handlebarsEnv.unregisterPartial('globalTest');
equals(handlebarsEnv.partials.globalTest, undefined); expect(handlebarsEnv.partials.globalTest).toBeUndefined();
}); });
it('Multiple partial registration', function () { it('Multiple partial registration', function () {
@@ -556,7 +554,7 @@ describe('partials', function () {
var env = Handlebars.create(); var env = Handlebars.create();
env.registerPartial('partial', '{{foo}}'); env.registerPartial('partial', '{{foo}}');
var template = env.compile('{{foo}} {{> partial}}', { noEscape: true }); var template = env.compile('{{foo}} {{> partial}}', { noEscape: true });
equal(template({ foo: '<' }), '< <'); expect(template({ foo: '<' })).toBe('< <');
} }
}); });
+73 -98
View File
@@ -85,62 +85,42 @@ describe('precompiler', function () {
it('should output version', function () { it('should output version', function () {
Precompiler.cli({ templates: [], version: true }); Precompiler.cli({ templates: [], version: true });
equals(log, Handlebars.VERSION); expect(log).toBe(Handlebars.VERSION);
}); });
it('should throw if lacking templates', function () { it('should throw if lacking templates', function () {
shouldThrow( expect(function () {
function () { Precompiler.cli({ templates: [] });
Precompiler.cli({ templates: [] }); }).toThrow('Must define at least one template or directory.');
},
Handlebars.Exception,
'Must define at least one template or directory.'
);
}); });
it('should handle empty/filtered directories', function () { it('should handle empty/filtered directories', function () {
Precompiler.cli({ hasDirectory: true, templates: [] }); Precompiler.cli({ hasDirectory: true, templates: [] });
// Success is not throwing // Success is not throwing
}); });
it('should throw when combining simple and minimized', function () { it('should throw when combining simple and minimized', function () {
shouldThrow( expect(function () {
function () { Precompiler.cli({ templates: [__dirname], simple: true, min: true });
Precompiler.cli({ templates: [__dirname], simple: true, min: true }); }).toThrow('Unable to minimize simple output');
},
Handlebars.Exception,
'Unable to minimize simple output'
);
}); });
it('should throw when combining simple and multiple templates', function () { it('should throw when combining simple and multiple templates', function () {
shouldThrow( expect(function () {
function () { Precompiler.cli({
Precompiler.cli({ templates: [
templates: [ __dirname + '/artifacts/empty.handlebars',
__dirname + '/artifacts/empty.handlebars', __dirname + '/artifacts/empty.handlebars',
__dirname + '/artifacts/empty.handlebars', ],
], simple: true,
simple: true, });
}); }).toThrow('Unable to output multiple templates in simple mode');
},
Handlebars.Exception,
'Unable to output multiple templates in simple mode'
);
}); });
it('should throw when missing name', function () { it('should throw when missing name', function () {
shouldThrow( expect(function () {
function () { Precompiler.cli({ templates: [{ source: '' }], amd: true });
Precompiler.cli({ templates: [{ source: '' }], amd: true }); }).toThrow('Name missing for template');
},
Handlebars.Exception,
'Name missing for template'
);
}); });
it('should throw when combining simple and directories', function () { it('should throw when combining simple and directories', function () {
shouldThrow( expect(function () {
function () { Precompiler.cli({ hasDirectory: true, templates: [1], simple: true });
Precompiler.cli({ hasDirectory: true, templates: [1], simple: true }); }).toThrow('Unable to output multiple templates in simple mode');
},
Handlebars.Exception,
'Unable to output multiple templates in simple mode'
);
}); });
it('should output simple templates', function () { it('should output simple templates', function () {
@@ -148,21 +128,21 @@ describe('precompiler', function () {
return 'simple'; return 'simple';
}; };
Precompiler.cli({ templates: [emptyTemplate], simple: true }); Precompiler.cli({ templates: [emptyTemplate], simple: true });
equal(log, 'simple\n'); expect(log).toBe('simple\n');
}); });
it('should default to simple templates', function () { it('should default to simple templates', function () {
Handlebars.precompile = function () { Handlebars.precompile = function () {
return 'simple'; return 'simple';
}; };
Precompiler.cli({ templates: [{ source: '' }] }); Precompiler.cli({ templates: [{ source: '' }] });
equal(log, 'simple\n'); expect(log).toBe('simple\n');
}); });
it('should output amd templates', function () { it('should output amd templates', function () {
Handlebars.precompile = function () { Handlebars.precompile = function () {
return 'amd'; return 'amd';
}; };
Precompiler.cli({ templates: [emptyTemplate], amd: true }); Precompiler.cli({ templates: [emptyTemplate], amd: true });
equal(/template\(amd\)/.test(log), true); expect(log).toMatch(/template\(amd\)/);
}); });
it('should output multiple amd', function () { it('should output multiple amd', function () {
Handlebars.precompile = function () { Handlebars.precompile = function () {
@@ -173,17 +153,17 @@ describe('precompiler', function () {
amd: true, amd: true,
namespace: 'foo', namespace: 'foo',
}); });
equal(/templates = foo = foo \|\|/.test(log), true); expect(log).toMatch(/templates = foo = foo \|\|/);
equal(/return templates/.test(log), true); expect(log).toMatch(/return templates/);
equal(/template\(amd\)/.test(log), true); expect(log).toMatch(/template\(amd\)/);
}); });
it('should output amd partials', function () { it('should output amd partials', function () {
Handlebars.precompile = function () { Handlebars.precompile = function () {
return 'amd'; return 'amd';
}; };
Precompiler.cli({ templates: [emptyTemplate], amd: true, partial: true }); Precompiler.cli({ templates: [emptyTemplate], amd: true, partial: true });
equal(/return Handlebars\.partials\['empty'\]/.test(log), true); expect(log).toMatch(/return Handlebars\.partials\['empty'\]/);
equal(/template\(amd\)/.test(log), true); expect(log).toMatch(/template\(amd\)/);
}); });
it('should output multiple amd partials', function () { it('should output multiple amd partials', function () {
Handlebars.precompile = function () { Handlebars.precompile = function () {
@@ -194,33 +174,33 @@ describe('precompiler', function () {
amd: true, amd: true,
partial: true, partial: true,
}); });
equal(/return Handlebars\.partials\[/.test(log), false); expect(log).not.toMatch(/return Handlebars\.partials\[/);
equal(/template\(amd\)/.test(log), true); expect(log).toMatch(/template\(amd\)/);
}); });
it('should output commonjs templates', function () { it('should output commonjs templates', function () {
Handlebars.precompile = function () { Handlebars.precompile = function () {
return 'commonjs'; return 'commonjs';
}; };
Precompiler.cli({ templates: [emptyTemplate], commonjs: true }); Precompiler.cli({ templates: [emptyTemplate], commonjs: true });
equal(/template\(commonjs\)/.test(log), true); expect(log).toMatch(/template\(commonjs\)/);
}); });
it('should set data flag', function () { it('should set data flag', function () {
Handlebars.precompile = function (data, options) { Handlebars.precompile = function (data, options) {
equal(options.data, true); expect(options.data).toBe(true);
return 'simple'; return 'simple';
}; };
Precompiler.cli({ templates: [emptyTemplate], simple: true, data: true }); Precompiler.cli({ templates: [emptyTemplate], simple: true, data: true });
equal(log, 'simple\n'); expect(log).toBe('simple\n');
}); });
it('should set known helpers', function () { it('should set known helpers', function () {
Handlebars.precompile = function (data, options) { Handlebars.precompile = function (data, options) {
equal(options.knownHelpers.foo, true); expect(options.knownHelpers.foo).toBe(true);
return 'simple'; return 'simple';
}; };
Precompiler.cli({ templates: [emptyTemplate], simple: true, known: 'foo' }); Precompiler.cli({ templates: [emptyTemplate], simple: true, known: 'foo' });
equal(log, 'simple\n'); expect(log).toBe('simple\n');
}); });
it('should output to file system', function () { it('should output to file system', function () {
Handlebars.precompile = function () { Handlebars.precompile = function () {
@@ -231,9 +211,9 @@ describe('precompiler', function () {
simple: true, simple: true,
output: 'file!', output: 'file!',
}); });
equal(file, 'file!'); expect(file).toBe('file!');
equal(content, 'simple\n'); expect(content).toBe('simple\n');
equal(log, ''); expect(log).toBe('');
}); });
it('should output minimized templates', function () { it('should output minimized templates', function () {
@@ -244,7 +224,7 @@ describe('precompiler', function () {
return { code: 'min' }; return { code: 'min' };
}; };
Precompiler.cli({ templates: [emptyTemplate], min: true }); Precompiler.cli({ templates: [emptyTemplate], min: true });
equal(log, 'min'); expect(log).toBe('min');
}); });
it('should omit minimization gracefully, if uglify-js is missing', function () { it('should omit minimization gracefully, if uglify-js is missing', function () {
@@ -256,33 +236,29 @@ describe('precompiler', function () {
return 'amd'; return 'amd';
}; };
Precompiler.cli({ templates: [emptyTemplate], min: true }); Precompiler.cli({ templates: [emptyTemplate], min: true });
equal(/template\(amd\)/.test(log), true); expect(log).toMatch(/template\(amd\)/);
equal(/\n/.test(log), true); expect(log).toMatch(/\n/);
equal(/Code minimization is disabled/.test(errorLog), true); expect(errorLog).toMatch(/Code minimization is disabled/);
}); });
}); });
it('should fail on errors (other than missing module) while loading uglify-js', function () { it('should fail on errors (other than missing module) while loading uglify-js', function () {
mockRequireUglify(new Error('Mock Error'), function () { mockRequireUglify(new Error('Mock Error'), function () {
shouldThrow( expect(function () {
function () { var Precompiler = require('../dist/cjs/precompiler');
var Precompiler = require('../dist/cjs/precompiler'); Handlebars.precompile = function () {
Handlebars.precompile = function () { return 'amd';
return 'amd'; };
}; Precompiler.cli({ templates: [emptyTemplate], min: true });
Precompiler.cli({ templates: [emptyTemplate], min: true }); }).toThrow('Mock Error');
},
Error,
'Mock Error'
);
}); });
}); });
it('should output map', function () { it('should output map', function () {
Precompiler.cli({ templates: [emptyTemplate], map: 'foo.js.map' }); Precompiler.cli({ templates: [emptyTemplate], map: 'foo.js.map' });
equal(file, 'foo.js.map'); expect(file).toBe('foo.js.map');
equal(log.match(/sourceMappingURL=/g).length, 1); expect(log.match(/sourceMappingURL=/g).length).toBe(1);
}); });
it('should output map', function () { it('should output map', function () {
@@ -292,8 +268,8 @@ describe('precompiler', function () {
map: 'foo.js.map', map: 'foo.js.map',
}); });
equal(file, 'foo.js.map'); expect(file).toBe('foo.js.map');
equal(log.match(/sourceMappingURL=/g).length, 1); expect(log.match(/sourceMappingURL=/g).length).toBe(1);
}); });
describe('#loadTemplates', function () { describe('#loadTemplates', function () {
@@ -315,7 +291,7 @@ describe('precompiler', function () {
await loadTemplatesAsync({ files: ['foo'] }); await loadTemplatesAsync({ files: ['foo'] });
throw new Error('should have thrown'); throw new Error('should have thrown');
} catch (err) { } catch (err) {
equal(err.message, 'Unable to open template file "foo"'); expect(err.message).toBe('Unable to open template file "foo"');
} }
}); });
it('should enumerate directories by extension', async function () { it('should enumerate directories by extension', async function () {
@@ -323,18 +299,18 @@ describe('precompiler', function () {
files: [__dirname + '/artifacts'], files: [__dirname + '/artifacts'],
extension: 'hbs', extension: 'hbs',
}); });
equal(opts.templates.length, 2); expect(opts.templates.length).toBe(2);
equal(opts.templates[0].name, 'example_2'); expect(opts.templates[0].name).toBe('example_2');
}); });
it('should enumerate all templates by extension', async function () { it('should enumerate all templates by extension', async function () {
var opts = await loadTemplatesAsync({ var opts = await loadTemplatesAsync({
files: [__dirname + '/artifacts'], files: [__dirname + '/artifacts'],
extension: 'handlebars', extension: 'handlebars',
}); });
equal(opts.templates.length, 5); expect(opts.templates.length).toBe(5);
equal(opts.templates[0].name, 'bom'); expect(opts.templates[0].name).toBe('bom');
equal(opts.templates[1].name, 'empty'); expect(opts.templates[1].name).toBe('empty');
equal(opts.templates[2].name, 'example_1'); expect(opts.templates[2].name).toBe('example_1');
}); });
it('should handle regular expression characters in extensions', async function () { it('should handle regular expression characters in extensions', async function () {
await loadTemplatesAsync({ await loadTemplatesAsync({
@@ -349,7 +325,7 @@ describe('precompiler', function () {
extension: 'handlebars', extension: 'handlebars',
bom: true, bom: true,
}); });
equal(opts.templates[0].source, 'a'); expect(opts.templates[0].source).toBe('a');
}); });
it('should handle different root', async function () { it('should handle different root', async function () {
@@ -358,23 +334,23 @@ describe('precompiler', function () {
simple: true, simple: true,
root: 'foo/', root: 'foo/',
}); });
equal(opts.templates[0].name, __dirname + '/artifacts/empty'); expect(opts.templates[0].name).toBe(__dirname + '/artifacts/empty');
}); });
it('should accept string inputs', async function () { it('should accept string inputs', async function () {
var opts = await loadTemplatesAsync({ string: '' }); var opts = await loadTemplatesAsync({ string: '' });
equal(opts.templates[0].name, undefined); expect(opts.templates[0].name).toBeUndefined();
equal(opts.templates[0].source, ''); expect(opts.templates[0].source).toBe('');
}); });
it('should accept string array inputs', async function () { it('should accept string array inputs', async function () {
var opts = await loadTemplatesAsync({ var opts = await loadTemplatesAsync({
string: ['', 'bar'], string: ['', 'bar'],
name: ['beep', 'boop'], name: ['beep', 'boop'],
}); });
equal(opts.templates[0].name, 'beep'); expect(opts.templates[0].name).toBe('beep');
equal(opts.templates[0].source, ''); expect(opts.templates[0].source).toBe('');
equal(opts.templates[1].name, 'boop'); expect(opts.templates[1].name).toBe('boop');
equal(opts.templates[1].source, 'bar'); expect(opts.templates[1].source).toBe('bar');
}); });
it('should accept stdin input', async function () { it('should accept stdin input', async function () {
var stdin = require('mock-stdin').stdin(); var stdin = require('mock-stdin').stdin();
@@ -383,15 +359,14 @@ describe('precompiler', function () {
stdin.send('o'); stdin.send('o');
stdin.end(); stdin.end();
var opts = await promise; var opts = await promise;
equal(opts.templates[0].source, 'foo'); expect(opts.templates[0].source).toBe('foo');
}); });
it('error on name missing', async function () { it('error on name missing', async function () {
try { try {
await loadTemplatesAsync({ string: ['', 'bar'] }); await loadTemplatesAsync({ string: ['', 'bar'] });
throw new Error('should have thrown'); throw new Error('should have thrown');
} catch (err) { } catch (err) {
equal( expect(err.message).toBe(
err.message,
'Number of names did not match the number of string inputs' 'Number of names did not match the number of string inputs'
); );
} }
@@ -399,7 +374,7 @@ describe('precompiler', function () {
it('should complete when no args are passed', async function () { it('should complete when no args are passed', async function () {
var opts = await loadTemplatesAsync({}); var opts = await loadTemplatesAsync({});
equal(opts.templates.length, 0); expect(opts.templates.length).toBe(0);
}); });
}); });
}); });
+9 -10
View File
@@ -337,7 +337,10 @@ describe('Regressions', function () {
}, },
}; };
shouldCompileTo('{{helpa length="foo"}}', [obj, helpers], 'foo'); expectTemplate('{{helpa length="foo"}}')
.withInput(obj)
.withHelpers(helpers)
.toCompileTo('foo');
}); });
it('GH-1319: "unless" breaks when "each" value equals "null"', function () { it('GH-1319: "unless" breaks when "each" value equals "null"', function () {
@@ -373,20 +376,16 @@ describe('Regressions', function () {
var result = newHandlebarsInstance.templates['test.hbs']({ var result = newHandlebarsInstance.templates['test.hbs']({
name: 'yehuda', name: 'yehuda',
}); });
equals(result.trim(), 'YEHUDA'); expect(result.trim()).toBe('YEHUDA');
}); });
it('should call "helperMissing" if a helper is missing', function () { it('should call "helperMissing" if a helper is missing', function () {
var newHandlebarsInstance = Handlebars.create(); var newHandlebarsInstance = Handlebars.create();
shouldThrow( expect(function () {
function () { registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
registerTemplate(newHandlebarsInstance, compiledTemplateVersion7()); newHandlebarsInstance.templates['test.hbs']({});
newHandlebarsInstance.templates['test.hbs']({}); }).toThrow('Missing helper: "loud"');
},
Handlebars.Exception,
'Missing helper: "loud"'
);
}); });
it('should pass "options.lookupProperty" to "lookup"-helper, even with old templates', function () { it('should pass "options.lookupProperty" to "lookup"-helper, even with old templates', function () {
+4 -4
View File
@@ -2,22 +2,22 @@ if (typeof require !== 'undefined' && require.extensions['.handlebars']) {
describe('Require', function () { describe('Require', function () {
it('Load .handlebars files with require()', function () { it('Load .handlebars files with require()', function () {
var template = require('./artifacts/example_1'); var template = require('./artifacts/example_1');
equal(template, require('./artifacts/example_1.handlebars')); expect(template).toBe(require('./artifacts/example_1.handlebars'));
var expected = 'foo\n'; var expected = 'foo\n';
var result = template({ foo: 'foo' }); var result = template({ foo: 'foo' });
equal(result, expected); expect(result).toBe(expected);
}); });
it('Load .hbs files with require()', function () { it('Load .hbs files with require()', function () {
var template = require('./artifacts/example_2'); var template = require('./artifacts/example_2');
equal(template, require('./artifacts/example_2.hbs')); expect(template).toBe(require('./artifacts/example_2.hbs'));
var expected = 'Hello, World!\n'; var expected = 'Hello, World!\n';
var result = template({ name: 'World' }); var result = template({ name: 'World' });
equal(result, expected); expect(result).toBe(expected);
}); });
}); });
} }
+28 -46
View File
@@ -1,56 +1,38 @@
describe('runtime', function () { describe('runtime', function () {
describe('#template', function () { describe('#template', function () {
it('should throw on invalid templates', function () { it('should throw on invalid templates', function () {
shouldThrow( expect(function () {
function () { Handlebars.template({});
Handlebars.template({}); }).toThrow('Unknown template object: object');
}, expect(function () {
Error, Handlebars.template();
'Unknown template object: object' }).toThrow('Unknown template object: undefined');
); expect(function () {
shouldThrow( Handlebars.template('');
function () { }).toThrow('Unknown template object: string');
Handlebars.template();
},
Error,
'Unknown template object: undefined'
);
shouldThrow(
function () {
Handlebars.template('');
},
Error,
'Unknown template object: string'
);
}); });
it('should throw on version mismatch', function () { it('should throw on version mismatch', function () {
shouldThrow( expect(function () {
function () { Handlebars.template({
Handlebars.template({ main: {},
main: {}, compiler: [Handlebars.COMPILER_REVISION + 1],
compiler: [Handlebars.COMPILER_REVISION + 1], });
}); }).toThrow(
},
Error,
/Template was precompiled with a newer version of Handlebars than the current runtime/ /Template was precompiled with a newer version of Handlebars than the current runtime/
); );
shouldThrow( expect(function () {
function () { Handlebars.template({
Handlebars.template({ main: {},
main: {}, compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1],
compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1], });
}); }).toThrow(
},
Error,
/Template was precompiled with an older version of Handlebars than the current runtime/ /Template was precompiled with an older version of Handlebars than the current runtime/
); );
shouldThrow( expect(function () {
function () { Handlebars.template({
Handlebars.template({ main: {},
main: {}, });
}); }).toThrow(
},
Error,
/Template was precompiled with an older version of Handlebars than the current runtime/ /Template was precompiled with an older version of Handlebars than the current runtime/
); );
}); });
@@ -63,11 +45,11 @@ describe('runtime', function () {
} }
var reset = Handlebars; var reset = Handlebars;
Handlebars.noConflict(); Handlebars.noConflict();
equal(Handlebars, 'no-conflict'); expect(Handlebars).toBe('no-conflict');
Handlebars = 'really, none'; Handlebars = 'really, none';
reset.noConflict(); reset.noConflict();
equal(Handlebars, 'really, none'); expect(Handlebars).toBe('really, none');
Handlebars = reset; Handlebars = reset;
}); });
+1 -1
View File
@@ -96,7 +96,7 @@ describe('security issues', function () {
}, },
{ allowCallsToHelperMissing: true } { allowCallsToHelperMissing: true }
); );
equals(functionCalls.length, 1); expect(functionCalls.length).toBe(1);
}); });
it('should not throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function () { it('should not throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function () {
+8 -4
View File
@@ -18,8 +18,12 @@ describe('source-map', function () {
srcName: 'src.hbs', srcName: 'src.hbs',
}); });
equal(!!template.code, true); expect(template.code).toBeTruthy();
equal(!!template.map, !CompilerContext.browser); if (CompilerContext.browser) {
expect(template.map).toBeFalsy();
} else {
expect(template.map).toBeTruthy();
}
}); });
it('should map source properly', function () { it('should map source properly', function () {
var templateSource = var templateSource =
@@ -37,8 +41,8 @@ describe('source-map', function () {
source = grepLine(' b', srcLines); source = grepLine(' b', srcLines);
var mapped = consumer.originalPositionFor(generated); var mapped = consumer.originalPositionFor(generated);
equal(mapped.line, source.line); expect(mapped.line).toBe(source.line);
equal(mapped.column, source.column); expect(mapped.column).toBe(source.column);
} }
}); });
}); });
+6 -6
View File
@@ -92,8 +92,8 @@ describe('strict', function () {
}) })
.withHelpers({ .withHelpers({
helper: function (options) { helper: function (options) {
equals('value' in options.hash, true); expect(options.hash).toHaveProperty('value');
equals(options.hash.value, undefined); expect(options.hash.value).toBeUndefined();
return 'success'; return 'success';
}, },
}) })
@@ -113,10 +113,10 @@ describe('strict', function () {
}); });
template({}); template({});
} catch (error) { } catch (error) {
equals(error.lineNumber, 4); expect(error.lineNumber).toBe(4);
equals(error.endLineNumber, 4); expect(error.endLineNumber).toBe(4);
equals(error.column, 5); expect(error.column).toBe(5);
equals(error.endColumn, 10); expect(error.endColumn).toBe(10);
} }
}); });
}); });
+3 -3
View File
@@ -1,11 +1,11 @@
function shouldMatchTokens(result, tokens) { function shouldMatchTokens(result, tokens) {
for (var index = 0; index < result.length; index++) { for (var index = 0; index < result.length; index++) {
equals(result[index].name, tokens[index]); expect(result[index].name).toBe(tokens[index]);
} }
} }
function shouldBeToken(result, name, text) { function shouldBeToken(result, name, text) {
equals(result.name, name); expect(result.name).toBe(name);
equals(result.text, text); expect(result.text).toBe(text);
} }
describe('Tokenizer', function () { describe('Tokenizer', function () {
+23 -28
View File
@@ -5,11 +5,7 @@ describe('utils', function () {
if (!(safe instanceof Handlebars.SafeString)) { if (!(safe instanceof Handlebars.SafeString)) {
throw new Error('Must be instance of SafeString'); throw new Error('Must be instance of SafeString');
} }
equals( expect(safe.toString()).toBe('testing 1, 2, 3');
safe.toString(),
'testing 1, 2, 3',
'SafeString is equivalent to its underlying string'
);
}); });
it('it should not escape SafeString properties', function () { it('it should not escape SafeString properties', function () {
@@ -23,51 +19,50 @@ describe('utils', function () {
describe('#escapeExpression', function () { describe('#escapeExpression', function () {
it('should escape html', function () { it('should escape html', function () {
equals( expect(Handlebars.Utils.escapeExpression('foo<&"\'>')).toBe(
Handlebars.Utils.escapeExpression('foo<&"\'>'),
'foo&lt;&amp;&quot;&#x27;&gt;' 'foo&lt;&amp;&quot;&#x27;&gt;'
); );
equals(Handlebars.Utils.escapeExpression('foo='), 'foo&#x3D;'); expect(Handlebars.Utils.escapeExpression('foo=')).toBe('foo&#x3D;');
}); });
it('should not escape SafeString', function () { it('should not escape SafeString', function () {
var string = new Handlebars.SafeString('foo<&"\'>'); var string = new Handlebars.SafeString('foo<&"\'>');
equals(Handlebars.Utils.escapeExpression(string), 'foo<&"\'>'); expect(Handlebars.Utils.escapeExpression(string)).toBe('foo<&"\'>');
var obj = { var obj = {
toHTML: function () { toHTML: function () {
return 'foo<&"\'>'; return 'foo<&"\'>';
}, },
}; };
equals(Handlebars.Utils.escapeExpression(obj), 'foo<&"\'>'); expect(Handlebars.Utils.escapeExpression(obj)).toBe('foo<&"\'>');
}); });
it('should handle falsy', function () { it('should handle falsy', function () {
equals(Handlebars.Utils.escapeExpression(''), ''); expect(Handlebars.Utils.escapeExpression('')).toBe('');
equals(Handlebars.Utils.escapeExpression(undefined), ''); expect(Handlebars.Utils.escapeExpression(undefined)).toBe('');
equals(Handlebars.Utils.escapeExpression(null), ''); expect(Handlebars.Utils.escapeExpression(null)).toBe('');
equals(Handlebars.Utils.escapeExpression(false), 'false'); expect(Handlebars.Utils.escapeExpression(false)).toBe('false');
equals(Handlebars.Utils.escapeExpression(0), '0'); expect(Handlebars.Utils.escapeExpression(0)).toBe('0');
}); });
it('should handle empty objects', function () { it('should handle empty objects', function () {
equals(Handlebars.Utils.escapeExpression({}), {}.toString()); expect(Handlebars.Utils.escapeExpression({})).toBe({}.toString());
equals(Handlebars.Utils.escapeExpression([]), [].toString()); expect(Handlebars.Utils.escapeExpression([])).toBe([].toString());
}); });
}); });
describe('#isEmpty', function () { describe('#isEmpty', function () {
it('should not be empty', function () { it('should not be empty', function () {
equals(Handlebars.Utils.isEmpty(undefined), true); expect(Handlebars.Utils.isEmpty(undefined)).toBe(true);
equals(Handlebars.Utils.isEmpty(null), true); expect(Handlebars.Utils.isEmpty(null)).toBe(true);
equals(Handlebars.Utils.isEmpty(false), true); expect(Handlebars.Utils.isEmpty(false)).toBe(true);
equals(Handlebars.Utils.isEmpty(''), true); expect(Handlebars.Utils.isEmpty('')).toBe(true);
equals(Handlebars.Utils.isEmpty([]), true); expect(Handlebars.Utils.isEmpty([])).toBe(true);
}); });
it('should be empty', function () { it('should be empty', function () {
equals(Handlebars.Utils.isEmpty(0), false); expect(Handlebars.Utils.isEmpty(0)).toBe(false);
equals(Handlebars.Utils.isEmpty([1]), false); expect(Handlebars.Utils.isEmpty([1])).toBe(false);
equals(Handlebars.Utils.isEmpty('foo'), false); expect(Handlebars.Utils.isEmpty('foo')).toBe(false);
equals(Handlebars.Utils.isEmpty({ bar: 1 }), false); expect(Handlebars.Utils.isEmpty({ bar: 1 })).toBe(false);
}); });
}); });
@@ -82,8 +77,8 @@ describe('utils', function () {
Handlebars.Utils.extend(b, new A()); Handlebars.Utils.extend(b, new A());
equals(b.a, 1); expect(b.a).toBe(1);
equals(b.b, 2); expect(b.b).toBe(2);
}); });
}); });