365 lines
10 KiB
JavaScript
365 lines
10 KiB
JavaScript
describe('data', function() {
|
|
it('passing in data to a compiled function that expects data - works with helpers', function() {
|
|
var template = CompilerContext.compile('{{hello}}', { data: true });
|
|
|
|
var helpers = {
|
|
hello: function(options) {
|
|
return options.data.adjective + ' ' + this.noun;
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{ noun: 'cat' },
|
|
{ helpers: helpers, data: { adjective: 'happy' } }
|
|
);
|
|
equals('happy cat', result, 'Data output by helper');
|
|
});
|
|
|
|
it('data can be looked up via @foo', function() {
|
|
var template = CompilerContext.compile('{{@hello}}');
|
|
var result = template({}, { data: { hello: 'hello' } });
|
|
equals('hello', result, '@foo retrieves template data');
|
|
});
|
|
|
|
it('deep @foo triggers automatic top-level data', function() {
|
|
var template = CompilerContext.compile(
|
|
'{{#let world="world"}}{{#if foo}}{{#if foo}}Hello {{@world}}{{/if}}{{/if}}{{/let}}'
|
|
);
|
|
|
|
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 });
|
|
};
|
|
|
|
var result = template({ foo: true }, { helpers: helpers });
|
|
equals('Hello world', result, 'Automatic data was triggered');
|
|
});
|
|
|
|
it('parameter data can be looked up via @foo', function() {
|
|
var template = CompilerContext.compile('{{hello @world}}');
|
|
var helpers = {
|
|
hello: function(noun) {
|
|
return 'Hello ' + noun;
|
|
}
|
|
};
|
|
|
|
var result = template({}, { helpers: helpers, data: { world: 'world' } });
|
|
equals(
|
|
'Hello world',
|
|
result,
|
|
'@foo as a parameter retrieves template data'
|
|
);
|
|
});
|
|
|
|
it('hash values can be looked up via @foo', function() {
|
|
var template = CompilerContext.compile('{{hello noun=@world}}');
|
|
var helpers = {
|
|
hello: function(options) {
|
|
return 'Hello ' + options.hash.noun;
|
|
}
|
|
};
|
|
|
|
var result = template({}, { helpers: helpers, data: { world: 'world' } });
|
|
equals(
|
|
'Hello world',
|
|
result,
|
|
'@foo as a parameter retrieves template data'
|
|
);
|
|
});
|
|
|
|
it('nested parameter data can be looked up via @foo.bar', function() {
|
|
var template = CompilerContext.compile('{{hello @world.bar}}');
|
|
var helpers = {
|
|
hello: function(noun) {
|
|
return 'Hello ' + noun;
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{},
|
|
{ helpers: helpers, data: { world: { bar: 'world' } } }
|
|
);
|
|
equals(
|
|
'Hello world',
|
|
result,
|
|
'@foo as a parameter retrieves template data'
|
|
);
|
|
});
|
|
|
|
it('nested parameter data does not fail with @world.bar', function() {
|
|
var template = CompilerContext.compile('{{hello @world.bar}}');
|
|
var helpers = {
|
|
hello: function(noun) {
|
|
return 'Hello ' + noun;
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{},
|
|
{ helpers: helpers, data: { foo: { bar: 'world' } } }
|
|
);
|
|
equals(
|
|
'Hello undefined',
|
|
result,
|
|
'@foo as a parameter retrieves template data'
|
|
);
|
|
});
|
|
|
|
it('parameter data throws when using complex scope references', function() {
|
|
var string = '{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}';
|
|
|
|
shouldThrow(function() {
|
|
CompilerContext.compile(string);
|
|
}, Error);
|
|
});
|
|
|
|
it('data can be functions', function() {
|
|
var template = CompilerContext.compile('{{@hello}}');
|
|
var result = template(
|
|
{},
|
|
{
|
|
data: {
|
|
hello: function() {
|
|
return 'hello';
|
|
}
|
|
}
|
|
}
|
|
);
|
|
equals('hello', result);
|
|
});
|
|
it('data can be functions with params', function() {
|
|
var template = CompilerContext.compile('{{@hello "hello"}}');
|
|
var result = template(
|
|
{},
|
|
{
|
|
data: {
|
|
hello: function(arg) {
|
|
return arg;
|
|
}
|
|
}
|
|
}
|
|
);
|
|
equals('hello', result);
|
|
});
|
|
|
|
it('data is inherited downstream', function() {
|
|
var template = CompilerContext.compile(
|
|
'{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}',
|
|
{ data: true }
|
|
);
|
|
var 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 });
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{ bar: { baz: 'hello world' } },
|
|
{ helpers: helpers, data: {} }
|
|
);
|
|
equals('2hello world1', result, 'data variables are inherited downstream');
|
|
});
|
|
|
|
it('passing in data to a compiled function that expects data - works with helpers in partials', function() {
|
|
var template = CompilerContext.compile('{{>myPartial}}', { data: true });
|
|
|
|
var partials = {
|
|
myPartial: CompilerContext.compile('{{hello}}', { data: true })
|
|
};
|
|
|
|
var helpers = {
|
|
hello: function(options) {
|
|
return options.data.adjective + ' ' + this.noun;
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{ noun: 'cat' },
|
|
{ helpers: helpers, partials: partials, data: { adjective: 'happy' } }
|
|
);
|
|
equals('happy cat', result, 'Data output by helper inside partial');
|
|
});
|
|
|
|
it('passing in data to a compiled function that expects data - works with helpers and parameters', function() {
|
|
var template = CompilerContext.compile('{{hello world}}', { data: true });
|
|
|
|
var helpers = {
|
|
hello: function(noun, options) {
|
|
return options.data.adjective + ' ' + noun + (this.exclaim ? '!' : '');
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{ exclaim: true, world: 'world' },
|
|
{ helpers: helpers, data: { adjective: 'happy' } }
|
|
);
|
|
equals('happy world!', result, 'Data output by helper');
|
|
});
|
|
|
|
it('passing in data to a compiled function that expects data - works with block helpers', function() {
|
|
var template = CompilerContext.compile('{{#hello}}{{world}}{{/hello}}', {
|
|
data: true
|
|
});
|
|
|
|
var helpers = {
|
|
hello: function(options) {
|
|
return options.fn(this);
|
|
},
|
|
world: function(options) {
|
|
return options.data.adjective + ' world' + (this.exclaim ? '!' : '');
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{ exclaim: true },
|
|
{ helpers: helpers, data: { adjective: 'happy' } }
|
|
);
|
|
equals('happy world!', result, 'Data output by helper');
|
|
});
|
|
|
|
it('passing in data to a compiled function that expects data - works with block helpers that use ..', function() {
|
|
var template = CompilerContext.compile(
|
|
'{{#hello}}{{world ../zomg}}{{/hello}}',
|
|
{ data: true }
|
|
);
|
|
|
|
var helpers = {
|
|
hello: function(options) {
|
|
return options.fn({ exclaim: '?' });
|
|
},
|
|
world: function(thing, options) {
|
|
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{ exclaim: true, zomg: 'world' },
|
|
{ helpers: helpers, data: { adjective: 'happy' } }
|
|
);
|
|
equals('happy world?', result, 'Data output by helper');
|
|
});
|
|
|
|
it('passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..', function() {
|
|
var template = CompilerContext.compile(
|
|
'{{#hello}}{{world ../zomg}}{{/hello}}',
|
|
{ data: true }
|
|
);
|
|
|
|
var helpers = {
|
|
hello: function(options) {
|
|
return options.data.accessData + ' ' + options.fn({ exclaim: '?' });
|
|
},
|
|
world: function(thing, options) {
|
|
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{ exclaim: true, zomg: 'world' },
|
|
{ helpers: helpers, data: { adjective: 'happy', accessData: '#win' } }
|
|
);
|
|
equals('#win happy world?', result, 'Data output by helper');
|
|
});
|
|
|
|
it('you can override inherited data when invoking a helper', function() {
|
|
var template = CompilerContext.compile(
|
|
'{{#hello}}{{world zomg}}{{/hello}}',
|
|
{ data: true }
|
|
);
|
|
|
|
var helpers = {
|
|
hello: function(options) {
|
|
return options.fn(
|
|
{ exclaim: '?', zomg: 'world' },
|
|
{ data: { adjective: 'sad' } }
|
|
);
|
|
},
|
|
world: function(thing, options) {
|
|
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{ exclaim: true, zomg: 'planet' },
|
|
{ helpers: helpers, data: { adjective: 'happy' } }
|
|
);
|
|
equals('sad world?', result, 'Overriden data output by helper');
|
|
});
|
|
|
|
it('you can override inherited data when invoking a helper with depth', function() {
|
|
var template = CompilerContext.compile(
|
|
'{{#hello}}{{world ../zomg}}{{/hello}}',
|
|
{ data: true }
|
|
);
|
|
|
|
var helpers = {
|
|
hello: function(options) {
|
|
return options.fn({ exclaim: '?' }, { data: { adjective: 'sad' } });
|
|
},
|
|
world: function(thing, options) {
|
|
return options.data.adjective + ' ' + thing + (this.exclaim || '');
|
|
}
|
|
};
|
|
|
|
var result = template(
|
|
{ exclaim: true, zomg: 'world' },
|
|
{ helpers: helpers, data: { adjective: 'happy' } }
|
|
);
|
|
equals('sad world?', result, 'Overriden data output by helper');
|
|
});
|
|
|
|
describe('@root', function() {
|
|
it('the root context can be looked up via @root', function() {
|
|
var template = CompilerContext.compile('{{@root.foo}}');
|
|
var result = template({ foo: 'hello' }, { data: {} });
|
|
equals('hello', result);
|
|
|
|
result = template({ foo: 'hello' }, {});
|
|
equals('hello', result);
|
|
});
|
|
it('passed root values take priority', function() {
|
|
var template = CompilerContext.compile('{{@root.foo}}');
|
|
var result = template({}, { data: { root: { foo: 'hello' } } });
|
|
equals('hello', result);
|
|
});
|
|
});
|
|
|
|
describe('nesting', function() {
|
|
it('the root context can be looked up via @root', function() {
|
|
var template = CompilerContext.compile(
|
|
'{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}'
|
|
);
|
|
var result = template(
|
|
{ foo: 'hello' },
|
|
{
|
|
helpers: {
|
|
helper: function(options) {
|
|
var frame = Handlebars.createFrame(options.data);
|
|
frame.depth = options.data.depth + 1;
|
|
return options.fn(this, { data: frame });
|
|
}
|
|
},
|
|
data: {
|
|
depth: 0
|
|
}
|
|
}
|
|
);
|
|
equals('2 1 0', result);
|
|
});
|
|
});
|
|
});
|