/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import Handlebars, { type HelperOptions } from '../..';
import { expectTemplate } from '../__jest__/test_bench';
describe('subexpressions', () => {
it('arg-less helper', () => {
expectTemplate('{{foo (bar)}}!')
.withHelpers({
foo(val) {
return val + val;
},
bar() {
return 'LOL';
},
})
.toCompileTo('LOLLOL!');
});
it('helper w args', () => {
expectTemplate('{{blog (equal a b)}}')
.withInput({ bar: 'LOL' })
.withHelpers({
blog(val) {
return 'val is ' + val;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is true');
});
it('mixed paths and helpers', () => {
expectTemplate('{{blog baz.bat (equal a b) baz.bar}}')
.withInput({ bar: 'LOL', baz: { bat: 'foo!', bar: 'bar!' } })
.withHelpers({
blog(val, that, theOther) {
return 'val is ' + val + ', ' + that + ' and ' + theOther;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is foo!, true and bar!');
});
it('supports much nesting', () => {
expectTemplate('{{blog (equal (equal true true) true)}}')
.withInput({ bar: 'LOL' })
.withHelpers({
blog(val) {
return 'val is ' + val;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is true');
});
it('GH-800 : Complex subexpressions', () => {
const context = { a: 'a', b: 'b', c: { c: 'c' }, d: 'd', e: { e: 'e' } };
const helpers = {
dash(a: any, b: any) {
return a + '-' + b;
},
concat(a: any, b: any) {
return a + b;
},
};
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', () => {
let lastOptions: HelperOptions;
const helpers = {
equal(x: any, y: any, options: HelperOptions) {
if (!options || options === lastOptions) {
throw new Error('options hash was reused');
}
lastOptions = options;
return x === y;
},
};
expectTemplate('{{equal (equal true true) true}}').withHelpers(helpers).toCompileTo('true');
});
it('with hashes', () => {
expectTemplate("{{blog (equal (equal true true) true fun='yes')}}")
.withInput({ bar: 'LOL' })
.withHelpers({
blog(val) {
return 'val is ' + val;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is true');
});
it('as hashes', () => {
expectTemplate("{{blog fun=(equal (blog fun=1) 'val is 1')}}")
.withHelpers({
blog(options) {
return 'val is ' + options.hash.fun;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is true');
});
it('multiple subexpressions in a hash', () => {
expectTemplate('{{input aria-label=(t "Name") placeholder=(t "Example User")}}')
.withHelpers({
input(options) {
const hash = options.hash;
const ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
const placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
return new Handlebars.SafeString(
''
);
},
t(defaultString) {
return new Handlebars.SafeString(defaultString);
},
})
.toCompileTo('');
});
it('multiple subexpressions in a hash with context', () => {
expectTemplate('{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}')
.withInput({
item: {
field: 'Name',
placeholder: 'Example User',
},
})
.withHelpers({
input(options) {
const hash = options.hash;
const ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
const placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
return new Handlebars.SafeString(
''
);
},
t(defaultString) {
return new Handlebars.SafeString(defaultString);
},
})
.toCompileTo('');
});
it('subexpression functions on the context', () => {
expectTemplate('{{foo (bar)}}!')
.withInput({
bar() {
return 'LOL';
},
})
.withHelpers({
foo(val) {
return val + val;
},
})
.toCompileTo('LOLLOL!');
});
it("subexpressions can't just be property lookups", () => {
expectTemplate('{{foo (bar)}}!')
.withInput({
bar: 'LOL',
})
.withHelpers({
foo(val) {
return val + val;
},
})
.toThrow();
});
});