diff options
Diffstat (limited to 'dev/lib/handlebars/src/spec/index.regressions.test.ts')
-rw-r--r-- | dev/lib/handlebars/src/spec/index.regressions.test.ts | 379 |
1 files changed, 0 insertions, 379 deletions
diff --git a/dev/lib/handlebars/src/spec/index.regressions.test.ts b/dev/lib/handlebars/src/spec/index.regressions.test.ts deleted file mode 100644 index fc2065fe..00000000 --- a/dev/lib/handlebars/src/spec/index.regressions.test.ts +++ /dev/null @@ -1,379 +0,0 @@ -/* - * 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, forEachCompileFunctionName } from '../__jest__/test_bench'; - -describe('Regressions', () => { - it('GH-94: Cannot read property of undefined', () => { - expectTemplate('{{#books}}{{title}}{{author.name}}{{/books}}') - .withInput({ - books: [ - { - title: 'The origin of species', - author: { - name: 'Charles Darwin', - }, - }, - { - title: 'Lazarillo de Tormes', - }, - ], - }) - .toCompileTo('The origin of speciesCharles DarwinLazarillo de Tormes'); - }); - - it("GH-150: Inverted sections print when they shouldn't", () => { - const string = '{{^set}}not set{{/set}} :: {{#set}}set{{/set}}'; - expectTemplate(string).toCompileTo('not set :: '); - expectTemplate(string).withInput({ set: undefined }).toCompileTo('not set :: '); - expectTemplate(string).withInput({ set: false }).toCompileTo('not set :: '); - expectTemplate(string).withInput({ set: true }).toCompileTo(' :: set'); - }); - - it('GH-158: Using array index twice, breaks the template', () => { - expectTemplate('{{arr.[0]}}, {{arr.[1]}}') - .withInput({ arr: [1, 2] }) - .toCompileTo('1, 2'); - }); - - it("bug reported by @fat where lambdas weren't being properly resolved", () => { - const string = - '<strong>This is a slightly more complicated {{thing}}.</strong>.\n' + - '{{! Just ignore this business. }}\n' + - 'Check this out:\n' + - '{{#hasThings}}\n' + - '<ul>\n' + - '{{#things}}\n' + - '<li class={{className}}>{{word}}</li>\n' + - '{{/things}}</ul>.\n' + - '{{/hasThings}}\n' + - '{{^hasThings}}\n' + - '\n' + - '<small>Nothing to check out...</small>\n' + - '{{/hasThings}}'; - - const data = { - thing() { - return 'blah'; - }, - things: [ - { className: 'one', word: '@fat' }, - { className: 'two', word: '@dhg' }, - { className: 'three', word: '@sayrer' }, - ], - hasThings() { - return true; - }, - }; - - const output = - '<strong>This is a slightly more complicated blah.</strong>.\n' + - 'Check this out:\n' + - '<ul>\n' + - '<li class=one>@fat</li>\n' + - '<li class=two>@dhg</li>\n' + - '<li class=three>@sayrer</li>\n' + - '</ul>.\n'; - - expectTemplate(string).withInput(data).toCompileTo(output); - }); - - it('GH-408: Multiple loops fail', () => { - expectTemplate('{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}') - .withInput([ - { name: 'John Doe', location: { city: 'Chicago' } }, - { name: 'Jane Doe', location: { city: 'New York' } }, - ]) - .toCompileTo('John DoeJane DoeJohn DoeJane DoeJohn DoeJane Doe'); - }); - - it('GS-428: Nested if else rendering', () => { - const succeedingTemplate = - '{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}'; - const failingTemplate = - '{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}'; - - const helpers = { - blk(block: HelperOptions) { - return block.fn(''); - }, - inverse(block: HelperOptions) { - return block.inverse(''); - }, - }; - - expectTemplate(succeedingTemplate).withHelpers(helpers).toCompileTo(' Expected '); - expectTemplate(failingTemplate).withHelpers(helpers).toCompileTo(' Expected '); - }); - - it('GH-458: Scoped this identifier', () => { - expectTemplate('{{./foo}}').withInput({ foo: 'bar' }).toCompileTo('bar'); - }); - - it('GH-375: Unicode line terminators', () => { - expectTemplate('\u2028').toCompileTo('\u2028'); - }); - - it('GH-534: Object prototype aliases', () => { - /* eslint-disable no-extend-native */ - // @ts-expect-error - Object.prototype[0xd834] = true; - - expectTemplate('{{foo}}').withInput({ foo: 'bar' }).toCompileTo('bar'); - - // @ts-expect-error - delete Object.prototype[0xd834]; - /* eslint-enable no-extend-native */ - }); - - it('GH-437: Matching escaping', () => { - expectTemplate('{{{a}}').toThrow(/Parse error on/); - expectTemplate('{{a}}}').toThrow(/Parse error on/); - }); - - it('GH-676: Using array in escaping mustache fails', () => { - const data = { arr: [1, 2] }; - expectTemplate('{{arr}}').withInput(data).toCompileTo(data.arr.toString()); - }); - - it('Mustache man page', () => { - expectTemplate( - 'Hello {{name}}. You have just won ${{value}}!{{#in_ca}} Well, ${{taxed_value}}, after taxes.{{/in_ca}}' - ) - .withInput({ - name: 'Chris', - value: 10000, - taxed_value: 10000 - 10000 * 0.4, - in_ca: true, - }) - .toCompileTo('Hello Chris. You have just won $10000! Well, $6000, after taxes.'); - }); - - it('GH-731: zero context rendering', () => { - expectTemplate('{{#foo}} This is {{bar}} ~ {{/foo}}') - .withInput({ - foo: 0, - bar: 'OK', - }) - .toCompileTo(' This is ~ '); - }); - - it('GH-820: zero pathed rendering', () => { - expectTemplate('{{foo.bar}}').withInput({ foo: 0 }).toCompileTo(''); - }); - - it('GH-837: undefined values for helpers', () => { - expectTemplate('{{str bar.baz}}') - .withHelpers({ - str(value) { - return value + ''; - }, - }) - .toCompileTo('undefined'); - }); - - it('GH-926: Depths and de-dupe', () => { - expectTemplate( - '{{#if dater}}{{#each data}}{{../name}}{{/each}}{{else}}{{#each notData}}{{../name}}{{/each}}{{/if}}' - ) - .withInput({ - name: 'foo', - data: [1], - notData: [1], - }) - .toCompileTo('foo'); - }); - - it('GH-1021: Each empty string key', () => { - expectTemplate('{{#each data}}Key: {{@key}}\n{{/each}}') - .withInput({ - data: { - '': 'foo', - name: 'Chris', - value: 10000, - }, - }) - .toCompileTo('Key: \nKey: name\nKey: value\n'); - }); - - it('GH-1054: Should handle simple safe string responses', () => { - expectTemplate('{{#wrap}}{{>partial}}{{/wrap}}') - .withHelpers({ - wrap(options: HelperOptions) { - return new Handlebars.SafeString(options.fn()); - }, - }) - .withPartials({ - partial: '{{#wrap}}<partial>{{/wrap}}', - }) - .toCompileTo('<partial>'); - }); - - it('GH-1065: Sparse arrays', () => { - const array = []; - array[1] = 'foo'; - array[3] = 'bar'; - expectTemplate('{{#each array}}{{@index}}{{.}}{{/each}}') - .withInput({ array }) - .toCompileTo('1foo3bar'); - }); - - it('GH-1093: Undefined helper context', () => { - expectTemplate('{{#each obj}}{{{helper}}}{{.}}{{/each}}') - .withInput({ obj: { foo: undefined, bar: 'bat' } }) - .withHelpers({ - helper(this: any) { - // It's valid to execute a block against an undefined context, but - // helpers can not do so, so we expect to have an empty object here; - for (const name in this) { - if (Object.prototype.hasOwnProperty.call(this, name)) { - return 'found'; - } - } - // And to make IE happy, check for the known string as length is not enumerated. - return this === 'bat' ? 'found' : 'not'; - }, - }) - .toCompileTo('notfoundbat'); - }); - - it('should support multiple levels of inline partials', () => { - expectTemplate('{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}') - .withPartials({ - doctype: 'doctype{{> content}}', - layout: '{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}', - }) - .toCompileTo('doctypelayoutsubcontent'); - }); - - it('GH-1089: should support failover content in multiple levels of inline partials', () => { - expectTemplate('{{#> layout}}{{/layout}}') - .withPartials({ - doctype: 'doctype{{> content}}', - layout: - '{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}', - }) - .toCompileTo('doctypelayoutsubcontent'); - }); - - it('GH-1099: should support greater than 3 nested levels of inline partials', () => { - expectTemplate('{{#> layout}}Outer{{/layout}}') - .withPartials({ - layout: '{{#> inner}}Inner{{/inner}}{{> @partial-block }}', - inner: '', - }) - .toCompileTo('Outer'); - }); - - it('GH-1135 : Context handling within each iteration', () => { - expectTemplate( - '{{#each array}}\n' + - ' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n' + - ' 2. MYIF: {{#myif true}}{{../name}}={{../../name}}={{../../../name}}{{/myif}}\n' + - '{{/each}}' - ) - .withInput({ array: [1], name: 'John' }) - .withHelpers({ - myif(conditional, options: HelperOptions) { - if (conditional) { - return options.fn(this); - } else { - return options.inverse(this); - } - }, - }) - .toCompileTo(' 1. IF: John--\n' + ' 2. MYIF: John==\n'); - }); - - it('GH-1186: Support block params for existing programs', () => { - expectTemplate( - '{{#*inline "test"}}{{> @partial-block }}{{/inline}}' + - '{{#>test }}{{#each listOne as |item|}}{{ item }}{{/each}}{{/test}}' + - '{{#>test }}{{#each listTwo as |item|}}{{ item }}{{/each}}{{/test}}' - ) - .withInput({ - listOne: ['a'], - listTwo: ['b'], - }) - .toCompileTo('ab'); - }); - - it('GH-1319: "unless" breaks when "each" value equals "null"', () => { - expectTemplate('{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}') - .withInput({ - value: 'parent', - list: [null, 'a'], - }) - .toCompileTo('parent=parent parent=parent '); - }); - - it('GH-1341: 4.0.7 release breaks {{#if @partial-block}} usage', () => { - expectTemplate('template {{>partial}} template') - .withPartials({ - partialWithBlock: '{{#if @partial-block}} block {{> @partial-block}} block {{/if}}', - partial: '{{#> partialWithBlock}} partial {{/partialWithBlock}}', - }) - .toCompileTo('template block partial block template'); - }); - - it('should allow hash with protected array names', () => { - expectTemplate('{{helpa length="foo"}}') - .withInput({ array: [1], name: 'John' }) - .withHelpers({ - helpa(options: HelperOptions) { - return options.hash.length; - }, - }) - .toCompileTo('foo'); - }); - - describe('GH-1598: Performance degradation for partials since v4.3.0', () => { - let newHandlebarsInstance: typeof Handlebars; - let spy: jest.SpyInstance; - beforeEach(() => { - newHandlebarsInstance = Handlebars.create(); - }); - afterEach(() => { - spy.mockRestore(); - }); - - forEachCompileFunctionName((compileName) => { - it(`should only compile global partials once when calling #${compileName}`, () => { - const compile = newHandlebarsInstance[compileName].bind(newHandlebarsInstance); - let calls; - switch (compileName) { - case 'compile': - spy = jest.spyOn(newHandlebarsInstance, 'template'); - calls = 3; - break; - case 'compileAST': - spy = jest.spyOn(newHandlebarsInstance, 'compileAST'); - calls = 2; - break; - } - newHandlebarsInstance.registerPartial({ - dude: 'I am a partial', - }); - const string = 'Dudes: {{> dude}} {{> dude}}'; - compile(string)(); // This should compile template + partial once - compile(string)(); // This should only compile template - expect(spy).toHaveBeenCalledTimes(calls); - spy.mockRestore(); - }); - }); - }); - - describe("GH-1639: TypeError: Cannot read property 'apply' of undefined\" when handlebars version > 4.6.0 (undocumented, deprecated usage)", () => { - it('should treat undefined helpers like non-existing helpers', () => { - expectTemplate('{{foo}}') - .withHelper('foo', undefined as any) - .withInput({ foo: 'bar' }) - .toCompileTo('bar'); - }); - }); -}); |