5fd0d7cd2b
CI / Lint (push) Failing after 1m9s
CI / Test (Node) (20, ubuntu-latest) (push) Failing after 51s
CI / Test (Node) (22, ubuntu-latest) (push) Failing after 52s
CI / Test (Node) (24, ubuntu-latest) (push) Failing after 36s
CI / Test (Browser) (push) Successful in 2m13s
Release / Publish to AWS S3 (push) Failing after 34s
CI / Test (Node) (20, windows-latest) (push) Has been cancelled
CI / Test (Node) (22, windows-latest) (push) Has been cancelled
CI / Test (Node) (24, windows-latest) (push) Has been cancelled
128 lines
3.8 KiB
JavaScript
128 lines
3.8 KiB
JavaScript
import Handlebars from './lib/index.js';
|
|
import fs from 'fs';
|
|
|
|
// Read the basic.js test file and extract test cases
|
|
// For now, manually define a set of representative test cases
|
|
const tests = [];
|
|
|
|
function T(template, input, expected, opts) {
|
|
tests.push({
|
|
template,
|
|
input: input ?? {},
|
|
expected,
|
|
compileOpts: opts?.compile ?? {},
|
|
runtimeOpts: opts?.runtime ?? {},
|
|
});
|
|
}
|
|
|
|
// ============ basic.js equivalents ============
|
|
const g = (t, i, e, co, ro) => T(t, i, e, { compile: co, runtime: ro });
|
|
|
|
g('{{foo}}', { foo: 'foo' }, 'foo');
|
|
g('\\{{foo}}', { foo: 'food' }, '{{foo}}');
|
|
g('content \\{{foo}}', { foo: 'food' }, 'content {{foo}}');
|
|
g('\\\\{{foo}}', { foo: 'food' }, '\\food');
|
|
g('\\\\ {{foo}}', { foo: 'food' }, '\\\\ food');
|
|
g(
|
|
'Goodbye\n{{cruel}}\n{{world}}!',
|
|
{ cruel: 'cruel', world: 'world' },
|
|
'Goodbye\ncruel\nworld!'
|
|
);
|
|
g('{{.}}{{length}}', 'bye', 'bye3');
|
|
g('Goodbye\n{{cruel}}\n{{world.bar}}!', undefined, 'Goodbye\n\n!');
|
|
g(
|
|
'{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!',
|
|
{ cruel: 'cruel', world: 'world' },
|
|
'Goodbye\ncruel\nworld!'
|
|
);
|
|
g(' {{~! comment ~}} blah', {}, 'blah');
|
|
g(' {{~!-- long-comment --~}} blah', {}, 'blah');
|
|
g(' {{! comment ~}} blah', {}, ' blah');
|
|
g(' {{~! comment}} blah', {}, ' blah');
|
|
g('{{#if foo}}foo{{/if}}', { foo: true }, 'foo');
|
|
g('{{#if foo}}foo{{else}}bar{{/if}}', { foo: false }, 'bar');
|
|
g('{{#unless foo}}bar{{/unless}}', { foo: false }, 'bar');
|
|
g('{{#with foo}}{{bar}}{{/with}}', { foo: { bar: 'baz' } }, 'baz');
|
|
g('{{#each items}}{{this}}{{/each}}', { items: ['a', 'b', 'c'] }, 'abc');
|
|
g('{{#each items}}{{@index}}{{/each}}', { items: ['a', 'b'] }, '01');
|
|
g('<b>{{foo}}</b>', { foo: '&' }, '<b>&</b>');
|
|
g('{{{foo}}}', { foo: '<b>' }, '<b>');
|
|
g('{{foo.bar}}', { foo: { bar: 'baz' } }, 'baz');
|
|
g('{{foo/bar}}', { foo: { bar: 'baz' } }, 'baz');
|
|
g('{{../foo}}', {}, ''); // depth at root = empty
|
|
g('{{{foo}}}', { foo: '&' }, '&');
|
|
|
|
// ============ blocks.js equivalents ============
|
|
g(
|
|
'{{#list people}}{{firstName}} {{lastName}}\n{{/list}}',
|
|
{
|
|
people: [
|
|
{ firstName: 'Yehuda', lastName: 'Katz' },
|
|
{ firstName: 'Carl', lastName: 'Lerche' },
|
|
],
|
|
},
|
|
'Yehuda Katz\nCarl Lerche\n'
|
|
);
|
|
g(
|
|
'{{#list people}}{{../prefix}} {{firstName}}\n{{/list}}',
|
|
{ people: [{ firstName: 'Yehuda' }, { firstName: 'Carl' }], prefix: 'Mr' },
|
|
'Mr Yehuda\nMr Carl\n'
|
|
);
|
|
g(
|
|
'{{#each people as |person|}}{{person}}\n{{/each}}',
|
|
{ people: ['Yehuda', 'Carl'] },
|
|
'Yehuda\nCarl\n'
|
|
);
|
|
|
|
// ============ builtins.js equivalents ============
|
|
g(
|
|
'{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!',
|
|
{ goodbye: true, world: 'world' },
|
|
'GOODBYE cruel world!'
|
|
);
|
|
g(
|
|
'{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!',
|
|
{ goodbye: false, world: 'world' },
|
|
'cruel world!'
|
|
);
|
|
g('{{lookup foo "bar"}}', { foo: { bar: 'val' } }, 'val');
|
|
g(
|
|
'{{#each items as |value key|}}{{key}}:{{value}},{{/each}}',
|
|
{ items: { a: 1, b: 2 } },
|
|
'a:1,b:2,'
|
|
);
|
|
|
|
// Write output
|
|
const results = tests.map((t, i) => {
|
|
let result,
|
|
error = null;
|
|
try {
|
|
const env = Handlebars.create();
|
|
const compiled = env.compile(t.template, t.compileOpts);
|
|
result = compiled(t.input, t.runtimeOpts);
|
|
} catch (e) {
|
|
error = e.message;
|
|
result = null;
|
|
}
|
|
return {
|
|
i,
|
|
template: t.template,
|
|
input: JSON.stringify(t.input),
|
|
expected: t.expected,
|
|
result,
|
|
error,
|
|
};
|
|
});
|
|
|
|
fs.writeFileSync('/tmp/golden_results.json', JSON.stringify(results, null, 2));
|
|
console.log(`Generated ${results.length} golden results`);
|
|
const failures = results.filter((r) => r.result !== r.expected);
|
|
if (failures.length) {
|
|
console.log(`\nFAILURES (${failures.length}):`);
|
|
failures.forEach((f) =>
|
|
console.log(
|
|
` [${f.i}] "${f.template}" expected="${f.expected}" got="${f.result}" error="${f.error}"`
|
|
)
|
|
);
|
|
}
|