From 6b164bc5fd6bba653bbf15a4c634c8efa03fab4d Mon Sep 17 00:00:00 2001 From: John Boehr Date: Sun, 26 Apr 2020 14:19:28 -0700 Subject: [PATCH] Convert remaining shouldCompileTo() to expectTemplate() --- spec/basic.js | 704 +++++++++++++++++------------------ spec/blocks.js | 336 ++++++++--------- spec/builtins.js | 376 +++++++++++-------- spec/helpers.js | 483 ++++++++++++------------ spec/javascript-compiler.js | 20 +- spec/partials.js | 724 ++++++++++++++++-------------------- spec/regressions.js | 217 +++++------ spec/security.js | 36 +- spec/subexpressions.js | 84 +++-- spec/utils.js | 8 +- spec/whitespace-control.js | 215 ++++++----- 11 files changed, 1574 insertions(+), 1629 deletions(-) diff --git a/spec/basic.js b/spec/basic.js index 4ed1914de..1e4ce2b6b 100644 --- a/spec/basic.js +++ b/spec/basic.js @@ -6,117 +6,141 @@ beforeEach(function() { describe('basic context', function() { it('most basic', function() { - shouldCompileTo('{{foo}}', { foo: 'foo' }, 'foo'); + expectTemplate('{{foo}}') + .withInput({ foo: 'foo' }) + .toCompileTo('foo'); }); it('escaping', function() { - shouldCompileTo('\\{{foo}}', { foo: 'food' }, '{{foo}}'); - shouldCompileTo('content \\{{foo}}', { foo: 'food' }, 'content {{foo}}'); - shouldCompileTo('\\\\{{foo}}', { foo: 'food' }, '\\food'); - shouldCompileTo('content \\\\{{foo}}', { foo: 'food' }, 'content \\food'); - shouldCompileTo('\\\\ {{foo}}', { foo: 'food' }, '\\\\ food'); + expectTemplate('\\{{foo}}') + .withInput({ foo: 'food' }) + .toCompileTo('{{foo}}'); + expectTemplate('content \\{{foo}}') + .withInput({ foo: 'food' }) + .toCompileTo('content {{foo}}'); + expectTemplate('\\\\{{foo}}') + .withInput({ foo: 'food' }) + .toCompileTo('\\food'); + expectTemplate('content \\\\{{foo}}') + .withInput({ foo: 'food' }) + .toCompileTo('content \\food'); + expectTemplate('\\\\ {{foo}}') + .withInput({ foo: 'food' }) + .toCompileTo('\\\\ food'); }); it('compiling with a basic context', function() { - shouldCompileTo( - 'Goodbye\n{{cruel}}\n{{world}}!', - { cruel: 'cruel', world: 'world' }, - 'Goodbye\ncruel\nworld!', - 'It works if all the required keys are provided' - ); + expectTemplate('Goodbye\n{{cruel}}\n{{world}}!') + .withInput({ + cruel: 'cruel', + world: 'world' + }) + .withMessage('It works if all the required keys are provided') + .toCompileTo('Goodbye\ncruel\nworld!'); }); it('compiling with a string context', function() { - shouldCompileTo('{{.}}{{length}}', 'bye', 'bye3'); + expectTemplate('{{.}}{{length}}') + .withInput('bye') + .toCompileTo('bye3'); }); it('compiling with an undefined context', function() { - shouldCompileTo( - 'Goodbye\n{{cruel}}\n{{world.bar}}!', - undefined, - 'Goodbye\n\n!' - ); + expectTemplate('Goodbye\n{{cruel}}\n{{world.bar}}!') + .withInput(undefined) + .toCompileTo('Goodbye\n\n!'); - shouldCompileTo( - '{{#unless foo}}Goodbye{{../test}}{{test2}}{{/unless}}', - undefined, - 'Goodbye' - ); + expectTemplate('{{#unless foo}}Goodbye{{../test}}{{test2}}{{/unless}}') + .withInput(undefined) + .toCompileTo('Goodbye'); }); it('comments', function() { - shouldCompileTo( - '{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!', - { cruel: 'cruel', world: 'world' }, - 'Goodbye\ncruel\nworld!', - 'comments are ignored' - ); + expectTemplate('{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!') + .withInput({ + cruel: 'cruel', + world: 'world' + }) + .withMessage('comments are ignored') + .toCompileTo('Goodbye\ncruel\nworld!'); - shouldCompileTo(' {{~! comment ~}} blah', {}, 'blah'); - shouldCompileTo(' {{~!-- long-comment --~}} blah', {}, 'blah'); - shouldCompileTo(' {{! comment ~}} blah', {}, ' blah'); - shouldCompileTo(' {{!-- long-comment --~}} blah', {}, ' blah'); - shouldCompileTo(' {{~! comment}} blah', {}, ' blah'); - shouldCompileTo(' {{~!-- long-comment --}} blah', {}, ' blah'); + expectTemplate(' {{~! comment ~}} blah').toCompileTo('blah'); + expectTemplate(' {{~!-- long-comment --~}} blah').toCompileTo( + 'blah' + ); + expectTemplate(' {{! comment ~}} blah').toCompileTo(' blah'); + expectTemplate(' {{!-- long-comment --~}} blah').toCompileTo( + ' blah' + ); + expectTemplate(' {{~! comment}} blah').toCompileTo(' blah'); + expectTemplate(' {{~!-- long-comment --}} blah').toCompileTo( + ' blah' + ); }); it('boolean', function() { var string = '{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!'; - shouldCompileTo( - string, - { goodbye: true, world: 'world' }, - 'GOODBYE cruel world!', - 'booleans show the contents when true' - ); - - shouldCompileTo( - string, - { goodbye: false, world: 'world' }, - 'cruel world!', - 'booleans do not show the contents when false' - ); + expectTemplate(string) + .withInput({ + goodbye: true, + world: 'world' + }) + .withMessage('booleans show the contents when true') + .toCompileTo('GOODBYE cruel world!'); + + expectTemplate(string) + .withInput({ + goodbye: false, + world: 'world' + }) + .withMessage('booleans do not show the contents when false') + .toCompileTo('cruel world!'); }); it('zeros', function() { - shouldCompileTo( - 'num1: {{num1}}, num2: {{num2}}', - { num1: 42, num2: 0 }, - 'num1: 42, num2: 0' - ); - shouldCompileTo('num: {{.}}', 0, 'num: 0'); - shouldCompileTo('num: {{num1/num2}}', { num1: { num2: 0 } }, 'num: 0'); + expectTemplate('num1: {{num1}}, num2: {{num2}}') + .withInput({ + num1: 42, + num2: 0 + }) + .toCompileTo('num1: 42, num2: 0'); + expectTemplate('num: {{.}}') + .withInput(0) + .toCompileTo('num: 0'); + expectTemplate('num: {{num1/num2}}') + .withInput({ num1: { num2: 0 } }) + .toCompileTo('num: 0'); }); it('false', function() { /* eslint-disable no-new-wrappers */ - shouldCompileTo( - 'val1: {{val1}}, val2: {{val2}}', - { val1: false, val2: new Boolean(false) }, - 'val1: false, val2: false' - ); - shouldCompileTo('val: {{.}}', false, 'val: false'); - shouldCompileTo( - 'val: {{val1/val2}}', - { val1: { val2: false } }, - 'val: false' - ); - - shouldCompileTo( - 'val1: {{{val1}}}, val2: {{{val2}}}', - { val1: false, val2: new Boolean(false) }, - 'val1: false, val2: false' - ); - shouldCompileTo( - 'val: {{{val1/val2}}}', - { val1: { val2: false } }, - 'val: false' - ); + expectTemplate('val1: {{val1}}, val2: {{val2}}') + .withInput({ + val1: false, + val2: new Boolean(false) + }) + .toCompileTo('val1: false, val2: false'); + expectTemplate('val: {{.}}') + .withInput(false) + .toCompileTo('val: false'); + expectTemplate('val: {{val1/val2}}') + .withInput({ val1: { val2: false } }) + .toCompileTo('val: false'); + + expectTemplate('val1: {{{val1}}}, val2: {{{val2}}}') + .withInput({ + val1: false, + val2: new Boolean(false) + }) + .toCompileTo('val1: false, val2: false'); + expectTemplate('val: {{{val1/val2}}}') + .withInput({ val1: { val2: false } }) + .toCompileTo('val: false'); /* eslint-enable */ }); it('should handle undefined and null', function() { - shouldCompileTo( - '{{awesome undefined null}}', - { + expectTemplate('{{awesome undefined null}}') + .withInput({ awesome: function(_undefined, _null, options) { return ( (_undefined === undefined) + @@ -126,95 +150,70 @@ describe('basic context', function() { typeof options ); } - }, - 'true true object' - ); - shouldCompileTo( - '{{undefined}}', - { + }) + .toCompileTo('true true object'); + expectTemplate('{{undefined}}') + .withInput({ undefined: function() { return 'undefined!'; } - }, - 'undefined!' - ); - shouldCompileTo( - '{{null}}', - { + }) + .toCompileTo('undefined!'); + expectTemplate('{{null}}') + .withInput({ null: function() { return 'null!'; } - }, - 'null!' - ); + }) + .toCompileTo('null!'); }); it('newlines', function() { - shouldCompileTo("Alan's\nTest", {}, "Alan's\nTest"); - shouldCompileTo("Alan's\rTest", {}, "Alan's\rTest"); + expectTemplate("Alan's\nTest").toCompileTo("Alan's\nTest"); + expectTemplate("Alan's\rTest").toCompileTo("Alan's\rTest"); }); it('escaping text', function() { - shouldCompileTo( - "Awesome's", - {}, - "Awesome's", - "text is escaped so that it doesn't get caught on single quotes" - ); - shouldCompileTo( - 'Awesome\\', - {}, - 'Awesome\\', - "text is escaped so that the closing quote can't be ignored" - ); - shouldCompileTo( - 'Awesome\\\\ foo', - {}, - 'Awesome\\\\ foo', - "text is escaped so that it doesn't mess up backslashes" - ); - shouldCompileTo( - 'Awesome {{foo}}', - { foo: '\\' }, - 'Awesome \\', - "text is escaped so that it doesn't mess up backslashes" - ); - shouldCompileTo( - " ' ' ", - {}, - " ' ' ", - 'double quotes never produce invalid javascript' - ); + expectTemplate("Awesome's") + .withMessage( + "text is escaped so that it doesn't get caught on single quotes" + ) + .toCompileTo("Awesome's"); + expectTemplate('Awesome\\') + .withMessage("text is escaped so that the closing quote can't be ignored") + .toCompileTo('Awesome\\'); + expectTemplate('Awesome\\\\ foo') + .withMessage("text is escaped so that it doesn't mess up backslashes") + .toCompileTo('Awesome\\\\ foo'); + expectTemplate('Awesome {{foo}}') + .withInput({ foo: '\\' }) + .withMessage("text is escaped so that it doesn't mess up backslashes") + .toCompileTo('Awesome \\'); + expectTemplate(" ' ' ") + .withMessage('double quotes never produce invalid javascript') + .toCompileTo(" ' ' "); }); it('escaping expressions', function() { - shouldCompileTo( - '{{{awesome}}}', - { awesome: "&'\\<>" }, - "&'\\<>", - "expressions with 3 handlebars aren't escaped" - ); + expectTemplate('{{{awesome}}}') + .withInput({ awesome: "&'\\<>" }) + .withMessage("expressions with 3 handlebars aren't escaped") + .toCompileTo("&'\\<>"); - shouldCompileTo( - '{{&awesome}}', - { awesome: "&'\\<>" }, - "&'\\<>", - "expressions with {{& handlebars aren't escaped" - ); + expectTemplate('{{&awesome}}') + .withInput({ awesome: "&'\\<>" }) + .withMessage("expressions with {{& handlebars aren't escaped") + .toCompileTo("&'\\<>"); - shouldCompileTo( - '{{awesome}}', - { awesome: '&"\'`\\<>' }, - '&"'`\\<>', - 'by default expressions should be escaped' - ); + expectTemplate('{{awesome}}') + .withInput({ awesome: '&"\'`\\<>' }) + .withMessage('by default expressions should be escaped') + .toCompileTo('&"'`\\<>'); - shouldCompileTo( - '{{awesome}}', - { awesome: 'Escaped, looks like: <b>' }, - 'Escaped, <b> looks like: &lt;b&gt;', - 'escaping should properly handle amperstands' - ); + expectTemplate('{{awesome}}') + .withInput({ awesome: 'Escaped, looks like: <b>' }) + .withMessage('escaping should properly handle amperstands') + .toCompileTo('Escaped, <b> looks like: &lt;b&gt;'); }); it("functions returning safestrings shouldn't be escaped", function() { @@ -223,263 +222,222 @@ describe('basic context', function() { return new Handlebars.SafeString("&'\\<>"); } }; - shouldCompileTo( - '{{awesome}}', - hash, - "&'\\<>", - "functions returning safestrings aren't escaped" - ); + expectTemplate('{{awesome}}') + .withInput(hash) + .withMessage("functions returning safestrings aren't escaped") + .toCompileTo("&'\\<>"); }); it('functions', function() { - shouldCompileTo( - '{{awesome}}', - { + expectTemplate('{{awesome}}') + .withInput({ awesome: function() { return 'Awesome'; } - }, - 'Awesome', - 'functions are called and render their output' - ); - shouldCompileTo( - '{{awesome}}', - { + }) + .withMessage('functions are called and render their output') + .toCompileTo('Awesome'); + expectTemplate('{{awesome}}') + .withInput({ awesome: function() { return this.more; }, more: 'More awesome' - }, - 'More awesome', - 'functions are bound to the context' - ); + }) + .withMessage('functions are bound to the context') + .toCompileTo('More awesome'); }); it('functions with context argument', function() { - shouldCompileTo( - '{{awesome frank}}', - { + expectTemplate('{{awesome frank}}') + .withInput({ awesome: function(context) { return context; }, frank: 'Frank' - }, - 'Frank', - 'functions are called with context arguments' - ); + }) + .withMessage('functions are called with context arguments') + .toCompileTo('Frank'); }); it('pathed functions with context argument', function() { - shouldCompileTo( - '{{bar.awesome frank}}', - { + expectTemplate('{{bar.awesome frank}}') + .withInput({ bar: { awesome: function(context) { return context; } }, frank: 'Frank' - }, - 'Frank', - 'functions are called with context arguments' - ); + }) + .withMessage('functions are called with context arguments') + .toCompileTo('Frank'); }); it('depthed functions with context argument', function() { - shouldCompileTo( - '{{#with frank}}{{../awesome .}}{{/with}}', - { + expectTemplate('{{#with frank}}{{../awesome .}}{{/with}}') + .withInput({ awesome: function(context) { return context; }, frank: 'Frank' - }, - 'Frank', - 'functions are called with context arguments' - ); + }) + .withMessage('functions are called with context arguments') + .toCompileTo('Frank'); }); it('block functions with context argument', function() { - shouldCompileTo( - '{{#awesome 1}}inner {{.}}{{/awesome}}', - { + expectTemplate('{{#awesome 1}}inner {{.}}{{/awesome}}') + .withInput({ awesome: function(context, options) { return options.fn(context); } - }, - 'inner 1', - 'block functions are called with context and options' - ); + }) + .withMessage('block functions are called with context and options') + .toCompileTo('inner 1'); }); it('depthed block functions with context argument', function() { - shouldCompileTo( - '{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}', - { + expectTemplate( + '{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}' + ) + .withInput({ value: true, awesome: function(context, options) { return options.fn(context); } - }, - 'inner 1', - 'block functions are called with context and options' - ); + }) + .withMessage('block functions are called with context and options') + .toCompileTo('inner 1'); }); it('block functions without context argument', function() { - shouldCompileTo( - '{{#awesome}}inner{{/awesome}}', - { + expectTemplate('{{#awesome}}inner{{/awesome}}') + .withInput({ awesome: function(options) { return options.fn(this); } - }, - 'inner', - 'block functions are called with options' - ); + }) + .withMessage('block functions are called with options') + .toCompileTo('inner'); }); it('pathed block functions without context argument', function() { - shouldCompileTo( - '{{#foo.awesome}}inner{{/foo.awesome}}', - { + expectTemplate('{{#foo.awesome}}inner{{/foo.awesome}}') + .withInput({ foo: { awesome: function() { return this; } } - }, - 'inner', - 'block functions are called with options' - ); + }) + .withMessage('block functions are called with options') + .toCompileTo('inner'); }); it('depthed block functions without context argument', function() { - shouldCompileTo( - '{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}', - { + expectTemplate( + '{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}' + ) + .withInput({ value: true, awesome: function() { return this; } - }, - 'inner', - 'block functions are called with options' - ); + }) + .withMessage('block functions are called with options') + .toCompileTo('inner'); }); it('paths with hyphens', function() { - shouldCompileTo( - '{{foo-bar}}', - { 'foo-bar': 'baz' }, - 'baz', - 'Paths can contain hyphens (-)' - ); - shouldCompileTo( - '{{foo.foo-bar}}', - { foo: { 'foo-bar': 'baz' } }, - 'baz', - 'Paths can contain hyphens (-)' - ); - shouldCompileTo( - '{{foo/foo-bar}}', - { foo: { 'foo-bar': 'baz' } }, - 'baz', - 'Paths can contain hyphens (-)' - ); + expectTemplate('{{foo-bar}}') + .withInput({ 'foo-bar': 'baz' }) + .withMessage('Paths can contain hyphens (-)') + .toCompileTo('baz'); + expectTemplate('{{foo.foo-bar}}') + .withInput({ foo: { 'foo-bar': 'baz' } }) + .withMessage('Paths can contain hyphens (-)') + .toCompileTo('baz'); + expectTemplate('{{foo/foo-bar}}') + .withInput({ foo: { 'foo-bar': 'baz' } }) + .withMessage('Paths can contain hyphens (-)') + .toCompileTo('baz'); }); it('nested paths', function() { - shouldCompileTo( - 'Goodbye {{alan/expression}} world!', - { alan: { expression: 'beautiful' } }, - 'Goodbye beautiful world!', - 'Nested paths access nested objects' - ); + expectTemplate('Goodbye {{alan/expression}} world!') + .withInput({ alan: { expression: 'beautiful' } }) + .withMessage('Nested paths access nested objects') + .toCompileTo('Goodbye beautiful world!'); }); it('nested paths with empty string value', function() { - shouldCompileTo( - 'Goodbye {{alan/expression}} world!', - { alan: { expression: '' } }, - 'Goodbye world!', - 'Nested paths access nested objects with empty string' - ); + expectTemplate('Goodbye {{alan/expression}} world!') + .withInput({ alan: { expression: '' } }) + .withMessage('Nested paths access nested objects with empty string') + .toCompileTo('Goodbye world!'); }); it('literal paths', function() { - shouldCompileTo( - 'Goodbye {{[@alan]/expression}} world!', - { '@alan': { expression: 'beautiful' } }, - 'Goodbye beautiful world!', - 'Literal paths can be used' - ); - shouldCompileTo( - 'Goodbye {{[foo bar]/expression}} world!', - { 'foo bar': { expression: 'beautiful' } }, - 'Goodbye beautiful world!', - 'Literal paths can be used' - ); + expectTemplate('Goodbye {{[@alan]/expression}} world!') + .withInput({ '@alan': { expression: 'beautiful' } }) + .withMessage('Literal paths can be used') + .toCompileTo('Goodbye beautiful world!'); + expectTemplate('Goodbye {{[foo bar]/expression}} world!') + .withInput({ 'foo bar': { expression: 'beautiful' } }) + .withMessage('Literal paths can be used') + .toCompileTo('Goodbye beautiful world!'); }); it('literal references', function() { - shouldCompileTo( - 'Goodbye {{[foo bar]}} world!', - { 'foo bar': 'beautiful' }, - 'Goodbye beautiful world!' - ); - shouldCompileTo( - 'Goodbye {{"foo bar"}} world!', - { 'foo bar': 'beautiful' }, - 'Goodbye beautiful world!' - ); - shouldCompileTo( - "Goodbye {{'foo bar'}} world!", - { 'foo bar': 'beautiful' }, - 'Goodbye beautiful world!' - ); - shouldCompileTo( - 'Goodbye {{"foo[bar"}} world!', - { 'foo[bar': 'beautiful' }, - 'Goodbye beautiful world!' - ); - shouldCompileTo( - 'Goodbye {{"foo\'bar"}} world!', - { "foo'bar": 'beautiful' }, - 'Goodbye beautiful world!' - ); - shouldCompileTo( - "Goodbye {{'foo\"bar'}} world!", - { 'foo"bar': 'beautiful' }, - 'Goodbye beautiful world!' - ); + expectTemplate('Goodbye {{[foo bar]}} world!') + .withInput({ 'foo bar': 'beautiful' }) + .toCompileTo('Goodbye beautiful world!'); + expectTemplate('Goodbye {{"foo bar"}} world!') + .withInput({ 'foo bar': 'beautiful' }) + .toCompileTo('Goodbye beautiful world!'); + expectTemplate("Goodbye {{'foo bar'}} world!") + .withInput({ 'foo bar': 'beautiful' }) + .toCompileTo('Goodbye beautiful world!'); + expectTemplate('Goodbye {{"foo[bar"}} world!') + .withInput({ 'foo[bar': 'beautiful' }) + .toCompileTo('Goodbye beautiful world!'); + expectTemplate('Goodbye {{"foo\'bar"}} world!') + .withInput({ "foo'bar": 'beautiful' }) + .toCompileTo('Goodbye beautiful world!'); + expectTemplate("Goodbye {{'foo\"bar'}} world!") + .withInput({ 'foo"bar': 'beautiful' }) + .toCompileTo('Goodbye beautiful world!'); }); it("that current context path ({{.}}) doesn't hit helpers", function() { - shouldCompileTo('test: {{.}}', [null, { helper: 'awesome' }], 'test: '); + expectTemplate('test: {{.}}') + .withInput(null) + .withHelpers({ helper: 'awesome' }) + .toCompileTo('test: '); }); it('complex but empty paths', function() { - shouldCompileTo('{{person/name}}', { person: { name: null } }, ''); - shouldCompileTo('{{person/name}}', { person: {} }, ''); + expectTemplate('{{person/name}}') + .withInput({ person: { name: null } }) + .toCompileTo(''); + expectTemplate('{{person/name}}') + .withInput({ person: {} }) + .toCompileTo(''); }); it('this keyword in paths', function() { var string = '{{#goodbyes}}{{this}}{{/goodbyes}}'; var hash = { goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] }; - shouldCompileTo( - string, - hash, - 'goodbyeGoodbyeGOODBYE', - 'This keyword in paths evaluates to current context' - ); + expectTemplate(string) + .withInput(hash) + .withMessage('This keyword in paths evaluates to current context') + .toCompileTo('goodbyeGoodbyeGOODBYE'); string = '{{#hellos}}{{this/text}}{{/hellos}}'; hash = { hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }] }; - shouldCompileTo( - string, - hash, - 'helloHelloHELLO', - 'This keyword evaluates in more complex paths' - ); + expectTemplate(string) + .withInput(hash) + .withMessage('This keyword evaluates in more complex paths') + .toCompileTo('helloHelloHELLO'); }); it('this keyword nested inside path', function() { @@ -488,8 +446,12 @@ describe('basic context', function() { 'Invalid path: text/this - 1:13' ); - shouldCompileTo('{{[this]}}', { this: 'bar' }, 'bar'); - shouldCompileTo('{{text/[this]}}', { text: { this: 'bar' } }, 'bar'); + expectTemplate('{{[this]}}') + .withInput({ this: 'bar' }) + .toCompileTo('bar'); + expectTemplate('{{text/[this]}}') + .withInput({ text: { this: 'bar' } }) + .toCompileTo('bar'); }); it('this keyword in helpers', function() { @@ -500,81 +462,83 @@ describe('basic context', function() { }; var string = '{{#goodbyes}}{{foo this}}{{/goodbyes}}'; var hash = { goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] }; - shouldCompileTo( - string, - [hash, helpers], - 'bar goodbyebar Goodbyebar GOODBYE', - 'This keyword in paths evaluates to current context' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .withMessage('This keyword in paths evaluates to current context') + .toCompileTo('bar goodbyebar Goodbyebar GOODBYE'); string = '{{#hellos}}{{foo this/text}}{{/hellos}}'; hash = { hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }] }; - shouldCompileTo( - string, - [hash, helpers], - 'bar hellobar Hellobar HELLO', - 'This keyword evaluates in more complex paths' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .withMessage('This keyword evaluates in more complex paths') + .toCompileTo('bar hellobar Hellobar HELLO'); }); it('this keyword nested inside helpers param', function() { var string = '{{#hellos}}{{foo text/this/foo}}{{/hellos}}'; expectTemplate(string).toThrow(Error, 'Invalid path: text/this - 1:17'); - shouldCompileTo( - '{{foo [this]}}', - { + expectTemplate('{{foo [this]}}') + .withInput({ foo: function(value) { return value; }, this: 'bar' - }, - 'bar' - ); - shouldCompileTo( - '{{foo text/[this]}}', - { + }) + .toCompileTo('bar'); + expectTemplate('{{foo text/[this]}}') + .withInput({ foo: function(value) { return value; }, text: { this: 'bar' } - }, - 'bar' - ); + }) + .toCompileTo('bar'); }); it('pass string literals', function() { - shouldCompileTo('{{"foo"}}', {}, ''); - shouldCompileTo('{{"foo"}}', { foo: 'bar' }, 'bar'); - shouldCompileTo( - '{{#"foo"}}{{.}}{{/"foo"}}', - { foo: ['bar', 'baz'] }, - 'barbaz' - ); + expectTemplate('{{"foo"}}').toCompileTo(''); + expectTemplate('{{"foo"}}') + .withInput({ foo: 'bar' }) + .toCompileTo('bar'); + expectTemplate('{{#"foo"}}{{.}}{{/"foo"}}') + .withInput({ + foo: ['bar', 'baz'] + }) + .toCompileTo('barbaz'); }); it('pass number literals', function() { - shouldCompileTo('{{12}}', {}, ''); - shouldCompileTo('{{12}}', { '12': 'bar' }, 'bar'); - shouldCompileTo('{{12.34}}', {}, ''); - shouldCompileTo('{{12.34}}', { '12.34': 'bar' }, 'bar'); - shouldCompileTo( - '{{12.34 1}}', - { + expectTemplate('{{12}}').toCompileTo(''); + expectTemplate('{{12}}') + .withInput({ '12': 'bar' }) + .toCompileTo('bar'); + expectTemplate('{{12.34}}').toCompileTo(''); + expectTemplate('{{12.34}}') + .withInput({ '12.34': 'bar' }) + .toCompileTo('bar'); + expectTemplate('{{12.34 1}}') + .withInput({ '12.34': function(arg) { return 'bar' + arg; } - }, - 'bar1' - ); + }) + .toCompileTo('bar1'); }); it('pass boolean literals', function() { - shouldCompileTo('{{true}}', {}, ''); - shouldCompileTo('{{true}}', { '': 'foo' }, ''); - shouldCompileTo('{{false}}', { false: 'foo' }, 'foo'); + expectTemplate('{{true}}').toCompileTo(''); + expectTemplate('{{true}}') + .withInput({ '': 'foo' }) + .toCompileTo(''); + expectTemplate('{{false}}') + .withInput({ false: 'foo' }) + .toCompileTo('foo'); }); it('should handle literals in subexpression', function() { @@ -583,17 +547,13 @@ describe('basic context', function() { return arg; } }; - shouldCompileTo( - '{{foo (false)}}', - [ - { - false: function() { - return 'bar'; - } - }, - helpers - ], - 'bar' - ); + expectTemplate('{{foo (false)}}') + .withInput({ + false: function() { + return 'bar'; + } + }) + .withHelpers(helpers) + .toCompileTo('bar'); }); }); diff --git a/spec/blocks.js b/spec/blocks.js index 2e5516198..ab16fd9d3 100644 --- a/spec/blocks.js +++ b/spec/blocks.js @@ -5,19 +5,18 @@ describe('blocks', function() { goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }], world: 'world' }; - shouldCompileTo( - string, - hash, - 'goodbye! Goodbye! GOODBYE! cruel world!', - 'Arrays iterate over the contents when not empty' - ); - - shouldCompileTo( - string, - { goodbyes: [], world: 'world' }, - 'cruel world!', - 'Arrays ignore the contents when empty' - ); + expectTemplate(string) + .withInput(hash) + .withMessage('Arrays iterate over the contents when not empty') + .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); + + expectTemplate(string) + .withInput({ + goodbyes: [], + world: 'world' + }) + .withMessage('Arrays ignore the contents when empty') + .toCompileTo('cruel world!'); }); it('array without data', function() { @@ -27,11 +26,10 @@ describe('blocks', function() { goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }], world: 'world' }; - shouldCompileTo( - string, - [hash, , , false], - 'goodbyeGoodbyeGOODBYE goodbyeGoodbyeGOODBYE' - ); + expectTemplate(string) + .withInput(hash) + .withCompileOptions({ compat: false }) + .toCompileTo('goodbyeGoodbyeGOODBYE goodbyeGoodbyeGOODBYE'); }); it('array with @index', function() { @@ -54,19 +52,18 @@ describe('blocks', function() { goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }], world: 'world' }; - shouldCompileTo( - string, - hash, - 'cruel world!', - 'Arrays iterate over the contents when not empty' - ); - - shouldCompileTo( - string, - { goodbyes: [], world: 'world' }, - 'cruel world!', - 'Arrays ignore the contents when empty' - ); + expectTemplate(string) + .withInput(hash) + .withMessage('Arrays iterate over the contents when not empty') + .toCompileTo('cruel world!'); + + expectTemplate(string) + .withInput({ + goodbyes: [], + world: 'world' + }) + .withMessage('Arrays ignore the contents when empty') + .toCompileTo('cruel world!'); }); it('block with complex lookup', function() { @@ -76,12 +73,14 @@ describe('blocks', function() { goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }] }; - shouldCompileTo( - string, - hash, - 'goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! ', - 'Templates can access variables in contexts up the stack with relative path syntax' - ); + expectTemplate(string) + .withInput(hash) + .withMessage( + 'Templates can access variables in contexts up the stack with relative path syntax' + ) + .toCompileTo( + 'goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! ' + ); }); it('multiple blocks with complex lookup', function() { @@ -91,7 +90,9 @@ describe('blocks', function() { goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }] }; - shouldCompileTo(string, hash, 'AlanAlanAlanAlanAlanAlan'); + expectTemplate(string) + .withInput(hash) + .toCompileTo('AlanAlanAlanAlanAlanAlan'); }); it('block with complex lookup using nested context', function() { @@ -108,7 +109,9 @@ describe('blocks', function() { outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }] }; - shouldCompileTo(string, hash, 'Goodbye cruel sad OMG!'); + expectTemplate(string) + .withInput(hash) + .toCompileTo('Goodbye cruel sad OMG!'); }); it('works with cached blocks', function() { @@ -133,61 +136,51 @@ describe('blocks', function() { var string = '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'; var hash = {}; - shouldCompileTo( - string, - hash, - 'Right On!', - "Inverted section rendered when value isn't set." - ); + expectTemplate(string) + .withInput(hash) + .withMessage("Inverted section rendered when value isn't set.") + .toCompileTo('Right On!'); }); it('inverted section with false value', function() { var string = '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'; var hash = { goodbyes: false }; - shouldCompileTo( - string, - hash, - 'Right On!', - 'Inverted section rendered when value is false.' - ); + expectTemplate(string) + .withInput(hash) + .withMessage('Inverted section rendered when value is false.') + .toCompileTo('Right On!'); }); it('inverted section with empty set', function() { var string = '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'; var hash = { goodbyes: [] }; - shouldCompileTo( - string, - hash, - 'Right On!', - 'Inverted section rendered when value is empty set.' - ); + expectTemplate(string) + .withInput(hash) + .withMessage('Inverted section rendered when value is empty set.') + .toCompileTo('Right On!'); }); it('block inverted sections', function() { - shouldCompileTo( - '{{#people}}{{name}}{{^}}{{none}}{{/people}}', - { none: 'No people' }, - 'No people' - ); + expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}') + .withInput({ none: 'No people' }) + .toCompileTo('No people'); }); it('chained inverted sections', function() { - shouldCompileTo( - '{{#people}}{{name}}{{else if none}}{{none}}{{/people}}', - { none: 'No people' }, - 'No people' - ); - shouldCompileTo( - '{{#people}}{{name}}{{else if nothere}}fail{{else unless nothere}}{{none}}{{/people}}', - { none: 'No people' }, - 'No people' - ); - shouldCompileTo( - '{{#people}}{{name}}{{else if none}}{{none}}{{else}}fail{{/people}}', - { none: 'No people' }, - 'No people' - ); + expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{/people}}') + .withInput({ none: 'No people' }) + .toCompileTo('No people'); + expectTemplate( + '{{#people}}{{name}}{{else if nothere}}fail{{else unless nothere}}{{none}}{{/people}}' + ) + .withInput({ none: 'No people' }) + .toCompileTo('No people'); + expectTemplate( + '{{#people}}{{name}}{{else if none}}{{none}}{{else}}fail{{/people}}' + ) + .withInput({ none: 'No people' }) + .toCompileTo('No people'); }); it('chained inverted sections with mismatch', function() { expectTemplate( @@ -196,62 +189,55 @@ describe('blocks', function() { }); it('block inverted sections with empty arrays', function() { - shouldCompileTo( - '{{#people}}{{name}}{{^}}{{none}}{{/people}}', - { none: 'No people', people: [] }, - 'No people' - ); + expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}') + .withInput({ + none: 'No people', + people: [] + }) + .toCompileTo('No people'); }); }); describe('standalone sections', function() { it('block standalone else sections', function() { - shouldCompileTo( - '{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n', - { none: 'No people' }, - 'No people\n' - ); - shouldCompileTo( - '{{#none}}\n{{.}}\n{{^}}\n{{none}}\n{{/none}}\n', - { none: 'No people' }, - 'No people\n' - ); - shouldCompileTo( - '{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n', - { none: 'No people' }, - 'No people\n' - ); + expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n') + .withInput({ none: 'No people' }) + .toCompileTo('No people\n'); + expectTemplate('{{#none}}\n{{.}}\n{{^}}\n{{none}}\n{{/none}}\n') + .withInput({ none: 'No people' }) + .toCompileTo('No people\n'); + expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n') + .withInput({ none: 'No people' }) + .toCompileTo('No people\n'); }); it('block standalone else sections can be disabled', function() { - shouldCompileTo( - '{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n', - [{ none: 'No people' }, {}, {}, { ignoreStandalone: true }], - '\nNo people\n\n' - ); - shouldCompileTo( - '{{#none}}\n{{.}}\n{{^}}\nFail\n{{/none}}\n', - [{ none: 'No people' }, {}, {}, { ignoreStandalone: true }], - '\nNo people\n\n' - ); + expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n') + .withInput({ none: 'No people' }) + .withCompileOptions({ ignoreStandalone: true }) + .toCompileTo('\nNo people\n\n'); + expectTemplate('{{#none}}\n{{.}}\n{{^}}\nFail\n{{/none}}\n') + .withInput({ none: 'No people' }) + .withCompileOptions({ ignoreStandalone: true }) + .toCompileTo('\nNo people\n\n'); }); it('block standalone chained else sections', function() { - shouldCompileTo( - '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n', - { none: 'No people' }, - 'No people\n' - ); - shouldCompileTo( - '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{^}}\n{{/people}}\n', - { none: 'No people' }, - 'No people\n' - ); + expectTemplate( + '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n' + ) + .withInput({ none: 'No people' }) + .toCompileTo('No people\n'); + expectTemplate( + '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{^}}\n{{/people}}\n' + ) + .withInput({ none: 'No people' }) + .toCompileTo('No people\n'); }); it('should handle nesting', function() { - shouldCompileTo( - '{{#data}}\n{{#if true}}\n{{.}}\n{{/if}}\n{{/data}}\nOK.', - { data: [1, 3, 5] }, - '1\n3\n5\nOK.' - ); + expectTemplate('{{#data}}\n{{#if true}}\n{{.}}\n{{/if}}\n{{/data}}\nOK.') + .withInput({ + data: [1, 3, 5] + }) + .toCompileTo('1\n3\n5\nOK.'); }); }); @@ -261,11 +247,10 @@ describe('blocks', function() { '{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}'; var hash = { omg: 'OMG!', outer: [{ inner: [{ text: 'goodbye' }] }] }; - shouldCompileTo( - string, - [hash, undefined, undefined, true], - 'Goodbye cruel OMG!' - ); + expectTemplate(string) + .withInput(hash) + .withCompileOptions({ compat: true }) + .toCompileTo('Goodbye cruel OMG!'); }); it('block with deep recursive pathed lookup', function() { @@ -276,11 +261,10 @@ describe('blocks', function() { outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }] }; - shouldCompileTo( - string, - [hash, undefined, undefined, true], - 'Goodbye cruel OMG!' - ); + expectTemplate(string) + .withInput(hash) + .withCompileOptions({ compat: true }) + .toCompileTo('Goodbye cruel OMG!'); }); it('block with missed recursive lookup', function() { var string = @@ -290,11 +274,10 @@ describe('blocks', function() { outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }] }; - shouldCompileTo( - string, - [hash, undefined, undefined, true], - 'Goodbye cruel ' - ); + expectTemplate(string) + .withInput(hash) + .withCompileOptions({ compat: true }) + .toCompileTo('Goodbye cruel '); }); }); @@ -311,11 +294,10 @@ describe('blocks', function() { return fn; } }; - shouldCompileTo( - '{{#helper}}{{*decorator}}{{/helper}}', - { hash: {}, helpers: helpers, decorators: decorators }, - 'success' - ); + expectTemplate('{{#helper}}{{*decorator}}{{/helper}}') + .withHelpers(helpers) + .withDecorators(decorators) + .toCompileTo('success'); }); it('should apply allow undefined return', function() { var helpers = { @@ -328,11 +310,10 @@ describe('blocks', function() { fn.run = 'cess'; } }; - shouldCompileTo( - '{{#helper}}{{*decorator}}suc{{/helper}}', - { hash: {}, helpers: helpers, decorators: decorators }, - 'success' - ); + expectTemplate('{{#helper}}{{*decorator}}suc{{/helper}}') + .withHelpers(helpers) + .withDecorators(decorators) + .toCompileTo('success'); }); it('should apply block decorators', function() { @@ -347,11 +328,12 @@ describe('blocks', function() { return fn; } }; - shouldCompileTo( - '{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}', - { hash: {}, helpers: helpers, decorators: decorators }, - 'success' - ); + expectTemplate( + '{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}' + ) + .withHelpers(helpers) + .withDecorators(decorators) + .toCompileTo('success'); }); it('should support nested decorators', function() { var helpers = { @@ -368,11 +350,12 @@ describe('blocks', function() { props.nested = options.fn(); } }; - shouldCompileTo( - '{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}', - { hash: {}, helpers: helpers, decorators: decorators }, - 'success' - ); + expectTemplate( + '{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}' + ) + .withHelpers(helpers) + .withDecorators(decorators) + .toCompileTo('success'); }); it('should apply multiple decorators', function() { @@ -387,11 +370,12 @@ describe('blocks', function() { return fn; } }; - shouldCompileTo( - '{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}', - { hash: {}, helpers: helpers, decorators: decorators }, - 'success' - ); + expectTemplate( + '{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}' + ) + .withHelpers(helpers) + .withDecorators(decorators) + .toCompileTo('success'); }); it('should access parent variables', function() { @@ -406,11 +390,11 @@ describe('blocks', function() { return fn; } }; - shouldCompileTo( - '{{#helper}}{{*decorator foo}}{{/helper}}', - { hash: { foo: 'success' }, helpers: helpers, decorators: decorators }, - 'success' - ); + expectTemplate('{{#helper}}{{*decorator foo}}{{/helper}}') + .withHelpers(helpers) + .withDecorators(decorators) + .withInput({ foo: 'success' }) + .toCompileTo('success'); }); it('should work with root program', function() { var run; @@ -421,11 +405,10 @@ describe('blocks', function() { return fn; } }; - shouldCompileTo( - '{{*decorator "success"}}', - { hash: { foo: 'success' }, decorators: decorators }, - '' - ); + expectTemplate('{{*decorator "success"}}') + .withDecorators(decorators) + .withInput({ foo: 'success' }) + .toCompileTo(''); equals(run, true); }); it('should fail when accessing variables from root', function() { @@ -437,11 +420,10 @@ describe('blocks', function() { return fn; } }; - shouldCompileTo( - '{{*decorator foo}}', - { hash: { foo: 'fail' }, decorators: decorators }, - '' - ); + expectTemplate('{{*decorator foo}}') + .withDecorators(decorators) + .withInput({ foo: 'fail' }) + .toCompileTo(''); equals(run, true); }); diff --git a/spec/builtins.js b/spec/builtins.js index 8502bfe44..b54c5ca3a 100644 --- a/spec/builtins.js +++ b/spec/builtins.js @@ -2,148 +2,165 @@ describe('builtin helpers', function() { describe('#if', function() { it('if', function() { var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!'; - shouldCompileTo( - string, - { goodbye: true, world: 'world' }, - 'GOODBYE cruel world!', - 'if with boolean argument shows the contents when true' - ); - shouldCompileTo( - string, - { goodbye: 'dummy', world: 'world' }, - 'GOODBYE cruel world!', - 'if with string argument shows the contents' - ); - shouldCompileTo( - string, - { goodbye: false, world: 'world' }, - 'cruel world!', - 'if with boolean argument does not show the contents when false' - ); - shouldCompileTo( - string, - { world: 'world' }, - 'cruel world!', - 'if with undefined does not show the contents' - ); - shouldCompileTo( - string, - { goodbye: ['foo'], world: 'world' }, - 'GOODBYE cruel world!', - 'if with non-empty array shows the contents' - ); - shouldCompileTo( - string, - { goodbye: [], world: 'world' }, - 'cruel world!', - 'if with empty array does not show the contents' - ); - shouldCompileTo( - string, - { goodbye: 0, world: 'world' }, - 'cruel world!', - 'if with zero does not show the contents' - ); - shouldCompileTo( - '{{#if goodbye includeZero=true}}GOODBYE {{/if}}cruel {{world}}!', - { goodbye: 0, world: 'world' }, - 'GOODBYE cruel world!', - 'if with zero does not show the contents' - ); + expectTemplate(string) + .withInput({ + goodbye: true, + world: 'world' + }) + .withMessage('if with boolean argument shows the contents when true') + .toCompileTo('GOODBYE cruel world!'); + expectTemplate(string) + .withInput({ + goodbye: 'dummy', + world: 'world' + }) + .withMessage('if with string argument shows the contents') + .toCompileTo('GOODBYE cruel world!'); + expectTemplate(string) + .withInput({ + goodbye: false, + world: 'world' + }) + .withMessage( + 'if with boolean argument does not show the contents when false' + ) + .toCompileTo('cruel world!'); + expectTemplate(string) + .withInput({ world: 'world' }) + .withMessage('if with undefined does not show the contents') + .toCompileTo('cruel world!'); + expectTemplate(string) + .withInput({ + goodbye: ['foo'], + world: 'world' + }) + .withMessage('if with non-empty array shows the contents') + .toCompileTo('GOODBYE cruel world!'); + expectTemplate(string) + .withInput({ + goodbye: [], + world: 'world' + }) + .withMessage('if with empty array does not show the contents') + .toCompileTo('cruel world!'); + expectTemplate(string) + .withInput({ + goodbye: 0, + world: 'world' + }) + .withMessage('if with zero does not show the contents') + .toCompileTo('cruel world!'); + expectTemplate( + '{{#if goodbye includeZero=true}}GOODBYE {{/if}}cruel {{world}}!' + ) + .withInput({ + goodbye: 0, + world: 'world' + }) + .withMessage('if with zero does not show the contents') + .toCompileTo('GOODBYE cruel world!'); }); it('if with function argument', function() { var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!'; - shouldCompileTo( - string, - { + expectTemplate(string) + .withInput({ goodbye: function() { return true; }, world: 'world' - }, - 'GOODBYE cruel world!', - 'if with function shows the contents when function returns true' - ); - shouldCompileTo( - string, - { + }) + .withMessage( + 'if with function shows the contents when function returns true' + ) + .toCompileTo('GOODBYE cruel world!'); + expectTemplate(string) + .withInput({ goodbye: function() { return this.world; }, world: 'world' - }, - 'GOODBYE cruel world!', - 'if with function shows the contents when function returns string' - ); - shouldCompileTo( - string, - { + }) + .withMessage( + 'if with function shows the contents when function returns string' + ) + .toCompileTo('GOODBYE cruel world!'); + expectTemplate(string) + .withInput({ goodbye: function() { return false; }, world: 'world' - }, - 'cruel world!', - 'if with function does not show the contents when returns false' - ); - shouldCompileTo( - string, - { + }) + .withMessage( + 'if with function does not show the contents when returns false' + ) + .toCompileTo('cruel world!'); + expectTemplate(string) + .withInput({ goodbye: function() { return this.foo; }, world: 'world' - }, - 'cruel world!', - 'if with function does not show the contents when returns undefined' - ); + }) + .withMessage( + 'if with function does not show the contents when returns undefined' + ) + .toCompileTo('cruel world!'); }); it('should not change the depth list', function() { var string = '{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}'; - shouldCompileTo( - string, - { foo: { goodbye: true }, world: 'world' }, - 'GOODBYE cruel world!' - ); + expectTemplate(string) + .withInput({ + foo: { goodbye: true }, + world: 'world' + }) + .toCompileTo('GOODBYE cruel world!'); }); }); describe('#with', function() { it('with', function() { var string = '{{#with person}}{{first}} {{last}}{{/with}}'; - shouldCompileTo( - string, - { person: { first: 'Alan', last: 'Johnson' } }, - 'Alan Johnson' - ); + expectTemplate(string) + .withInput({ + person: { + first: 'Alan', + last: 'Johnson' + } + }) + .toCompileTo('Alan Johnson'); }); it('with with function argument', function() { var string = '{{#with person}}{{first}} {{last}}{{/with}}'; - shouldCompileTo( - string, - { + expectTemplate(string) + .withInput({ person: function() { - return { first: 'Alan', last: 'Johnson' }; + return { + first: 'Alan', + last: 'Johnson' + }; } - }, - 'Alan Johnson' - ); + }) + .toCompileTo('Alan Johnson'); }); it('with with else', function() { var string = '{{#with person}}Person is present{{else}}Person is not present{{/with}}'; - shouldCompileTo(string, {}, 'Person is not present'); + expectTemplate(string).toCompileTo('Person is not present'); }); it('with provides block parameter', function() { var string = '{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}'; - shouldCompileTo( - string, - { person: { first: 'Alan', last: 'Johnson' } }, - 'Alan Johnson' - ); + expectTemplate(string) + .withInput({ + person: { + first: 'Alan', + last: 'Johnson' + } + }) + .toCompileTo('Alan Johnson'); }); it('works when data is disabled', function() { expectTemplate('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}') @@ -170,18 +187,19 @@ describe('builtin helpers', function() { ], world: 'world' }; - shouldCompileTo( - string, - hash, - 'goodbye! Goodbye! GOODBYE! cruel world!', - 'each with array argument iterates over the contents when not empty' - ); - shouldCompileTo( - string, - { goodbyes: [], world: 'world' }, - 'cruel world!', - 'each with array argument ignores the contents when empty' - ); + expectTemplate(string) + .withInput(hash) + .withMessage( + 'each with array argument iterates over the contents when not empty' + ) + .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); + expectTemplate(string) + .withInput({ + goodbyes: [], + world: 'world' + }) + .withMessage('each with array argument ignores the contents when empty') + .toCompileTo('cruel world!'); }); it('each without data', function() { @@ -194,23 +212,25 @@ describe('builtin helpers', function() { ], world: 'world' }; - shouldCompileTo( - string, - [hash, , , , false], - 'goodbye! Goodbye! GOODBYE! cruel world!' - ); + expectTemplate(string) + .withInput(hash) + .withRuntimeOptions({ data: false }) + .withCompileOptions({ data: false }) + .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); hash = { goodbyes: 'cruel', world: 'world' }; - shouldCompileTo( - '{{#each .}}{{.}}{{/each}}', - [hash, , , , false], - 'cruelworld' - ); + expectTemplate('{{#each .}}{{.}}{{/each}}') + .withInput(hash) + .withRuntimeOptions({ data: false }) + .withCompileOptions({ data: false }) + .toCompileTo('cruelworld'); }); it('each without context', function() { var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!'; - shouldCompileTo(string, [, , , ,], 'cruel !'); + expectTemplate(string) + .withInput(undefined) + .toCompileTo('cruel !'); }); it('each with an object and @key', function() { @@ -238,7 +258,12 @@ describe('builtin helpers', function() { true, 'each with object argument iterates over the contents when not empty' ); - shouldCompileTo(string, { goodbyes: {}, world: 'world' }, 'cruel world!'); + expectTemplate(string) + .withInput({ + goodbyes: {}, + world: 'world' + }) + .toCompileTo('cruel world!'); }); it('each with @index', function() { @@ -428,18 +453,21 @@ describe('builtin helpers', function() { }, world: 'world' }; - shouldCompileTo( - string, - hash, - 'goodbye! Goodbye! GOODBYE! cruel world!', - 'each with array function argument iterates over the contents when not empty' - ); - shouldCompileTo( - string, - { goodbyes: [], world: 'world' }, - 'cruel world!', - 'each with array function argument ignores the contents when empty' - ); + expectTemplate(string) + .withInput(hash) + .withMessage( + 'each with array function argument iterates over the contents when not empty' + ) + .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); + expectTemplate(string) + .withInput({ + goodbyes: [], + world: 'world' + }) + .withMessage( + 'each with array function argument ignores the contents when empty' + ) + .toCompileTo('cruel world!'); }); it('each object when last key is an empty string', function() { @@ -511,18 +539,21 @@ describe('builtin helpers', function() { ]); var goodbyesEmpty = new Iterable([]); var hash = { goodbyes: goodbyes, world: 'world' }; - shouldCompileTo( - string, - hash, - 'goodbye! Goodbye! GOODBYE! cruel world!', - 'each with array argument iterates over the contents when not empty' - ); - shouldCompileTo( - string, - { goodbyes: goodbyesEmpty, world: 'world' }, - 'cruel world!', - 'each with array argument ignores the contents when empty' - ); + expectTemplate(string) + .withInput(hash) + .withMessage( + 'each with array argument iterates over the contents when not empty' + ) + .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!'); + expectTemplate(string) + .withInput({ + goodbyes: goodbyesEmpty, + world: 'world' + }) + .withMessage( + 'each with array argument ignores the contents when empty' + ) + .toCompileTo('cruel world!'); }); } }); @@ -555,7 +586,10 @@ describe('builtin helpers', function() { logArg = arg; }; - shouldCompileTo(string, hash, '', 'log should not display'); + expectTemplate(string) + .withInput(hash) + .withMessage('log should not display') + .toCompileTo(''); equals(1, levelArg, 'should call log with 1'); equals('whee', logArg, "should call log with 'whee'"); }); @@ -569,7 +603,11 @@ describe('builtin helpers', function() { logArg = arg; }; - shouldCompileTo(string, [hash, , , , { level: '03' }], ''); + expectTemplate(string) + .withInput(hash) + .withRuntimeOptions({ data: { level: '03' } }) + .withCompileOptions({ data: true }) + .toCompileTo(''); equals('03', levelArg); equals('whee', logArg); }); @@ -591,7 +629,9 @@ describe('builtin helpers', function() { console.log = $log; }; - shouldCompileTo(string, hash, ''); + expectTemplate(string) + .withInput(hash) + .toCompileTo(''); equals(true, called); }); it('should log at data level', function() { @@ -605,7 +645,11 @@ describe('builtin helpers', function() { console.error = $error; }; - shouldCompileTo(string, [hash, , , , { level: '03' }], ''); + expectTemplate(string) + .withInput(hash) + .withRuntimeOptions({ data: { level: '03' } }) + .withCompileOptions({ data: true }) + .toCompileTo(''); equals(true, called); }); it('should handle missing logger', function() { @@ -620,7 +664,11 @@ describe('builtin helpers', function() { console.log = $log; }; - shouldCompileTo(string, [hash, , , , { level: '03' }], ''); + expectTemplate(string) + .withInput(hash) + .withRuntimeOptions({ data: { level: '03' } }) + .withCompileOptions({ data: true }) + .toCompileTo(''); equals(true, called); }); @@ -634,12 +682,20 @@ describe('builtin helpers', function() { called = true; }; - shouldCompileTo(string, [hash, , , , { level: 'error' }], ''); + expectTemplate(string) + .withInput(hash) + .withRuntimeOptions({ data: { level: 'error' } }) + .withCompileOptions({ data: true }) + .toCompileTo(''); equals(true, called); called = false; - shouldCompileTo(string, [hash, , , , { level: 'ERROR' }], ''); + expectTemplate(string) + .withInput(hash) + .withRuntimeOptions({ data: { level: 'ERROR' } }) + .withCompileOptions({ data: true }) + .toCompileTo(''); equals(true, called); }); it('should handle hash log levels', function() { @@ -652,7 +708,9 @@ describe('builtin helpers', function() { called = true; }; - shouldCompileTo(string, hash, ''); + expectTemplate(string) + .withInput(hash) + .toCompileTo(''); equals(true, called); }); it('should handle hash log levels', function() { @@ -665,7 +723,9 @@ describe('builtin helpers', function() { console.info = console.log = console.error = console.debug = $log; }; - shouldCompileTo(string, hash, ''); + expectTemplate(string) + .withInput(hash) + .toCompileTo(''); equals(false, called); }); it('should pass multiple log arguments', function() { @@ -681,7 +741,9 @@ describe('builtin helpers', function() { console.log = $log; }; - shouldCompileTo(string, hash, ''); + expectTemplate(string) + .withInput(hash) + .toCompileTo(''); equals(true, called); }); diff --git a/spec/helpers.js b/spec/helpers.js index b3eefa236..59960b384 100644 --- a/spec/helpers.js +++ b/spec/helpers.js @@ -12,11 +12,10 @@ describe('helpers', function() { ); } }; - shouldCompileTo( - string, - [hash, helpers], - 'Goodbye' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('Goodbye'); }); it('helper for raw block gets raw content', function() { @@ -27,12 +26,11 @@ describe('helpers', function() { return options.fn(); } }; - shouldCompileTo( - string, - [hash, helpers], - ' {{test}} ', - 'raw block helper gets raw content' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .withMessage('raw block helper gets raw content') + .toCompileTo(' {{test}} '); }); it('helper for raw block gets parameters', function() { @@ -43,12 +41,11 @@ describe('helpers', function() { return options.fn() + a + b + c; } }; - shouldCompileTo( - string, - [hash, helpers], - ' {{test}} 123', - 'raw block helper gets raw content' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .withMessage('raw block helper gets raw content') + .toCompileTo(' {{test}} 123'); }); describe('raw block parsing (with identity helper-function)', function() { @@ -58,7 +55,9 @@ describe('helpers', function() { return options.fn(); } }; - shouldCompileTo(template, [{}, helpers], expected); + expectTemplate(template) + .withHelpers(helpers) + .toCompileTo(expected); } it('helper for nested raw block gets raw content', function() { @@ -109,11 +108,10 @@ describe('helpers', function() { return out; } }; - shouldCompileTo( - string, - [hash, helpers], - 'Goodbye Alan! goodbye Alan! GOODBYE Alan! ' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('Goodbye Alan! goodbye Alan! GOODBYE Alan! '); }); it('helper block with complex lookup expression', function() { var string = '{{#goodbyes}}{{../name}}{{/goodbyes}}'; @@ -128,11 +126,10 @@ describe('helpers', function() { return out; } }; - shouldCompileTo( - string, - [hash, helpers], - 'Goodbye Alan! goodbye Alan! GOODBYE Alan! ' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('Goodbye Alan! goodbye Alan! GOODBYE Alan! '); }); it('helper with complex lookup and nested template', function() { @@ -155,12 +152,10 @@ describe('helpers', function() { ); } }; - shouldCompileToWithPartials( - string, - [hash, helpers], - false, - 'Goodbye' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('Goodbye'); }); it('helper with complex lookup and nested template in VM+Compiler', function() { @@ -183,20 +178,22 @@ describe('helpers', function() { ); } }; - shouldCompileToWithPartials( - string, - [hash, helpers], - true, - 'Goodbye' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('Goodbye'); }); it('helper returning undefined value', function() { - shouldCompileTo(' {{nothere}}', [{}, { nothere: function() {} }], ' '); - shouldCompileTo( - ' {{#nothere}}{{/nothere}}', - [{}, { nothere: function() {} }], - ' ' - ); + expectTemplate(' {{nothere}}') + .withHelpers({ + nothere: function() {} + }) + .toCompileTo(' '); + expectTemplate(' {{#nothere}}{{/nothere}}') + .withHelpers({ + nothere: function() {} + }) + .toCompileTo(' '); }); it('block helper', function() { @@ -246,15 +243,16 @@ describe('helpers', function() { ] }; - shouldCompileTo( - source, - [data, { link: link }], - '' - ); + expectTemplate(source) + .withInput(data) + .withHelpers({ link: link }) + .toCompileTo( + '' + ); }); it('block helper for undefined value', function() { - shouldCompileTo("{{#empty}}shouldn't render{{/empty}}", {}, ''); + expectTemplate("{{#empty}}shouldn't render{{/empty}}").toCompileTo(''); }); it('block helper passing a new context', function() { @@ -342,24 +340,21 @@ describe('helpers', function() { // the meaning here may be kind of hard to catch, but list.not is always called, // so we should see the output of both - shouldCompileTo( - string, - [hash, { list: list }], - '
  • Alan
  • Yehuda
', - 'an inverse wrapper is passed in as a new context' - ); - shouldCompileTo( - string, - [empty, { list: list }], - "

Nobody's here

", - 'an inverse wrapper can be optionally called' - ); - shouldCompileTo( - messageString, - [rootMessage, { list: list }], - '

Nobody's here

', - 'the context of an inverse is the parent of the block' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers({ list: list }) + .withMessage('an inverse wrapper is passed in as a new context') + .toCompileTo('
  • Alan
  • Yehuda
'); + expectTemplate(string) + .withInput(empty) + .withHelpers({ list: list }) + .withMessage('an inverse wrapper can be optionally called') + .toCompileTo("

Nobody's here

"); + expectTemplate(messageString) + .withInput(rootMessage) + .withHelpers({ list: list }) + .withMessage('the context of an inverse is the parent of the block') + .toCompileTo('

Nobody's here

'); }); it('pathed lambas with parameters', function() { @@ -374,84 +369,70 @@ describe('helpers', function() { return 'fail'; } }; - shouldCompileTo('{{./helper 1}}', [hash, helpers], 'winning'); - shouldCompileTo('{{hash/helper 1}}', [hash, helpers], 'winning'); + expectTemplate('{{./helper 1}}') + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('winning'); + expectTemplate('{{hash/helper 1}}') + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('winning'); }); describe('helpers hash', function() { it('providing a helpers hash', function() { - shouldCompileTo( - 'Goodbye {{cruel}} {{world}}!', - [ - { cruel: 'cruel' }, - { - world: function() { - return 'world'; - } + expectTemplate('Goodbye {{cruel}} {{world}}!') + .withInput({ cruel: 'cruel' }) + .withHelpers({ + world: function() { + return 'world'; } - ], - 'Goodbye cruel world!', - 'helpers hash is available' - ); - - shouldCompileTo( - 'Goodbye {{#iter}}{{cruel}} {{world}}{{/iter}}!', - [ - { iter: [{ cruel: 'cruel' }] }, - { - world: function() { - return 'world'; - } + }) + .withMessage('helpers hash is available') + .toCompileTo('Goodbye cruel world!'); + + expectTemplate('Goodbye {{#iter}}{{cruel}} {{world}}{{/iter}}!') + .withInput({ iter: [{ cruel: 'cruel' }] }) + .withHelpers({ + world: function() { + return 'world'; } - ], - 'Goodbye cruel world!', - 'helpers hash is available inside other blocks' - ); + }) + .withMessage('helpers hash is available inside other blocks') + .toCompileTo('Goodbye cruel world!'); }); it('in cases of conflict, helpers win', function() { - shouldCompileTo( - '{{{lookup}}}', - [ - { lookup: 'Explicit' }, - { - lookup: function() { - return 'helpers'; - } + expectTemplate('{{{lookup}}}') + .withInput({ lookup: 'Explicit' }) + .withHelpers({ + lookup: function() { + return 'helpers'; } - ], - 'helpers', - 'helpers hash has precedence escaped expansion' - ); - shouldCompileTo( - '{{lookup}}', - [ - { lookup: 'Explicit' }, - { - lookup: function() { - return 'helpers'; - } + }) + .withMessage('helpers hash has precedence escaped expansion') + .toCompileTo('helpers'); + expectTemplate('{{lookup}}') + .withInput({ lookup: 'Explicit' }) + .withHelpers({ + lookup: function() { + return 'helpers'; } - ], - 'helpers', - 'helpers hash has precedence simple expansion' - ); + }) + .withMessage('helpers hash has precedence simple expansion') + .toCompileTo('helpers'); }); it('the helpers hash is available is nested contexts', function() { - shouldCompileTo( - '{{#outer}}{{#inner}}{{helper}}{{/inner}}{{/outer}}', - [ - { outer: { inner: { unused: [] } } }, - { - helper: function() { - return 'helper'; - } + expectTemplate('{{#outer}}{{#inner}}{{helper}}{{/inner}}{{/outer}}') + .withInput({ outer: { inner: { unused: [] } } }) + .withHelpers({ + helper: function() { + return 'helper'; } - ], - 'helper', - 'helpers hash is available in nested contexts.' - ); + }) + .withMessage('helpers hash is available in nested contexts.') + .toCompileTo('helper'); }); it('the helper hash should augment the global hash', function() { @@ -459,18 +440,16 @@ describe('helpers', function() { return 'found it!'; }); - shouldCompileTo( - '{{test_helper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}', - [ - { cruel: 'cruel' }, - { - world: function() { - return 'world!'; - } + expectTemplate( + '{{test_helper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}' + ) + .withInput({ cruel: 'cruel' }) + .withHelpers({ + world: function() { + return 'world!'; } - ], - 'found it! Goodbye cruel world!!' - ); + }) + .toCompileTo('found it! Goodbye cruel world!!'); }); }); @@ -499,11 +478,11 @@ describe('helpers', function() { } }); - shouldCompileTo( - '{{testHelper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}', - [{ cruel: 'cruel' }], - 'found it! Goodbye cruel world!!' - ); + expectTemplate( + '{{testHelper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}' + ) + .withInput({ cruel: 'cruel' }) + .toCompileTo('found it! Goodbye cruel world!!'); }); it('fails with multiple and args', function() { shouldThrow( @@ -539,12 +518,10 @@ describe('helpers', function() { return 'Hello ' + times + ' ' + times2 + ' times'; } }; - shouldCompileTo( - string, - [{}, helpers], - 'Message: Hello -1.2 1.2 times', - 'template with a negative integer literal' - ); + expectTemplate(string) + .withHelpers(helpers) + .withMessage('template with a negative integer literal') + .toCompileTo('Message: Hello -1.2 1.2 times'); }); it('negative number literals work', function() { @@ -557,12 +534,10 @@ describe('helpers', function() { return 'Hello ' + times + ' times'; } }; - shouldCompileTo( - string, - [{}, helpers], - 'Message: Hello -12 times', - 'template with a negative integer literal' - ); + expectTemplate(string) + .withHelpers(helpers) + .withMessage('template with a negative integer literal') + .toCompileTo('Message: Hello -12 times'); }); describe('String literal parameters', function() { @@ -584,12 +559,10 @@ describe('helpers', function() { ); } }; - shouldCompileTo( - string, - [{}, helpers], - 'Message: Hello world 12 times: true false', - 'template with a simple String literal' - ); + expectTemplate(string) + .withHelpers(helpers) + .withMessage('template with a simple String literal') + .toCompileTo('Message: Hello world 12 times: true false'); }); it('using a quote in the middle of a parameter raises an error', function() { @@ -604,12 +577,10 @@ describe('helpers', function() { return 'Hello ' + param; } }; - shouldCompileTo( - string, - [{}, helpers], - 'Message: Hello "world"', - 'template with an escaped String literal' - ); + expectTemplate(string) + .withHelpers(helpers) + .withMessage('template with an escaped String literal') + .toCompileTo('Message: Hello "world"'); }); it("it works with ' marks", function() { @@ -619,12 +590,10 @@ describe('helpers', function() { return 'Hello ' + param; } }; - shouldCompileTo( - string, - [{}, helpers], - "Message: Hello Alan's world", - "template with a ' mark" - ); + expectTemplate(string) + .withHelpers(helpers) + .withMessage("template with a ' mark") + .toCompileTo("Message: Hello Alan's world"); }); }); @@ -638,12 +607,10 @@ describe('helpers', function() { return 'Hello ' + times + ' times'; } }; - shouldCompileTo( - string, - [{}, helpers], - 'Message: Hello -12 times', - 'template with a negative integer literal' - ); + expectTemplate(string) + .withHelpers(helpers) + .withMessage('template with a negative integer literal') + .toCompileTo('Message: Hello -12 times'); }); describe('multiple parameters', function() { @@ -655,12 +622,11 @@ describe('helpers', function() { return 'Goodbye ' + cruel + ' ' + world; } }; - shouldCompileTo( - string, - [hash, helpers], - 'Message: Goodbye cruel world', - 'regular helpers with multiple params' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .withMessage('regular helpers with multiple params') + .toCompileTo('Message: Goodbye cruel world'); }); it('block multi-params work', function() { @@ -672,12 +638,11 @@ describe('helpers', function() { return options.fn({ greeting: 'Goodbye', adj: cruel, noun: world }); } }; - shouldCompileTo( - string, - [hash, helpers], - 'Message: Goodbye cruel world', - 'block helpers with multiple params' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .withMessage('block helpers with multiple params') + .toCompileTo('Message: Goodbye cruel world'); }); }); @@ -826,7 +791,10 @@ describe('helpers', function() { } }; - shouldCompileTo(string, [context, helpers], 'Hello world'); + expectTemplate(string) + .withInput(context) + .withHelpers(helpers) + .toCompileTo('Hello world'); }); it('if a value is not found, custom helperMissing is used', function() { @@ -841,7 +809,10 @@ describe('helpers', function() { } }; - shouldCompileTo(string, [context, helpers], 'Hello winning'); + expectTemplate(string) + .withInput(context) + .withHelpers(helpers) + .toCompileTo('Hello winning'); }); }); @@ -962,7 +933,9 @@ describe('helpers', function() { return true; } }; - shouldCompileTo(string, data, 'yep'); + expectTemplate(string) + .withInput(data) + .toCompileTo('yep'); }); it('lambdas resolved by blockHelperMissing are bound to the context', function() { var string = '{{#truthy}}yep{{/truthy}}'; @@ -974,7 +947,9 @@ describe('helpers', function() { return false; } }; - shouldCompileTo(string, boundData, ''); + expectTemplate(string) + .withInput(boundData) + .toCompileTo(''); }); }); @@ -993,31 +968,34 @@ describe('helpers', function() { }; it('should include in ambiguous mustache calls', function() { - shouldCompileTo('{{helper}}', [context, helpers], 'ran: helper'); + expectTemplate('{{helper}}') + .withInput(context) + .withHelpers(helpers) + .toCompileTo('ran: helper'); }); it('should include in helper mustache calls', function() { - shouldCompileTo('{{helper 1}}', [context, helpers], 'ran: helper'); + expectTemplate('{{helper 1}}') + .withInput(context) + .withHelpers(helpers) + .toCompileTo('ran: helper'); }); it('should include in ambiguous block calls', function() { - shouldCompileTo( - '{{#helper}}{{/helper}}', - [context, helpers], - 'ran: helper' - ); + expectTemplate('{{#helper}}{{/helper}}') + .withInput(context) + .withHelpers(helpers) + .toCompileTo('ran: helper'); }); it('should include in simple block calls', function() { - shouldCompileTo( - '{{#./helper}}{{/./helper}}', - [context, helpers], - 'missing: ./helper' - ); + expectTemplate('{{#./helper}}{{/./helper}}') + .withInput(context) + .withHelpers(helpers) + .toCompileTo('missing: ./helper'); }); it('should include in helper block calls', function() { - shouldCompileTo( - '{{#helper 1}}{{/helper}}', - [context, helpers], - 'ran: helper' - ); + expectTemplate('{{#helper 1}}{{/helper}}') + .withInput(context) + .withHelpers(helpers) + .toCompileTo('ran: helper'); }); it('should include in known helper calls', function() { var string = '{{helper}}'; @@ -1033,19 +1011,17 @@ describe('helpers', function() { }); it('should include full id', function() { - shouldCompileTo( - '{{#foo.helper}}{{/foo.helper}}', - [{ foo: {} }, helpers], - 'missing: foo.helper' - ); + expectTemplate('{{#foo.helper}}{{/foo.helper}}') + .withInput({ foo: {} }) + .withHelpers(helpers) + .toCompileTo('missing: foo.helper'); }); it('should include full id if a hash is passed', function() { - shouldCompileTo( - '{{#foo.helper bar=baz}}{{/foo.helper}}', - [{ foo: {} }, helpers], - 'helper missing: foo.helper' - ); + expectTemplate('{{#foo.helper bar=baz}}{{/foo.helper}}') + .withInput({ foo: {} }) + .withHelpers(helpers) + .toCompileTo('helper missing: foo.helper'); }); }); @@ -1160,11 +1136,10 @@ describe('helpers', function() { return options.fn({ value: 'bar' }, { blockParams: [1, 2] }); } }; - shouldCompileTo( - '{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}', - [hash, helpers], - '1foo' - ); + expectTemplate('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}') + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('1foo'); }); it('should take presedence over helper values', function() { var hash = {}; @@ -1177,11 +1152,10 @@ describe('helpers', function() { return options.fn({}, { blockParams: [1, 2] }); } }; - shouldCompileTo( - '{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}', - [hash, helpers], - '1foo' - ); + expectTemplate('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}') + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('1foo'); }); it('should not take presedence over pathed values', function() { var hash = { value: 'bar' }; @@ -1194,11 +1168,12 @@ describe('helpers', function() { return options.fn(this, { blockParams: [1, 2] }); } }; - shouldCompileTo( - '{{#goodbyes as |value|}}{{./value}}{{/goodbyes}}{{value}}', - [hash, helpers], - 'barfoo' - ); + expectTemplate( + '{{#goodbyes as |value|}}{{./value}}{{/goodbyes}}{{value}}' + ) + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('barfoo'); }); it('should take presednece over parent block params', function() { var hash = { value: 'foo' }, @@ -1214,11 +1189,12 @@ describe('helpers', function() { ); } }; - shouldCompileTo( - '{{#goodbyes as |value|}}{{#goodbyes}}{{value}}{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{/goodbyes}}{{/goodbyes}}{{value}}', - [hash, helpers], - '13foo' - ); + expectTemplate( + '{{#goodbyes as |value|}}{{#goodbyes}}{{value}}{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{/goodbyes}}{{/goodbyes}}{{value}}' + ) + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('13foo'); }); it('should allow block params on chained helpers', function() { @@ -1229,11 +1205,12 @@ describe('helpers', function() { return options.fn({ value: 'bar' }, { blockParams: [1, 2] }); } }; - shouldCompileTo( - '{{#if bar}}{{else goodbyes as |value|}}{{value}}{{/if}}{{value}}', - [hash, helpers], - '1foo' - ); + expectTemplate( + '{{#if bar}}{{else goodbyes as |value|}}{{value}}{{/if}}{{value}}' + ) + .withInput(hash) + .withHelpers(helpers) + .toCompileTo('1foo'); }); }); diff --git a/spec/javascript-compiler.js b/spec/javascript-compiler.js index e97cbb083..ed2dc8c56 100644 --- a/spec/javascript-compiler.js +++ b/spec/javascript-compiler.js @@ -20,14 +20,18 @@ describe('javascript-compiler api', function() { return parent + '.bar_' + name; }; /* eslint-disable camelcase */ - shouldCompileTo('{{foo}}', { bar_foo: 'food' }, 'food'); + expectTemplate('{{foo}}') + .withInput({ bar_foo: 'food' }) + .toCompileTo('food'); /* eslint-enable camelcase */ }); // Tests nameLookup dot vs. bracket behavior. Bracket is required in certain cases // to avoid errors in older browsers. it('should handle reserved words', function() { - shouldCompileTo('{{foo}} {{~null~}}', { foo: 'food' }, 'food'); + expectTemplate('{{foo}} {{~null~}}') + .withInput({ foo: 'food' }) + .toCompileTo('food'); }); }); describe('#compilerInfo', function() { @@ -49,7 +53,9 @@ describe('javascript-compiler api', function() { throw new Error("It didn't work"); } }; - shouldCompileTo('{{foo}} ', { foo: 'food' }, 'food '); + expectTemplate('{{foo}} ') + .withInput({ foo: 'food' }) + .toCompileTo('food '); }); }); describe('buffer', function() { @@ -70,7 +76,9 @@ describe('javascript-compiler api', function() { handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer = function() { return this.quotedString('foo_'); }; - shouldCompileTo('{{foo}} ', { foo: 'food' }, 'foo_food '); + expectTemplate('{{foo}} ') + .withInput({ foo: 'food' }) + .toCompileTo('foo_food '); }); it('should allow append buffer override', function() { handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = function( @@ -78,7 +86,9 @@ describe('javascript-compiler api', function() { ) { return $superAppend.call(this, [string, ' + "_foo"']); }; - shouldCompileTo('{{foo}}', { foo: 'food' }, 'food_foo'); + expectTemplate('{{foo}}') + .withInput({ foo: 'food' }) + .toCompileTo('food_foo'); }); }); diff --git a/spec/partials.js b/spec/partials.js index 019c71d94..a98bfd23f 100644 --- a/spec/partials.js +++ b/spec/partials.js @@ -8,18 +8,16 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }], - true, - 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ' - ); - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }, , false], - true, - 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .withRuntimeOptions({ data: false }) + .withCompileOptions({ data: false }) + .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); }); it('dynamic partials', function() { @@ -36,18 +34,18 @@ describe('partials', function() { return 'dude'; } }; - shouldCompileToWithPartials( - string, - [hash, helpers, { dude: partial }], - true, - 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ' - ); - shouldCompileToWithPartials( - string, - [hash, helpers, { dude: partial }, , false], - true, - 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ' - ); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .withPartials({ dude: partial }) + .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); + expectTemplate(string) + .withInput(hash) + .withHelpers(helpers) + .withPartials({ dude: partial }) + .withRuntimeOptions({ data: false }) + .withCompileOptions({ data: false }) + .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); }); it('failing dynamic partials', function() { var string = 'Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}'; @@ -79,13 +77,11 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }], - true, - 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ', - 'Partials can be passed a context' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .withMessage('Partials can be passed a context') + .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); }); it('partials with no context', function() { @@ -96,42 +92,36 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - 'Dudes: {{#dudes}}{{>dude}}{{/dudes}}', - [hash, {}, { dude: partial }, { explicitPartialContext: true }], - true, - 'Dudes: () () ' - ); - shouldCompileToWithPartials( - 'Dudes: {{#dudes}}{{>dude name="foo"}}{{/dudes}}', - [hash, {}, { dude: partial }, { explicitPartialContext: true }], - true, - 'Dudes: foo () foo () ' - ); + expectTemplate('Dudes: {{#dudes}}{{>dude}}{{/dudes}}') + .withInput(hash) + .withPartials({ dude: partial }) + .withCompileOptions({ explicitPartialContext: true }) + .toCompileTo('Dudes: () () '); + expectTemplate('Dudes: {{#dudes}}{{>dude name="foo"}}{{/dudes}}') + .withInput(hash) + .withPartials({ dude: partial }) + .withCompileOptions({ explicitPartialContext: true }) + .toCompileTo('Dudes: foo () foo () '); }); it('partials with string context', function() { var string = 'Dudes: {{>dude "dudes"}}'; var partial = '{{.}}'; var hash = {}; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }], - true, - 'Dudes: dudes' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .toCompileTo('Dudes: dudes'); }); it('partials with undefined context', function() { var string = 'Dudes: {{>dude dudes}}'; var partial = '{{foo}} Empty'; var hash = {}; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }], - true, - 'Dudes: Empty' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .toCompileTo('Dudes: Empty'); }); it('partials with duplicate parameters', function() { @@ -151,13 +141,11 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }], - true, - 'Dudes: barYehuda (http://yehuda) barAlan (http://alan) ', - 'Basic partials output based on current context.' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .withMessage('Basic partials output based on current context.') + .toCompileTo('Dudes: barYehuda (http://yehuda) barAlan (http://alan) '); }); it('partial in a partial', function() { @@ -170,13 +158,16 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: dude, url: url }], - true, - 'Dudes: Yehuda http://yehuda Alan http://alan ', - 'Partials are rendered inside of other partials' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ + dude: dude, + url: url + }) + .withMessage('Partials are rendered inside of other partials') + .toCompileTo( + 'Dudes: Yehuda http://yehuda Alan http://alan ' + ); }); it('rendering undefined partial throws an exception', function() { @@ -215,51 +206,44 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileTo( - string, - [hash, {}, { dude: partial }], - 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ', - 'Function partials output based in VM.' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .withMessage('Function partials output based in VM.') + .toCompileTo('Dudes: Yehuda (http://yehuda) Alan (http://alan) '); }); it('GH-14: a partial preceding a selector', function() { var string = 'Dudes: {{>dude}} {{anotherDude}}'; var dude = '{{name}}'; var hash = { name: 'Jeepers', anotherDude: 'Creepers' }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: dude }], - true, - 'Dudes: Jeepers Creepers', - 'Regular selectors can follow a partial' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: dude }) + .withMessage('Regular selectors can follow a partial') + .toCompileTo('Dudes: Jeepers Creepers'); }); it('Partials with slash paths', function() { var string = 'Dudes: {{> shared/dude}}'; var dude = '{{name}}'; var hash = { name: 'Jeepers', anotherDude: 'Creepers' }; - shouldCompileToWithPartials( - string, - [hash, {}, { 'shared/dude': dude }], - true, - 'Dudes: Jeepers', - 'Partials can use literal paths' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ 'shared/dude': dude }) + .withMessage('Partials can use literal paths') + .toCompileTo('Dudes: Jeepers'); }); it('Partials with slash and point paths', function() { var string = 'Dudes: {{> shared/dude.thing}}'; var dude = '{{name}}'; var hash = { name: 'Jeepers', anotherDude: 'Creepers' }; - shouldCompileToWithPartials( - string, - [hash, {}, { 'shared/dude.thing': dude }], - true, - 'Dudes: Jeepers', - 'Partials can use literal with points in paths' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ 'shared/dude.thing': dude }) + .withMessage('Partials can use literal with points in paths') + .toCompileTo('Dudes: Jeepers'); }); it('Global Partials', function() { @@ -268,13 +252,11 @@ describe('partials', function() { var string = 'Dudes: {{> shared/dude}} {{> globalTest}}'; var dude = '{{name}}'; var hash = { name: 'Jeepers', anotherDude: 'Creepers' }; - shouldCompileToWithPartials( - string, - [hash, {}, { 'shared/dude': dude }], - true, - 'Dudes: Jeepers Creepers', - 'Partials can use globals or passed' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ 'shared/dude': dude }) + .withMessage('Partials can use globals or passed') + .toCompileTo('Dudes: Jeepers Creepers'); handlebarsEnv.unregisterPartial('globalTest'); equals(handlebarsEnv.partials.globalTest, undefined); @@ -299,52 +281,44 @@ describe('partials', function() { var string = 'Dudes: {{> 404}}'; var dude = '{{name}}'; var hash = { name: 'Jeepers', anotherDude: 'Creepers' }; - shouldCompileToWithPartials( - string, - [hash, {}, { 404: dude }], - true, - 'Dudes: Jeepers', - 'Partials can use literal paths' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ 404: dude }) + .withMessage('Partials can use literal paths') + .toCompileTo('Dudes: Jeepers'); }); it('Partials with complex path', function() { var string = 'Dudes: {{> 404/asdf?.bar}}'; var dude = '{{name}}'; var hash = { name: 'Jeepers', anotherDude: 'Creepers' }; - shouldCompileToWithPartials( - string, - [hash, {}, { '404/asdf?.bar': dude }], - true, - 'Dudes: Jeepers', - 'Partials can use literal paths' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ '404/asdf?.bar': dude }) + .withMessage('Partials can use literal paths') + .toCompileTo('Dudes: Jeepers'); }); it('Partials with escaped', function() { var string = 'Dudes: {{> [+404/asdf?.bar]}}'; var dude = '{{name}}'; var hash = { name: 'Jeepers', anotherDude: 'Creepers' }; - shouldCompileToWithPartials( - string, - [hash, {}, { '+404/asdf?.bar': dude }], - true, - 'Dudes: Jeepers', - 'Partials can use literal paths' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ '+404/asdf?.bar': dude }) + .withMessage('Partials can use literal paths') + .toCompileTo('Dudes: Jeepers'); }); it('Partials with string', function() { var string = "Dudes: {{> '+404/asdf?.bar'}}"; var dude = '{{name}}'; var hash = { name: 'Jeepers', anotherDude: 'Creepers' }; - shouldCompileToWithPartials( - string, - [hash, {}, { '+404/asdf?.bar': dude }], - true, - 'Dudes: Jeepers', - 'Partials can use literal paths' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ '+404/asdf?.bar': dude }) + .withMessage('Partials can use literal paths') + .toCompileTo('Dudes: Jeepers'); }); it('should handle empty partial', function() { @@ -356,12 +330,10 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }], - true, - 'Dudes: ' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .toCompileTo('Dudes: '); }); it('throw on missing partial', function() { @@ -378,305 +350,231 @@ describe('partials', function() { describe('partial blocks', function() { it('should render partial block as default', function() { - shouldCompileToWithPartials( - '{{#> dude}}success{{/dude}}', - [{}, {}, {}], - true, - 'success' - ); + expectTemplate('{{#> dude}}success{{/dude}}').toCompileTo('success'); }); it('should execute default block with proper context', function() { - shouldCompileToWithPartials( - '{{#> dude context}}{{value}}{{/dude}}', - [{ context: { value: 'success' } }, {}, {}], - true, - 'success' - ); + expectTemplate('{{#> dude context}}{{value}}{{/dude}}') + .withInput({ context: { value: 'success' } }) + .toCompileTo('success'); }); it('should propagate block parameters to default block', function() { - shouldCompileToWithPartials( - '{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}', - [{ context: { value: 'success' } }, {}, {}], - true, - 'success' - ); + expectTemplate( + '{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}' + ) + .withInput({ context: { value: 'success' } }) + .toCompileTo('success'); }); it('should not use partial block if partial exists', function() { - shouldCompileToWithPartials( - '{{#> dude}}fail{{/dude}}', - [{}, {}, { dude: 'success' }], - true, - 'success' - ); + expectTemplate('{{#> dude}}fail{{/dude}}') + .withPartials({ dude: 'success' }) + .toCompileTo('success'); }); it('should render block from partial', function() { - shouldCompileToWithPartials( - '{{#> dude}}success{{/dude}}', - [{}, {}, { dude: '{{> @partial-block }}' }], - true, - 'success' - ); + expectTemplate('{{#> dude}}success{{/dude}}') + .withPartials({ dude: '{{> @partial-block }}' }) + .toCompileTo('success'); }); it('should be able to render the partial-block twice', function() { - shouldCompileToWithPartials( - '{{#> dude}}success{{/dude}}', - [{}, {}, { dude: '{{> @partial-block }} {{> @partial-block }}' }], - true, - 'success success' - ); + expectTemplate('{{#> dude}}success{{/dude}}') + .withPartials({ dude: '{{> @partial-block }} {{> @partial-block }}' }) + .toCompileTo('success success'); }); it('should render block from partial with context', function() { - shouldCompileToWithPartials( - '{{#> dude}}{{value}}{{/dude}}', - [ - { context: { value: 'success' } }, - {}, - { dude: '{{#with context}}{{> @partial-block }}{{/with}}' } - ], - true, - 'success' - ); + expectTemplate('{{#> dude}}{{value}}{{/dude}}') + .withInput({ context: { value: 'success' } }) + .withPartials({ + dude: '{{#with context}}{{> @partial-block }}{{/with}}' + }) + .toCompileTo('success'); }); it('should be able to access the @data frame from a partial-block', function() { - shouldCompileToWithPartials( - '{{#> dude}}in-block: {{@root/value}}{{/dude}}', - [ - { value: 'success' }, - {}, - { - dude: - 'before-block: {{@root/value}} {{> @partial-block }}' - } - ], - true, - 'before-block: success in-block: success' - ); + expectTemplate('{{#> dude}}in-block: {{@root/value}}{{/dude}}') + .withInput({ value: 'success' }) + .withPartials({ + dude: + 'before-block: {{@root/value}} {{> @partial-block }}' + }) + .toCompileTo('before-block: success in-block: success'); }); it('should allow the #each-helper to be used along with partial-blocks', function() { - shouldCompileToWithPartials( - '', - [ - { value: ['a', 'b', 'c'] }, - {}, - { - list: - '{{#each .}}{{> @partial-block}}{{/each}}' - } - ], - true, - '' - ); + expectTemplate( + '' + ) + .withInput({ + value: ['a', 'b', 'c'] + }) + .withPartials({ + list: + '{{#each .}}{{> @partial-block}}{{/each}}' + }) + .toCompileTo( + '' + ); }); it('should render block from partial with context (twice)', function() { - shouldCompileToWithPartials( - '{{#> dude}}{{value}}{{/dude}}', - [ - { context: { value: 'success' } }, - {}, - { - dude: - '{{#with context}}{{> @partial-block }} {{> @partial-block }}{{/with}}' - } - ], - true, - 'success success' - ); + expectTemplate('{{#> dude}}{{value}}{{/dude}}') + .withInput({ context: { value: 'success' } }) + .withPartials({ + dude: + '{{#with context}}{{> @partial-block }} {{> @partial-block }}{{/with}}' + }) + .toCompileTo('success success'); }); it('should render block from partial with context', function() { - shouldCompileToWithPartials( - '{{#> dude}}{{../context/value}}{{/dude}}', - [ - { context: { value: 'success' } }, - {}, - { dude: '{{#with context}}{{> @partial-block }}{{/with}}' } - ], - true, - 'success' - ); + expectTemplate('{{#> dude}}{{../context/value}}{{/dude}}') + .withInput({ context: { value: 'success' } }) + .withPartials({ + dude: '{{#with context}}{{> @partial-block }}{{/with}}' + }) + .toCompileTo('success'); }); it('should render block from partial with block params', function() { - shouldCompileToWithPartials( - '{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}', - [ - { context: { value: 'success' } }, - {}, - { dude: '{{> @partial-block }}' } - ], - true, - 'success' - ); + expectTemplate( + '{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}' + ) + .withInput({ context: { value: 'success' } }) + .withPartials({ dude: '{{> @partial-block }}' }) + .toCompileTo('success'); }); it('should render nested partial blocks', function() { - shouldCompileToWithPartials( - '', - [ - { value: 'success' }, - {}, - { - outer: - '{{#> nested}}{{> @partial-block}}{{/nested}}', - nested: '{{> @partial-block}}' - } - ], - true, - '' - ); + expectTemplate('') + .withInput({ value: 'success' }) + .withPartials({ + outer: + '{{#> nested}}{{> @partial-block}}{{/nested}}', + nested: '{{> @partial-block}}' + }) + .toCompileTo( + '' + ); }); it('should render nested partial blocks at different nesting levels', function() { - shouldCompileToWithPartials( - '', - [ - { value: 'success' }, - {}, - { - outer: - '{{#> nested}}{{> @partial-block}}{{/nested}}{{> @partial-block}}', - nested: '{{> @partial-block}}' - } - ], - true, - '' - ); + expectTemplate('') + .withInput({ value: 'success' }) + .withPartials({ + outer: + '{{#> nested}}{{> @partial-block}}{{/nested}}{{> @partial-block}}', + nested: '{{> @partial-block}}' + }) + .toCompileTo( + '' + ); }); it('should render nested partial blocks at different nesting levels (twice)', function() { - shouldCompileToWithPartials( - '', - [ - { value: 'success' }, - {}, - { - outer: - '{{#> nested}}{{> @partial-block}} {{> @partial-block}}{{/nested}}{{> @partial-block}}+{{> @partial-block}}', - nested: '{{> @partial-block}}' - } - ], - true, - '' - ); + expectTemplate('') + .withInput({ value: 'success' }) + .withPartials({ + outer: + '{{#> nested}}{{> @partial-block}} {{> @partial-block}}{{/nested}}{{> @partial-block}}+{{> @partial-block}}', + nested: '{{> @partial-block}}' + }) + .toCompileTo( + '' + ); }); it('should render nested partial blocks (twice at each level)', function() { - shouldCompileToWithPartials( - '', - [ - { value: 'success' }, - {}, - { - outer: - '{{#> nested}}{{> @partial-block}} {{> @partial-block}}{{/nested}}', - nested: '{{> @partial-block}}{{> @partial-block}}' - } - ], - true, - '' - ); + expectTemplate('') + .withInput({ value: 'success' }) + .withPartials({ + outer: + '{{#> nested}}{{> @partial-block}} {{> @partial-block}}{{/nested}}', + nested: '{{> @partial-block}}{{> @partial-block}}' + }) + .toCompileTo( + '' + ); }); }); describe('inline partials', function() { it('should define inline partials for template', function() { - shouldCompileTo( - '{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}', - {}, - 'success' - ); + expectTemplate( + '{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}' + ).toCompileTo('success'); }); it('should overwrite multiple partials in the same template', function() { - shouldCompileTo( - '{{#*inline "myPartial"}}fail{{/inline}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}', - {}, - 'success' - ); + expectTemplate( + '{{#*inline "myPartial"}}fail{{/inline}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}' + ).toCompileTo('success'); }); it('should define inline partials for block', function() { - shouldCompileTo( - '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}', - {}, - 'success' - ); + expectTemplate( + '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}' + ).toCompileTo('success'); expectTemplate( '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{/with}}{{> myPartial}}' ).toThrow(Error, /myPartial could not/); }); it('should override global partials', function() { - shouldCompileTo( - '{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}', - { - hash: {}, - partials: { - myPartial: function() { - return 'fail'; - } + expectTemplate( + '{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}' + ) + .withPartials({ + myPartial: function() { + return 'fail'; } - }, - 'success' - ); + }) + .toCompileTo('success'); }); it('should override template partials', function() { - shouldCompileTo( - '{{#*inline "myPartial"}}fail{{/inline}}{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}', - {}, - 'success' - ); + expectTemplate( + '{{#*inline "myPartial"}}fail{{/inline}}{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}' + ).toCompileTo('success'); }); it('should override partials down the entire stack', function() { - shouldCompileTo( - '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{#with .}}{{#with .}}{{> myPartial}}{{/with}}{{/with}}{{/with}}', - {}, - 'success' - ); + expectTemplate( + '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{#with .}}{{#with .}}{{> myPartial}}{{/with}}{{/with}}{{/with}}' + ).toCompileTo('success'); }); it('should define inline partials for partial call', function() { - shouldCompileToWithPartials( - '{{#*inline "myPartial"}}success{{/inline}}{{> dude}}', - [{}, {}, { dude: '{{> myPartial }}' }], - true, - 'success' - ); + expectTemplate('{{#*inline "myPartial"}}success{{/inline}}{{> dude}}') + .withPartials({ dude: '{{> myPartial }}' }) + .toCompileTo('success'); }); it('should define inline partials in partial block call', function() { - shouldCompileToWithPartials( - '{{#> dude}}{{#*inline "myPartial"}}success{{/inline}}{{/dude}}', - [{}, {}, { dude: '{{> myPartial }}' }], - true, - 'success' - ); + expectTemplate( + '{{#> dude}}{{#*inline "myPartial"}}success{{/inline}}{{/dude}}' + ) + .withPartials({ dude: '{{> myPartial }}' }) + .toCompileTo('success'); }); it('should render nested inline partials', function() { - shouldCompileToWithPartials( + expectTemplate( '{{#*inline "outer"}}{{#>inner}}{{>@partial-block}}{{/inner}}{{/inline}}' + '{{#*inline "inner"}}{{>@partial-block}}{{/inline}}' + - '{{#>outer}}{{value}}{{/outer}}', - [{ value: 'success' }, {}, {}], - true, - 'success' - ); + '{{#>outer}}{{value}}{{/outer}}' + ) + .withInput({ value: 'success' }) + .toCompileTo('success'); }); it('should render nested inline partials with partial-blocks on different nesting levels', function() { - shouldCompileToWithPartials( + expectTemplate( '{{#*inline "outer"}}{{#>inner}}{{>@partial-block}}{{/inner}}{{>@partial-block}}{{/inline}}' + '{{#*inline "inner"}}{{>@partial-block}}{{/inline}}' + - '{{#>outer}}{{value}}{{/outer}}', - [{ value: 'success' }, {}, {}], - true, - 'successsuccess' - ); + '{{#>outer}}{{value}}{{/outer}}' + ) + .withInput({ value: 'success' }) + .toCompileTo( + 'successsuccess' + ); }); it('should render nested inline partials (twice at each level)', function() { - shouldCompileToWithPartials( + expectTemplate( '{{#*inline "outer"}}{{#>inner}}{{>@partial-block}} {{>@partial-block}}{{/inner}}{{/inline}}' + '{{#*inline "inner"}}{{>@partial-block}}{{>@partial-block}}{{/inline}}' + - '{{#>outer}}{{value}}{{/outer}}', - [{ value: 'success' }, {}, {}], - true, - 'success successsuccess success' - ); + '{{#>outer}}{{value}}{{/outer}}' + ) + .withInput({ value: 'success' }) + .toCompileTo( + 'success successsuccess success' + ); }); }); @@ -699,12 +597,10 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: dude }], - true, - 'Dudes:\n Yehuda\n Alan\n' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: dude }) + .toCompileTo('Dudes:\n Yehuda\n Alan\n'); }); it('nested indented partials', function() { var string = 'Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}'; @@ -716,12 +612,15 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: dude, url: url }], - true, - 'Dudes:\n Yehuda\n http://yehuda!\n Alan\n http://alan!\n' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ + dude: dude, + url: url + }) + .toCompileTo( + 'Dudes:\n Yehuda\n http://yehuda!\n Alan\n http://alan!\n' + ); }); it('prevent nested indented partials', function() { var string = 'Dudes:\n{{#dudes}}\n {{>dude}}\n{{/dudes}}'; @@ -733,12 +632,16 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: dude, url: url }, { preventIndent: true }], - true, - 'Dudes:\n Yehuda\n http://yehuda!\n Alan\n http://alan!\n' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ + dude: dude, + url: url + }) + .withCompileOptions({ preventIndent: true }) + .toCompileTo( + 'Dudes:\n Yehuda\n http://yehuda!\n Alan\n http://alan!\n' + ); }); }); @@ -753,12 +656,13 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }, true], - true, - 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .withCompileOptions({ compat: true }) + .toCompileTo( + 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' + ); }); it('partials can access parents with custom context', function() { var string = 'Dudes: {{#dudes}}{{> dude "test"}}{{/dudes}}'; @@ -770,12 +674,13 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }, true], - true, - 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .withCompileOptions({ compat: true }) + .toCompileTo( + 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' + ); }); it('partials can access parents without data', function() { var string = 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}'; @@ -787,12 +692,14 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }, true, false], - true, - 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .withRuntimeOptions({ data: false }) + .withCompileOptions({ data: false, compat: true }) + .toCompileTo( + 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' + ); }); it('partials inherit compat', function() { var string = 'Dudes: {{> dude}}'; @@ -804,12 +711,13 @@ describe('partials', function() { { name: 'Alan', url: 'http://alan' } ] }; - shouldCompileToWithPartials( - string, - [hash, {}, { dude: partial }, true], - true, - 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' - ); + expectTemplate(string) + .withInput(hash) + .withPartials({ dude: partial }) + .withCompileOptions({ compat: true }) + .toCompileTo( + 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ' + ); }); }); }); diff --git a/spec/regressions.js b/spec/regressions.js index aaa89cef7..6da9672d1 100644 --- a/spec/regressions.js +++ b/spec/regressions.js @@ -14,48 +14,42 @@ describe('Regressions', function() { ] }; var string = '{{#books}}{{title}}{{author.name}}{{/books}}'; - shouldCompileTo( - string, - data, - 'The origin of speciesCharles DarwinLazarillo de Tormes', - 'Renders without an undefined property error' - ); + expectTemplate(string) + .withInput(data) + .withMessage('Renders without an undefined property error') + .toCompileTo('The origin of speciesCharles DarwinLazarillo de Tormes'); }); it("GH-150: Inverted sections print when they shouldn't", function() { var string = '{{^set}}not set{{/set}} :: {{#set}}set{{/set}}'; - shouldCompileTo( - string, - {}, - 'not set :: ', - "inverted sections run when property isn't present in context" - ); - shouldCompileTo( - string, - { set: undefined }, - 'not set :: ', - 'inverted sections run when property is undefined' - ); - shouldCompileTo( - string, - { set: false }, - 'not set :: ', - 'inverted sections run when property is false' - ); - shouldCompileTo( - string, - { set: true }, - ' :: set', - "inverted sections don't run when property is true" - ); + expectTemplate(string) + .withMessage( + "inverted sections run when property isn't present in context" + ) + .toCompileTo('not set :: '); + expectTemplate(string) + .withInput({ set: undefined }) + .withMessage('inverted sections run when property is undefined') + .toCompileTo('not set :: '); + expectTemplate(string) + .withInput({ set: false }) + .withMessage('inverted sections run when property is false') + .toCompileTo('not set :: '); + expectTemplate(string) + .withInput({ set: true }) + .withMessage("inverted sections don't run when property is true") + .toCompileTo(' :: set'); }); it('GH-158: Using array index twice, breaks the template', function() { var string = '{{arr.[0]}}, {{arr.[1]}}'; var data = { arr: [1, 2] }; - shouldCompileTo(string, data, '1, 2', 'it works as expected'); + expectTemplate(string) + .withInput(data) + .withMessage('it works as expected') + .toCompileTo('1, 2'); }); it("bug reported by @fat where lambdas weren't being properly resolved", function() { @@ -95,7 +89,9 @@ describe('Regressions', function() { '
  • @dhg
  • \n' + '
  • @sayrer
  • \n' + '.\n'; - shouldCompileTo(string, data, output); + expectTemplate(string) + .withInput(data) + .toCompileTo(output); }); it('GH-408: Multiple loops fail', function() { @@ -127,23 +123,31 @@ describe('Regressions', function() { } }; - shouldCompileTo(succeedingTemplate, [{}, helpers], ' Expected '); - shouldCompileTo(failingTemplate, [{}, helpers], ' Expected '); + expectTemplate(succeedingTemplate) + .withHelpers(helpers) + .toCompileTo(' Expected '); + expectTemplate(failingTemplate) + .withHelpers(helpers) + .toCompileTo(' Expected '); }); it('GH-458: Scoped this identifier', function() { - shouldCompileTo('{{./foo}}', { foo: 'bar' }, 'bar'); + expectTemplate('{{./foo}}') + .withInput({ foo: 'bar' }) + .toCompileTo('bar'); }); it('GH-375: Unicode line terminators', function() { - shouldCompileTo('\u2028', {}, '\u2028'); + expectTemplate('\u2028').toCompileTo('\u2028'); }); it('GH-534: Object prototype aliases', function() { /* eslint-disable no-extend-native */ Object.prototype[0xd834] = true; - shouldCompileTo('{{foo}}', { foo: 'bar' }, 'bar'); + expectTemplate('{{foo}}') + .withInput({ foo: 'bar' }) + .toCompileTo('bar'); delete Object.prototype[0xd834]; /* eslint-enable no-extend-native */ @@ -158,7 +162,10 @@ describe('Regressions', function() { var string = '{{arr}}'; var data = { arr: [1, 2] }; - shouldCompileTo(string, data, data.arr.toString(), 'it works as expected'); + expectTemplate(string) + .withInput(data) + .withMessage('it works as expected') + .toCompileTo(data.arr.toString()); }); it('Mustache man page', function() { @@ -171,24 +178,27 @@ describe('Regressions', function() { in_ca: true }; - shouldCompileTo( - string, - data, - 'Hello Chris. You have just won $10000! Well, $6000, after taxes.', - 'the hello world mustache example works' - ); + expectTemplate(string) + .withInput(data) + .withMessage('the hello world mustache example works') + .toCompileTo( + 'Hello Chris. You have just won $10000! Well, $6000, after taxes.' + ); }); it('GH-731: zero context rendering', function() { - shouldCompileTo( - '{{#foo}} This is {{bar}} ~ {{/foo}}', - { foo: 0, bar: 'OK' }, - ' This is ~ ' - ); + expectTemplate('{{#foo}} This is {{bar}} ~ {{/foo}}') + .withInput({ + foo: 0, + bar: 'OK' + }) + .toCompileTo(' This is ~ '); }); it('GH-820: zero pathed rendering', function() { - shouldCompileTo('{{foo.bar}}', { foo: 0 }, ''); + expectTemplate('{{foo.bar}}') + .withInput({ foo: 0 }) + .toCompileTo(''); }); it('GH-837: undefined values for helpers', function() { @@ -198,7 +208,9 @@ describe('Regressions', function() { } }; - shouldCompileTo('{{str bar.baz}}', [{}, helpers], 'undefined'); + expectTemplate('{{str bar.baz}}') + .withHelpers(helpers) + .toCompileTo('undefined'); }); it('GH-926: Depths and de-dupe', function() { @@ -223,11 +235,9 @@ describe('Regressions', function() { value: 10000 }; - shouldCompileTo( - '{{#each data}}Key: {{@key}}\n{{/each}}', - { data: data }, - 'Key: \nKey: name\nKey: value\n' - ); + expectTemplate('{{#each data}}Key: {{@key}}\n{{/each}}') + .withInput({ data: data }) + .toCompileTo('Key: \nKey: name\nKey: value\n'); }); it('GH-1054: Should handle simple safe string responses', function() { @@ -241,23 +251,19 @@ describe('Regressions', function() { } }; - shouldCompileToWithPartials( - root, - [{}, helpers, partials], - true, - '' - ); + expectTemplate(root) + .withHelpers(helpers) + .withPartials(partials) + .toCompileTo(''); }); it('GH-1065: Sparse arrays', function() { var array = []; array[1] = 'foo'; array[3] = 'bar'; - shouldCompileTo( - '{{#each array}}{{@index}}{{.}}{{/each}}', - { array: array }, - '1foo3bar' - ); + expectTemplate('{{#each array}}{{@index}}{{.}}{{/each}}') + .withInput({ array: array }) + .toCompileTo('1foo3bar'); }); it('GH-1093: Undefined helper context', function() { @@ -276,11 +282,10 @@ describe('Regressions', function() { } }; - shouldCompileTo( - '{{#each obj}}{{{helper}}}{{.}}{{/each}}', - [{ obj: obj }, helpers], - 'notfoundbat' - ); + expectTemplate('{{#each obj}}{{{helper}}}{{.}}{{/each}}') + .withInput({ obj: obj }) + .withHelpers(helpers) + .toCompileTo('notfoundbat'); }); it('should support multiple levels of inline partials', function() { @@ -291,12 +296,9 @@ describe('Regressions', function() { layout: '{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}' }; - shouldCompileToWithPartials( - string, - [{}, {}, partials], - true, - 'doctypelayoutsubcontent' - ); + expectTemplate(string) + .withPartials(partials) + .toCompileTo('doctypelayoutsubcontent'); }); it('GH-1089: should support failover content in multiple levels of inline partials', function() { var string = '{{#> layout}}{{/layout}}'; @@ -305,12 +307,9 @@ describe('Regressions', function() { layout: '{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}' }; - shouldCompileToWithPartials( - string, - [{}, {}, partials], - true, - 'doctypelayoutsubcontent' - ); + expectTemplate(string) + .withPartials(partials) + .toCompileTo('doctypelayoutsubcontent'); }); it('GH-1099: should support greater than 3 nested levels of inline partials', function() { var string = '{{#> layout}}Outer{{/layout}}'; @@ -318,7 +317,9 @@ describe('Regressions', function() { layout: '{{#> inner}}Inner{{/inner}}{{> @partial-block }}', inner: '' }; - shouldCompileToWithPartials(string, [{}, {}, partials], true, 'Outer'); + expectTemplate(string) + .withPartials(partials) + .toCompileTo('Outer'); }); it('GH-1135 : Context handling within each iteration', function() { @@ -333,14 +334,15 @@ describe('Regressions', function() { } }; - shouldCompileTo( + expectTemplate( '{{#each array}}\n' + ' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n' + ' 2. MYIF: {{#myif true}}{{../name}}={{../../name}}={{../../../name}}{{/myif}}\n' + - '{{/each}}', - [obj, helpers], - ' 1. IF: John--\n' + ' 2. MYIF: John==\n' - ); + '{{/each}}' + ) + .withInput(obj) + .withHelpers(helpers) + .toCompileTo(' 1. IF: John--\n' + ' 2. MYIF: John==\n'); }); it('GH-1186: Support block params for existing programs', function() { @@ -349,18 +351,25 @@ describe('Regressions', function() { '{{#>test }}{{#each listOne as |item|}}{{ item }}{{/each}}{{/test}}' + '{{#>test }}{{#each listTwo as |item|}}{{ item }}{{/each}}{{/test}}'; - shouldCompileTo(string, { listOne: ['a'], listTwo: ['b'] }, 'ab', ''); + expectTemplate(string) + .withInput({ + listOne: ['a'], + listTwo: ['b'] + }) + .withMessage('') + .toCompileTo('ab'); }); it('GH-1319: "unless" breaks when "each" value equals "null"', function() { var string = '{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}'; - shouldCompileTo( - string, - { value: 'parent', list: [null, 'a'] }, - 'parent=parent parent=parent ', - '' - ); + expectTemplate(string) + .withInput({ + value: 'parent', + list: [null, 'a'] + }) + .withMessage('') + .toCompileTo('parent=parent parent=parent '); }); it('GH-1341: 4.0.7 release breaks {{#if @partial-block}} usage', function() { @@ -370,12 +379,9 @@ describe('Regressions', function() { '{{#if @partial-block}} block {{> @partial-block}} block {{/if}}', partial: '{{#> partialWithBlock}} partial {{/partialWithBlock}}' }; - shouldCompileToWithPartials( - string, - [{}, {}, partials], - true, - 'template block partial block template' - ); + expectTemplate(string) + .withPartials(partials) + .toCompileTo('template block partial block template'); }); describe('GH-1561: 4.3.x should still work with precompiled templates from 4.0.0 <= x < 4.3.0', function() { @@ -481,7 +487,10 @@ describe('Regressions', function() { } }; - shouldCompileTo('{{helpa length="foo"}}', [obj, helpers], 'foo'); + expectTemplate('{{helpa length="foo"}}') + .withInput(obj) + .withHelpers(helpers) + .toCompileTo('foo'); }); describe('GH-1598: Performance degradation for partials since v4.3.0', function() { diff --git a/spec/security.js b/spec/security.js index 68a60e15d..e01dc3db7 100644 --- a/spec/security.js +++ b/spec/security.js @@ -20,36 +20,18 @@ describe('security issues', function() { }); it('should allow the "constructor" property to be accessed if it is an "ownProperty"', function() { - shouldCompileTo( - '{{constructor.name}}', - { - constructor: { - name: 'here we go' - } - }, - 'here we go' - ); - shouldCompileTo( - '{{lookup (lookup this "constructor") "name"}}', - { - constructor: { - name: 'here we go' - } - }, - 'here we go' - ); + expectTemplate('{{constructor.name}}') + .withInput({ constructor: { name: 'here we go' } }) + .toCompileTo('here we go'); + expectTemplate('{{lookup (lookup this "constructor") "name"}}') + .withInput({ constructor: { name: 'here we go' } }) + .toCompileTo('here we go'); }); it('should allow the "constructor" property to be accessed if it is an "own property"', function() { - shouldCompileTo( - '{{lookup (lookup this "constructor") "name"}}', - { - constructor: { - name: 'here we go' - } - }, - 'here we go' - ); + expectTemplate('{{lookup (lookup this "constructor") "name"}}') + .withInput({ constructor: { name: 'here we go' } }) + .toCompileTo('here we go'); }); }); diff --git a/spec/subexpressions.js b/spec/subexpressions.js index 584278831..8f041816a 100644 --- a/spec/subexpressions.js +++ b/spec/subexpressions.js @@ -10,7 +10,10 @@ describe('subexpressions', function() { return 'LOL'; } }; - shouldCompileTo(string, [context, helpers], 'LOLLOL!'); + expectTemplate(string) + .withInput(context) + .withHelpers(helpers) + .toCompileTo('LOLLOL!'); }); it('helper w args', function() { @@ -25,7 +28,10 @@ describe('subexpressions', function() { return x === y; } }; - shouldCompileTo(string, [context, helpers], 'val is true'); + expectTemplate(string) + .withInput(context) + .withHelpers(helpers) + .toCompileTo('val is true'); }); it('mixed paths and helpers', function() { @@ -40,7 +46,10 @@ describe('subexpressions', function() { return x === y; } }; - shouldCompileTo(string, [context, helpers], 'val is foo!, true and bar!'); + expectTemplate(string) + .withInput(context) + .withHelpers(helpers) + .toCompileTo('val is foo!, true and bar!'); }); it('supports much nesting', function() { @@ -55,7 +64,10 @@ describe('subexpressions', function() { return x === y; } }; - shouldCompileTo(string, [context, helpers], 'val is true'); + expectTemplate(string) + .withInput(context) + .withHelpers(helpers) + .toCompileTo('val is true'); }); it('GH-800 : Complex subexpressions', function() { @@ -69,15 +81,26 @@ describe('subexpressions', function() { } }; - shouldCompileTo( - "{{dash 'abc' (concat a b)}}", - [context, helpers], - 'abc-ab' - ); - shouldCompileTo('{{dash d (concat a b)}}', [context, helpers], 'd-ab'); - shouldCompileTo('{{dash c.c (concat a b)}}', [context, helpers], 'c-ab'); - shouldCompileTo('{{dash (concat a b) c.c}}', [context, helpers], 'ab-c'); - shouldCompileTo('{{dash (concat a e.e) c.c}}', [context, helpers], 'ae-c'); + expectTemplate("{{dash 'abc' (concat a b)}}") + .withInput(context) + .withHelpers(helpers) + .toCompileTo('abc-ab'); + expectTemplate('{{dash d (concat a b)}}') + .withInput(context) + .withHelpers(helpers) + .toCompileTo('d-ab'); + expectTemplate('{{dash c.c (concat a b)}}') + .withInput(context) + .withHelpers(helpers) + .toCompileTo('c-ab'); + expectTemplate('{{dash (concat a b) c.c}}') + .withInput(context) + .withHelpers(helpers) + .toCompileTo('ab-c'); + expectTemplate('{{dash (concat a e.e) c.c}}') + .withInput(context) + .withHelpers(helpers) + .toCompileTo('ae-c'); }); it('provides each nested helper invocation its own options hash', function() { @@ -93,7 +116,9 @@ describe('subexpressions', function() { return x === y; } }; - shouldCompileTo(string, [{}, helpers], 'true'); + expectTemplate(string) + .withHelpers(helpers) + .toCompileTo('true'); }); it('with hashes', function() { @@ -108,7 +133,10 @@ describe('subexpressions', function() { return x === y; } }; - shouldCompileTo(string, [context, helpers], 'val is true'); + expectTemplate(string) + .withInput(context) + .withHelpers(helpers) + .toCompileTo('val is true'); }); it('as hashes', function() { @@ -122,7 +150,9 @@ describe('subexpressions', function() { return x === y; } }; - shouldCompileTo(string, [{}, helpers], 'val is true'); + expectTemplate(string) + .withHelpers(helpers) + .toCompileTo('val is true'); }); it('multiple subexpressions in a hash', function() { @@ -146,11 +176,9 @@ describe('subexpressions', function() { return new Handlebars.SafeString(defaultString); } }; - shouldCompileTo( - string, - [{}, helpers], - '' - ); + expectTemplate(string) + .withHelpers(helpers) + .toCompileTo(''); }); it('multiple subexpressions in a hash with context', function() { @@ -181,11 +209,10 @@ describe('subexpressions', function() { return new Handlebars.SafeString(defaultString); } }; - shouldCompileTo( - string, - [context, helpers], - '' - ); + expectTemplate(string) + .withInput(context) + .withHelpers(helpers) + .toCompileTo(''); }); it('in string params mode,', function() { @@ -272,7 +299,10 @@ describe('subexpressions', function() { return val + val; } }; - shouldCompileTo(string, [context, helpers], 'LOLLOL!'); + expectTemplate(string) + .withInput(context) + .withHelpers(helpers) + .toCompileTo('LOLLOL!'); }); it("subexpressions can't just be property lookups", function() { diff --git a/spec/utils.js b/spec/utils.js index 667aa0ed3..f4a4e3e4f 100644 --- a/spec/utils.js +++ b/spec/utils.js @@ -15,11 +15,9 @@ describe('utils', function() { it('it should not escape SafeString properties', function() { var name = new Handlebars.SafeString('Sean O'Malley'); - shouldCompileTo( - '{{name}}', - [{ name: name }], - 'Sean O'Malley' - ); + expectTemplate('{{name}}') + .withInput({ name: name }) + .toCompileTo('Sean O'Malley'); }); }); diff --git a/spec/whitespace-control.js b/spec/whitespace-control.js index b1a6db045..0e7f74221 100644 --- a/spec/whitespace-control.js +++ b/spec/whitespace-control.js @@ -2,125 +2,152 @@ describe('whitespace control', function() { it('should strip whitespace around mustache calls', function() { var hash = { foo: 'bar<' }; - shouldCompileTo(' {{~foo~}} ', hash, 'bar<'); - shouldCompileTo(' {{~foo}} ', hash, 'bar< '); - shouldCompileTo(' {{foo~}} ', hash, ' bar<'); - - shouldCompileTo(' {{~&foo~}} ', hash, 'bar<'); - shouldCompileTo(' {{~{foo}~}} ', hash, 'bar<'); - - shouldCompileTo('1\n{{foo~}} \n\n 23\n{{bar}}4', {}, '1\n23\n4'); + expectTemplate(' {{~foo~}} ') + .withInput(hash) + .toCompileTo('bar<'); + expectTemplate(' {{~foo}} ') + .withInput(hash) + .toCompileTo('bar< '); + expectTemplate(' {{foo~}} ') + .withInput(hash) + .toCompileTo(' bar<'); + + expectTemplate(' {{~&foo~}} ') + .withInput(hash) + .toCompileTo('bar<'); + expectTemplate(' {{~{foo}~}} ') + .withInput(hash) + .toCompileTo('bar<'); + + expectTemplate('1\n{{foo~}} \n\n 23\n{{bar}}4').toCompileTo('1\n23\n4'); }); describe('blocks', function() { it('should strip whitespace around simple block calls', function() { var hash = { foo: 'bar<' }; - shouldCompileTo(' {{~#if foo~}} bar {{~/if~}} ', hash, 'bar'); - shouldCompileTo(' {{#if foo~}} bar {{/if~}} ', hash, ' bar '); - shouldCompileTo(' {{~#if foo}} bar {{~/if}} ', hash, ' bar '); - shouldCompileTo(' {{#if foo}} bar {{/if}} ', hash, ' bar '); - - shouldCompileTo( - ' \n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\n ', - hash, - 'bar' - ); - shouldCompileTo( - ' a\n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\na ', - hash, - ' abara ' - ); + expectTemplate(' {{~#if foo~}} bar {{~/if~}} ') + .withInput(hash) + .toCompileTo('bar'); + expectTemplate(' {{#if foo~}} bar {{/if~}} ') + .withInput(hash) + .toCompileTo(' bar '); + expectTemplate(' {{~#if foo}} bar {{~/if}} ') + .withInput(hash) + .toCompileTo(' bar '); + expectTemplate(' {{#if foo}} bar {{/if}} ') + .withInput(hash) + .toCompileTo(' bar '); + + expectTemplate(' \n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\n ') + .withInput(hash) + .toCompileTo('bar'); + expectTemplate(' a\n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\na ') + .withInput(hash) + .toCompileTo(' abara '); }); it('should strip whitespace around inverse block calls', function() { var hash = {}; - shouldCompileTo(' {{~^if foo~}} bar {{~/if~}} ', hash, 'bar'); - shouldCompileTo(' {{^if foo~}} bar {{/if~}} ', hash, ' bar '); - shouldCompileTo(' {{~^if foo}} bar {{~/if}} ', hash, ' bar '); - shouldCompileTo(' {{^if foo}} bar {{/if}} ', hash, ' bar '); - - shouldCompileTo( - ' \n\n{{~^if foo~}} \n\nbar \n\n{{~/if~}}\n\n ', - hash, - 'bar' - ); + expectTemplate(' {{~^if foo~}} bar {{~/if~}} ') + .withInput(hash) + .toCompileTo('bar'); + expectTemplate(' {{^if foo~}} bar {{/if~}} ') + .withInput(hash) + .toCompileTo(' bar '); + expectTemplate(' {{~^if foo}} bar {{~/if}} ') + .withInput(hash) + .toCompileTo(' bar '); + expectTemplate(' {{^if foo}} bar {{/if}} ') + .withInput(hash) + .toCompileTo(' bar '); + + expectTemplate(' \n\n{{~^if foo~}} \n\nbar \n\n{{~/if~}}\n\n ') + .withInput(hash) + .toCompileTo('bar'); }); it('should strip whitespace around complex block calls', function() { var hash = { foo: 'bar<' }; - shouldCompileTo('{{#if foo~}} bar {{~^~}} baz {{~/if}}', hash, 'bar'); - shouldCompileTo('{{#if foo~}} bar {{^~}} baz {{/if}}', hash, 'bar '); - shouldCompileTo('{{#if foo}} bar {{~^~}} baz {{~/if}}', hash, ' bar'); - shouldCompileTo('{{#if foo}} bar {{^~}} baz {{/if}}', hash, ' bar '); - - shouldCompileTo('{{#if foo~}} bar {{~else~}} baz {{~/if}}', hash, 'bar'); - - shouldCompileTo( - '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n', - hash, - 'bar' - ); - shouldCompileTo( - '\n\n{{~#if foo~}} \n\n{{{foo}}} \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n', - hash, - 'bar<' - ); + expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}') + .withInput(hash) + .toCompileTo('bar'); + expectTemplate('{{#if foo~}} bar {{^~}} baz {{/if}}') + .withInput(hash) + .toCompileTo('bar '); + expectTemplate('{{#if foo}} bar {{~^~}} baz {{~/if}}') + .withInput(hash) + .toCompileTo(' bar'); + expectTemplate('{{#if foo}} bar {{^~}} baz {{/if}}') + .withInput(hash) + .toCompileTo(' bar '); + + expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}') + .withInput(hash) + .toCompileTo('bar'); + + expectTemplate( + '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n' + ) + .withInput(hash) + .toCompileTo('bar'); + expectTemplate( + '\n\n{{~#if foo~}} \n\n{{{foo}}} \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n' + ) + .withInput(hash) + .toCompileTo('bar<'); hash = {}; - shouldCompileTo('{{#if foo~}} bar {{~^~}} baz {{~/if}}', hash, 'baz'); - shouldCompileTo('{{#if foo}} bar {{~^~}} baz {{/if}}', hash, 'baz '); - shouldCompileTo('{{#if foo~}} bar {{~^}} baz {{~/if}}', hash, ' baz'); - shouldCompileTo('{{#if foo~}} bar {{~^}} baz {{/if}}', hash, ' baz '); - - shouldCompileTo('{{#if foo~}} bar {{~else~}} baz {{~/if}}', hash, 'baz'); - - shouldCompileTo( - '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n', - hash, - 'baz' - ); + expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}') + .withInput(hash) + .toCompileTo('baz'); + expectTemplate('{{#if foo}} bar {{~^~}} baz {{/if}}') + .withInput(hash) + .toCompileTo('baz '); + expectTemplate('{{#if foo~}} bar {{~^}} baz {{~/if}}') + .withInput(hash) + .toCompileTo(' baz'); + expectTemplate('{{#if foo~}} bar {{~^}} baz {{/if}}') + .withInput(hash) + .toCompileTo(' baz '); + + expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}') + .withInput(hash) + .toCompileTo('baz'); + + expectTemplate( + '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n' + ) + .withInput(hash) + .toCompileTo('baz'); }); }); it('should strip whitespace around partials', function() { - shouldCompileToWithPartials( - 'foo {{~> dude~}} ', - [{}, {}, { dude: 'bar' }], - true, - 'foobar' - ); - shouldCompileToWithPartials( - 'foo {{> dude~}} ', - [{}, {}, { dude: 'bar' }], - true, - 'foo bar' - ); - shouldCompileToWithPartials( - 'foo {{> dude}} ', - [{}, {}, { dude: 'bar' }], - true, - 'foo bar ' - ); - - shouldCompileToWithPartials( - 'foo\n {{~> dude}} ', - [{}, {}, { dude: 'bar' }], - true, - 'foobar' - ); - shouldCompileToWithPartials( - 'foo\n {{> dude}} ', - [{}, {}, { dude: 'bar' }], - true, - 'foo\n bar' - ); + expectTemplate('foo {{~> dude~}} ') + .withPartials({ dude: 'bar' }) + .toCompileTo('foobar'); + expectTemplate('foo {{> dude~}} ') + .withPartials({ dude: 'bar' }) + .toCompileTo('foo bar'); + expectTemplate('foo {{> dude}} ') + .withPartials({ dude: 'bar' }) + .toCompileTo('foo bar '); + + expectTemplate('foo\n {{~> dude}} ') + .withPartials({ dude: 'bar' }) + .toCompileTo('foobar'); + expectTemplate('foo\n {{> dude}} ') + .withPartials({ dude: 'bar' }) + .toCompileTo('foo\n bar'); }); it('should only strip whitespace once', function() { var hash = { foo: 'bar' }; - shouldCompileTo(' {{~foo~}} {{foo}} {{foo}} ', hash, 'barbar bar '); + expectTemplate(' {{~foo~}} {{foo}} {{foo}} ') + .withInput(hash) + .toCompileTo('barbar bar '); }); });