Files
handlebars.js/spec/data.js
T
Jakob Linskeseder e534a911f3 Upgrade prettier to v2
Prettier v2 has the following breaking changes:
* enforces spaces between `function` and params
* enforces trailing commas by default
2022-10-29 21:49:15 +02:00

279 lines
9.8 KiB
JavaScript

describe('data', function () {
it('passing in data to a compiled function that expects data - works with helpers', function () {
expectTemplate('{{hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (options) {
return options.data.adjective + ' ' + this.noun;
})
.withRuntimeOptions({ data: { adjective: 'happy' } })
.withInput({ noun: 'cat' })
.withMessage('Data output by helper')
.toCompileTo('happy cat');
});
it('data can be looked up via @foo', function () {
expectTemplate('{{@hello}}')
.withRuntimeOptions({ data: { hello: 'hello' } })
.withMessage('@foo retrieves template data')
.toCompileTo('hello');
});
it('deep @foo triggers automatic top-level data', function () {
var helpers = Handlebars.createFrame(handlebarsEnv.helpers);
helpers.let = function (options) {
var frame = Handlebars.createFrame(options.data);
for (var prop in options.hash) {
if (prop in options.hash) {
frame[prop] = options.hash[prop];
}
}
return options.fn(this, { data: frame });
};
expectTemplate(
'{{#let world="world"}}{{#if foo}}{{#if foo}}Hello {{@world}}{{/if}}{{/if}}{{/let}}'
)
.withInput({ foo: true })
.withHelpers(helpers)
.withMessage('Automatic data was triggered')
.toCompileTo('Hello world');
});
it('parameter data can be looked up via @foo', function () {
expectTemplate('{{hello @world}}')
.withRuntimeOptions({ data: { world: 'world' } })
.withHelper('hello', function (noun) {
return 'Hello ' + noun;
})
.withMessage('@foo as a parameter retrieves template data')
.toCompileTo('Hello world');
});
it('hash values can be looked up via @foo', function () {
expectTemplate('{{hello noun=@world}}')
.withRuntimeOptions({ data: { world: 'world' } })
.withHelper('hello', function (options) {
return 'Hello ' + options.hash.noun;
})
.withMessage('@foo as a parameter retrieves template data')
.toCompileTo('Hello world');
});
it('nested parameter data can be looked up via @foo.bar', function () {
expectTemplate('{{hello @world.bar}}')
.withRuntimeOptions({ data: { world: { bar: 'world' } } })
.withHelper('hello', function (noun) {
return 'Hello ' + noun;
})
.withMessage('@foo as a parameter retrieves template data')
.toCompileTo('Hello world');
});
it('nested parameter data does not fail with @world.bar', function () {
expectTemplate('{{hello @world.bar}}')
.withRuntimeOptions({ data: { foo: { bar: 'world' } } })
.withHelper('hello', function (noun) {
return 'Hello ' + noun;
})
.withMessage('@foo as a parameter retrieves template data')
.toCompileTo('Hello undefined');
});
it('parameter data throws when using complex scope references', function () {
expectTemplate(
'{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}'
).toThrow(Error);
});
it('data can be functions', function () {
expectTemplate('{{@hello}}')
.withRuntimeOptions({
data: {
hello: function () {
return 'hello';
},
},
})
.toCompileTo('hello');
});
it('data can be functions with params', function () {
expectTemplate('{{@hello "hello"}}')
.withRuntimeOptions({
data: {
hello: function (arg) {
return arg;
},
},
})
.toCompileTo('hello');
});
it('data is inherited downstream', function () {
expectTemplate(
'{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}'
)
.withInput({ bar: { baz: 'hello world' } })
.withCompileOptions({ data: true })
.withHelper('let', function (options) {
var frame = Handlebars.createFrame(options.data);
for (var prop in options.hash) {
if (prop in options.hash) {
frame[prop] = options.hash[prop];
}
}
return options.fn(this, { data: frame });
})
.withRuntimeOptions({ data: {} })
.withMessage('data variables are inherited downstream')
.toCompileTo('2hello world1');
});
it('passing in data to a compiled function that expects data - works with helpers in partials', function () {
expectTemplate('{{>myPartial}}')
.withCompileOptions({ data: true })
.withPartial('myPartial', '{{hello}}')
.withHelper('hello', function (options) {
return options.data.adjective + ' ' + this.noun;
})
.withInput({ noun: 'cat' })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.withMessage('Data output by helper inside partial')
.toCompileTo('happy cat');
});
it('passing in data to a compiled function that expects data - works with helpers and parameters', function () {
expectTemplate('{{hello world}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (noun, options) {
return options.data.adjective + ' ' + noun + (this.exclaim ? '!' : '');
})
.withInput({ exclaim: true, world: 'world' })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.withMessage('Data output by helper')
.toCompileTo('happy world!');
});
it('passing in data to a compiled function that expects data - works with block helpers', function () {
expectTemplate('{{#hello}}{{world}}{{/hello}}')
.withCompileOptions({
data: true,
})
.withHelper('hello', function (options) {
return options.fn(this);
})
.withHelper('world', function (options) {
return options.data.adjective + ' world' + (this.exclaim ? '!' : '');
})
.withInput({ exclaim: true })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.withMessage('Data output by helper')
.toCompileTo('happy world!');
});
it('passing in data to a compiled function that expects data - works with block helpers that use ..', function () {
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (options) {
return options.fn({ exclaim: '?' });
})
.withHelper('world', function (thing, options) {
return options.data.adjective + ' ' + thing + (this.exclaim || '');
})
.withInput({ exclaim: true, zomg: 'world' })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.withMessage('Data output by helper')
.toCompileTo('happy world?');
});
it('passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..', function () {
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (options) {
return options.data.accessData + ' ' + options.fn({ exclaim: '?' });
})
.withHelper('world', function (thing, options) {
return options.data.adjective + ' ' + thing + (this.exclaim || '');
})
.withInput({ exclaim: true, zomg: 'world' })
.withRuntimeOptions({ data: { adjective: 'happy', accessData: '#win' } })
.withMessage('Data output by helper')
.toCompileTo('#win happy world?');
});
it('you can override inherited data when invoking a helper', function () {
expectTemplate('{{#hello}}{{world zomg}}{{/hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (options) {
return options.fn(
{ exclaim: '?', zomg: 'world' },
{ data: { adjective: 'sad' } }
);
})
.withHelper('world', function (thing, options) {
return options.data.adjective + ' ' + thing + (this.exclaim || '');
})
.withInput({ exclaim: true, zomg: 'planet' })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.withMessage('Overridden data output by helper')
.toCompileTo('sad world?');
});
it('you can override inherited data when invoking a helper with depth', function () {
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (options) {
return options.fn({ exclaim: '?' }, { data: { adjective: 'sad' } });
})
.withHelper('world', function (thing, options) {
return options.data.adjective + ' ' + thing + (this.exclaim || '');
})
.withInput({ exclaim: true, zomg: 'world' })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.withMessage('Overridden data output by helper')
.toCompileTo('sad world?');
});
describe('@root', function () {
it('the root context can be looked up via @root', function () {
expectTemplate('{{@root.foo}}')
.withInput({ foo: 'hello' })
.withRuntimeOptions({ data: {} })
.toCompileTo('hello');
expectTemplate('{{@root.foo}}')
.withInput({ foo: 'hello' })
.toCompileTo('hello');
});
it('passed root values take priority', function () {
expectTemplate('{{@root.foo}}')
.withInput({ foo: 'should not be used' })
.withRuntimeOptions({ data: { root: { foo: 'hello' } } })
.toCompileTo('hello');
});
});
describe('nesting', function () {
it('the root context can be looked up via @root', function () {
expectTemplate(
'{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}'
)
.withInput({ foo: 'hello' })
.withHelper('helper', function (options) {
var frame = Handlebars.createFrame(options.data);
frame.depth = options.data.depth + 1;
return options.fn(this, { data: frame });
})
.withRuntimeOptions({
data: {
depth: 0,
},
})
.toCompileTo('2 1 0');
});
});
});