diff --git a/packages/@ember/-internals/glimmer/lib/components/link-to.ts b/packages/@ember/-internals/glimmer/lib/components/link-to.ts index 4a13b2d266a..5e09ae9caf2 100644 --- a/packages/@ember/-internals/glimmer/lib/components/link-to.ts +++ b/packages/@ember/-internals/glimmer/lib/components/link-to.ts @@ -557,13 +557,14 @@ if (EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS) { let { model, models } = this; assert( - 'You cannot provide both the `@model` and `@models` arguments to the component', + 'You cannot provide both the `@model` and `@models` arguments to the component.', model === UNDEFINED || models === UNDEFINED ); if (model !== UNDEFINED) { return [model]; } else if (models !== UNDEFINED) { + assert('The `@models` argument must be an array.', Array.isArray(models)); return models; } else { return []; @@ -921,6 +922,16 @@ if (EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS) { ) ); + if (DEBUG && this.query === UNDEFINED) { + let { _models: models } = this; + let lastModel = models.length > 0 && models[models.length - 1]; + + assert( + 'The `(query-params)` helper can only be used when invoking the `{{link-to}}` component.', + !(lastModel && lastModel.isQueryParams) + ); + } + return; } @@ -933,9 +944,9 @@ if (EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS) { } // 2. The last argument is possibly the `query` object. - let lastParam = params[params.length - 1]; + let queryParams = params[params.length - 1]; - if (lastParam && lastParam.isQueryParams) { + if (queryParams && queryParams.isQueryParams) { this.set('query', params.pop().values); } else { this.set('query', UNDEFINED); @@ -1795,8 +1806,8 @@ if (EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS) { } assert( - 'You must provide one or more parameters to the link-to component.', - params && params.length + 'You must provide one or more parameters to the `{{link-to}}` component.', + params && params.length > 0 ); let disabledWhen = get(this, 'disabledWhen'); diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/query-params-curly-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/query-params-curly-test.js index c7842f5927a..321a986e1b4 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/query-params-curly-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/query-params-curly-test.js @@ -50,6 +50,18 @@ moduleFor( }); }); } + + ['@feature(ember-glimmer-angle-bracket-built-ins) `(query-params)` must be used in conjunction with `{{link-to}}']() { + this.addTemplate( + 'index', + `{{#let (query-params foo='456' bar='NAW') as |qp|}}{{link-to 'Index' 'index' qp}}{{/let}}` + ); + + return expectAssertion( + () => this.visit('/'), + /The `\(query-params\)` helper can only be used when invoking the `{{link-to}}` component\./ + ); + } } ); diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-curly-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-curly-test.js index cf5a7e7bde2..fdcf5a48b93 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-curly-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-curly-test.js @@ -12,11 +12,9 @@ moduleFor( ) { assert.expect(1); - this.addTemplate('application', `{{#link-to id='the-link'}}Index{{/link-to}}`); - expectAssertion(() => { - this.visit('/'); - }, /You must provide at least one of the `@route`, `@model`, `@models` or `@query` argument to ``/); + this.addTemplate('application', `{{#link-to id='the-link'}}Index{{/link-to}}`); + }, /You must provide one or more parameters to the `{{link-to}}` component\. \('my-app\/templates\/application\.hbs' @ L1:C0\)/); } [`@feature(!ember-glimmer-angle-bracket-built-ins) throws a useful error if you invoke it wrong`]( diff --git a/packages/ember-template-compiler/lib/plugins/transform-link-to.ts b/packages/ember-template-compiler/lib/plugins/transform-link-to.ts index 49e6aa9acc1..4ec13852b53 100644 --- a/packages/ember-template-compiler/lib/plugins/transform-link-to.ts +++ b/packages/ember-template-compiler/lib/plugins/transform-link-to.ts @@ -1,6 +1,166 @@ +import { EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS } from '@ember/canary-features'; +import { assert } from '@ember/debug'; import { AST, ASTPlugin, ASTPluginEnvironment } from '@glimmer/syntax'; +import calculateLocationDisplay from '../system/calculate-location-display'; import { Builders } from '../types'; +function isInlineLinkTo(node: AST.MustacheStatement): boolean { + return node.path.original === 'link-to'; +} + +function isBlockLinkTo(node: AST.BlockStatement): boolean { + return node.path.original === 'link-to'; +} + +function isSubExpression(node: AST.Expression): node is AST.SubExpression { + return node.type === 'SubExpression'; +} + +function isQueryParams(node: AST.Expression): node is AST.SubExpression { + return isSubExpression(node) && node.path.original === 'query-params'; +} + +function transformInlineLinkToIntoBlockForm( + env: ASTPluginEnvironment, + node: AST.MustacheStatement +): AST.BlockStatement { + let { builders: b } = env.syntax; + + return b.block( + 'link-to', + node.params.slice(1), + node.hash, + buildProgram(b, node.params[0], node.escaped, node.loc), + null, + node.loc + ); +} + +function transformPositionalLinkToIntoNamedArguments( + env: ASTPluginEnvironment, + node: AST.BlockStatement +): AST.BlockStatement { + let { builders: b } = env.syntax; + let { moduleName } = env.meta; + let { + params, + hash: { pairs }, + } = node; + + let keys = pairs.map(pair => pair.key); + + if (params.length === 0) { + assert( + `You must provide one or more parameters to the \`{{link-to}}\` component. ${calculateLocationDisplay( + moduleName, + node.loc + )}`, + keys.indexOf('params') !== -1 || + keys.indexOf('route') !== -1 || + keys.indexOf('model') !== -1 || + keys.indexOf('models') !== -1 || + keys.indexOf('query') !== -1 + ); + + return node; + } else { + assert( + `You cannot pass positional parameters and the \`params\` argument to the \`{{link-to}}\` component at the same time. ${calculateLocationDisplay( + moduleName, + node.loc + )}`, + keys.indexOf('params') === -1 + ); + + assert( + `You cannot pass positional parameters and the \`route\` argument to the \`{{link-to}}\` component at the same time. ${calculateLocationDisplay( + moduleName, + node.loc + )}`, + keys.indexOf('route') === -1 + ); + + assert( + `You cannot pass positional parameters and the \`model\` argument to the \`{{link-to}}\` component at the same time. ${calculateLocationDisplay( + moduleName, + node.loc + )}`, + keys.indexOf('model') === -1 + ); + + assert( + `You cannot pass positional parameters and the \`models\` argument to the \`{{link-to}}\` component at the same time. ${calculateLocationDisplay( + moduleName, + node.loc + )}`, + keys.indexOf('models') === -1 + ); + + assert( + `You cannot pass positional parameters and the \`query\` argument to the \`{{link-to}}\` component at the same time. ${calculateLocationDisplay( + moduleName, + node.loc + )}`, + keys.indexOf('query') === -1 + ); + } + + assert( + `You must provide one or more parameters to the \`{{link-to}}\` component. ${calculateLocationDisplay( + moduleName, + node.loc + )}`, + params.length > 0 + ); + + // 1. The last argument is possibly the `query` object. + + let query = params[params.length - 1]; + + if (query && isQueryParams(query)) { + params.pop(); + + assert( + `The \`(query-params ...)\` helper does not take positional arguments. ${calculateLocationDisplay( + moduleName, + query.loc + )}`, + query.params.length === 0 + ); + + pairs.push( + b.pair('query', b.sexpr(b.path('hash', query.path.loc), [], query.hash, query.loc), query.loc) + ); + } + + // 2. If there is a `route`, it is now at index 0. + + let route = params.shift(); + + if (route) { + pairs.push(b.pair('route', route, route.loc)); + } + + // 3. Any remaining indices (if any) are `models`. + + if (params.length === 1) { + pairs.push(b.pair('model', params[0], params[0].loc)); + } else if (params.length > 1) { + pairs.push( + b.pair('models', b.sexpr(b.path('array', node.loc), params, undefined, node.loc), node.loc) + ); + } + + return b.block( + node.path, + null, + b.hash(pairs, node.hash.loc), + node.program, + node.inverse, + node.loc + ); +} + function buildProgram(b: Builders, content: AST.Node, escaped: boolean, loc: AST.SourceLocation) { return b.program([buildStatement(b, content, escaped, loc)], undefined, loc); } @@ -20,22 +180,25 @@ function buildStatement(b: Builders, content: AST.Node, escaped: boolean, loc: A } export default function transformLinkTo(env: ASTPluginEnvironment): ASTPlugin { - let { builders: b } = env.syntax; - return { name: 'transform-link-to', visitor: { MustacheStatement(node: AST.MustacheStatement): AST.Node | void { - if (node.path.original === 'link-to') { - return b.block( - 'link-to', - node.params.slice(1), - node.hash, - buildProgram(b, node.params[0], node.escaped, node.loc), - null, - node.loc - ); + if (isInlineLinkTo(node)) { + let block = transformInlineLinkToIntoBlockForm(env, node); + + if (EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS) { + block = transformPositionalLinkToIntoNamedArguments(env, block); + } + + return block; + } + }, + + BlockStatement(node: AST.BlockStatement): AST.Node | void { + if (EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS && isBlockLinkTo(node)) { + return transformPositionalLinkToIntoNamedArguments(env, node); } }, }, diff --git a/packages/ember-template-compiler/tests/plugins/transform-link-to-test.js b/packages/ember-template-compiler/tests/plugins/transform-link-to-test.js index 3efeac0d236..7a891d330c9 100644 --- a/packages/ember-template-compiler/tests/plugins/transform-link-to-test.js +++ b/packages/ember-template-compiler/tests/plugins/transform-link-to-test.js @@ -1,95 +1,419 @@ import TransformTestCase from '../utils/transform-test-case'; +import { compile } from '../../index'; +import { EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS } from '@ember/canary-features'; import { moduleFor } from 'internal-test-helpers'; -moduleFor( - 'ember-template-compiler: transforming inline {{link-to}} into the block form', - class extends TransformTestCase { - ['@test it transforms an inline {{link-to}} into its block form']() { - this.assertTransformed(`{{link-to 'foo' 'index'}}`, `{{#link-to 'index'}}foo{{/link-to}}`); - } +if (EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS) { + moduleFor( + 'ember-template-compiler: transforming inline {{link-to}} into the block form', + class extends TransformTestCase { + ['@test it transforms an inline {{link-to}} into its block form']() { + this.assertTransformed( + `{{link-to 'foo' 'index'}}`, + `{{#link-to route='index'}}foo{{/link-to}}` + ); + } + + ['@test bound link title']() { + this.assertTransformed( + `{{link-to foo 'index'}}`, + `{{#link-to route='index'}}{{foo}}{{/link-to}}` + ); + + this.assertTransformed( + `{{link-to this.foo 'index'}}`, + `{{#link-to route='index'}}{{this.foo}}{{/link-to}}` + ); + + this.assertTransformed( + `{{link-to foo.bar.baz 'index'}}`, + `{{#link-to route='index'}}{{foo.bar.baz}}{{/link-to}}` + ); - ['@test bound link title']() { - this.assertTransformed(`{{link-to foo 'index'}}`, `{{#link-to 'index'}}{{foo}}{{/link-to}}`); + this.assertTransformed( + `{{link-to @foo 'index'}}`, + `{{#link-to route='index'}}{{@foo}}{{/link-to}}` + ); + } - this.assertTransformed( - `{{link-to this.foo 'index'}}`, - `{{#link-to 'index'}}{{this.foo}}{{/link-to}}` - ); + ['@test sexp link title']() { + this.assertTransformed( + `{{link-to (foo) 'index'}}`, + `{{#link-to route='index'}}{{foo}}{{/link-to}}` + ); - this.assertTransformed( - `{{link-to foo.bar.baz 'index'}}`, - `{{#link-to 'index'}}{{foo.bar.baz}}{{/link-to}}` - ); + this.assertTransformed( + `{{link-to (foo bar) 'index'}}`, + `{{#link-to route='index'}}{{foo bar}}{{/link-to}}` + ); - this.assertTransformed( - `{{link-to @foo 'index'}}`, - `{{#link-to 'index'}}{{@foo}}{{/link-to}}` - ); + this.assertTransformed( + `{{link-to (foo bar baz=bat) 'index'}}`, + `{{#link-to route='index'}}{{foo bar baz=bat}}{{/link-to}}` + ); + } } + ); + + moduleFor( + 'ember-template-compiler: transforming inline {{{link-to}}} into the block form', + class extends TransformTestCase { + ['@test it transforms an inline {{{link-to}}} into its block form']() { + this.assertTransformed( + `{{{link-to 'foo' 'index'}}}`, + `{{#link-to route='index'}}foo{{/link-to}}` + ); + } + + ['@test bound link title']() { + this.assertTransformed( + `{{{link-to foo 'index'}}}`, + `{{#link-to route='index'}}{{{foo}}}{{/link-to}}` + ); + + this.assertTransformed( + `{{{link-to this.foo 'index'}}}`, + `{{#link-to route='index'}}{{{this.foo}}}{{/link-to}}` + ); + + this.assertTransformed( + `{{{link-to foo.bar.baz 'index'}}}`, + `{{#link-to route='index'}}{{{foo.bar.baz}}}{{/link-to}}` + ); - ['@test sexp link title']() { - this.assertTransformed( - `{{link-to (foo) 'index'}}`, - `{{#link-to 'index'}}{{foo}}{{/link-to}}` - ); - - this.assertTransformed( - `{{link-to (foo bar) 'index'}}`, - `{{#link-to 'index'}}{{foo bar}}{{/link-to}}` - ); - - this.assertTransformed( - `{{link-to (foo bar baz=bat) 'index'}}`, - `{{#link-to 'index'}}{{foo bar baz=bat}}{{/link-to}}` - ); + this.assertTransformed( + `{{{link-to @foo 'index'}}}`, + `{{#link-to route='index'}}{{{@foo}}}{{/link-to}}` + ); + } + + ['@test sexp link title']() { + this.assertTransformed( + `{{{link-to (foo) 'index'}}}`, + `{{#link-to route='index'}}{{{foo}}}{{/link-to}}` + ); + + this.assertTransformed( + `{{{link-to (foo bar) 'index'}}}`, + `{{#link-to route='index'}}{{{foo bar}}}{{/link-to}}` + ); + + this.assertTransformed( + `{{{link-to (foo bar baz=bat) 'index'}}}`, + `{{#link-to route='index'}}{{{foo bar baz=bat}}}{{/link-to}}` + ); + } } - } -); - -moduleFor( - 'ember-template-compiler: transforming inline {{{link-to}}} into the block form', - class extends TransformTestCase { - ['@test it transforms an inline {{{link-to}}} into its block form']() { - this.assertTransformed(`{{{link-to 'foo' 'index'}}}`, `{{#link-to 'index'}}foo{{/link-to}}`); + ); + + moduleFor( + 'ember-template-compiler: transforming positional arguments into named arguments', + class extends TransformTestCase { + ['@test no arguments']() { + expectAssertion( + () => compile('{{#link-to}}zomg{{/link-to}}', { moduleName: '-top-level' }), + /You must provide one or more parameters to the `{{link-to}}` component. \('-top-level' @ L1:C0\)/ + ); + + expectAssertion( + () => compile('{{#link-to class="wow"}}zomg{{/link-to}}', { moduleName: '-top-level' }), + /You must provide one or more parameters to the `{{link-to}}` component. \('-top-level' @ L1:C0\)/ + ); + + // these are ok + + compile('{{#link-to params=foo}}zomg{{/link-to}}', { moduleName: '-top-level' }); + compile('{{#link-to route=foo}}zomg{{/link-to}}', { moduleName: '-top-level' }); + compile('{{#link-to model=foo}}zomg{{/link-to}}', { moduleName: '-top-level' }); + compile('{{#link-to models=foo}}zomg{{/link-to}}', { moduleName: '-top-level' }); + compile('{{#link-to query=foo}}zomg{{/link-to}}', { moduleName: '-top-level' }); + } + + ['@test mixing positional and named arguments']() { + expectAssertion( + () => + compile('{{#link-to foo params=bar}}zomg{{/link-to}}', { moduleName: '-top-level' }), + /cannot pass positional parameters and the `params` argument to the `{{link-to}}` component at the same time. \('-top-level' @ L1:C0\)/ + ); + + expectAssertion( + () => compile('{{#link-to foo route=bar}}zomg{{/link-to}}', { moduleName: '-top-level' }), + /cannot pass positional parameters and the `route` argument to the `{{link-to}}` component at the same time. \('-top-level' @ L1:C0\)/ + ); + + expectAssertion( + () => compile('{{#link-to foo model=bar}}zomg{{/link-to}}', { moduleName: '-top-level' }), + /cannot pass positional parameters and the `model` argument to the `{{link-to}}` component at the same time. \('-top-level' @ L1:C0\)/ + ); + + expectAssertion( + () => + compile('{{#link-to foo models=bar}}zomg{{/link-to}}', { moduleName: '-top-level' }), + /cannot pass positional parameters and the `models` argument to the `{{link-to}}` component at the same time. \('-top-level' @ L1:C0\)/ + ); + + expectAssertion( + () => compile('{{#link-to foo query=bar}}zomg{{/link-to}}', { moduleName: '-top-level' }), + /cannot pass positional parameters and the `query` argument to the `{{link-to}}` component at the same time. \('-top-level' @ L1:C0\)/ + ); + } + + ['@test route only']() { + this.assertTransformed( + `{{#link-to 'foo'}}Foo{{/link-to}}`, + `{{#link-to route='foo'}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to foo}}Foo{{/link-to}}`, + `{{#link-to route=foo}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to this.foo}}Foo{{/link-to}}`, + `{{#link-to route=this.foo}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to foo.bar.baz}}Foo{{/link-to}}`, + `{{#link-to route=foo.bar.baz}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to @foo}}Foo{{/link-to}}`, + `{{#link-to route=@foo}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to @foo}}Foo{{/link-to}}`, + `{{#link-to route=@foo}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to (foo)}}Foo{{/link-to}}`, + `{{#link-to route=(foo)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to (foo bar)}}Foo{{/link-to}}`, + `{{#link-to route=(foo bar)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to (foo bar baz=bat)}}Foo{{/link-to}}`, + `{{#link-to route=(foo bar baz=bat)}}Foo{{/link-to}}` + ); + } + + ['@test single model']() { + this.assertTransformed( + `{{#link-to 'foo' 'bar'}}Foo{{/link-to}}`, + `{{#link-to route='foo' model='bar'}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' bar}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=bar}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' this.bar}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=this.bar}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' bar.baz.bat}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=bar.baz.bat}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' @bar}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=@bar}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' (bar)}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=(bar)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' (bar baz)}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=(bar baz)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' (bar baz bat=wat)}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=(bar baz bat=wat)}}Foo{{/link-to}}` + ); + } + + ['@test multi models']() { + this.assertTransformed( + `{{#link-to 'foo' 'bar' 'baz' 'bat'}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array 'bar' 'baz' 'bat')}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' bar baz bat}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array bar baz bat)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' this.bar this.baz this.bat}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array this.bar this.baz this.bat)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' bar.baz.bat baz.bat.bar bat.bar.baz}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array bar.baz.bat baz.bat.bar bat.bar.baz)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' @bar @baz @bat}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array @bar @baz @bat)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' (bar) (baz) (bat)}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array (bar) (baz) (bat))}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' (bar baz) (baz bat) (bat bar)}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array (bar baz) (baz bat) (bat bar))}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' (bar baz bat=wat) (baz bat wat=bar) (bat wat bar=baz)}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array (bar baz bat=wat) (baz bat wat=bar) (bat wat bar=baz))}}Foo{{/link-to}}` + ); + } + + ['@test query params']() { + this.assertTransformed( + `{{#link-to (query-params)}}Foo{{/link-to}}`, + `{{#link-to query=(hash)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to (query-params foo='bar' baz=bat)}}Foo{{/link-to}}`, + `{{#link-to query=(hash foo='bar' baz=bat)}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' (query-params foo='bar' baz=bat)}}Foo{{/link-to}}`, + `{{#link-to query=(hash foo='bar' baz=bat) route='foo'}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' 'bar' (query-params foo='bar' baz=bat)}}Foo{{/link-to}}`, + `{{#link-to query=(hash foo='bar' baz=bat) route='foo' model='bar'}}Foo{{/link-to}}` + ); + + this.assertTransformed( + `{{#link-to 'foo' 'bar' 'baz' 'bat' 'wat' (query-params foo='bar' baz=bat)}}Foo{{/link-to}}`, + `{{#link-to query=(hash foo='bar' baz=bat) route='foo' models=(array 'bar' 'baz' 'bat' 'wat')}}Foo{{/link-to}}` + ); + } } + ); +} else { + moduleFor( + 'ember-template-compiler: transforming inline {{link-to}} into the block form', + class extends TransformTestCase { + ['@test it transforms an inline {{link-to}} into its block form']() { + this.assertTransformed(`{{link-to 'foo' 'index'}}`, `{{#link-to 'index'}}foo{{/link-to}}`); + } + + ['@test bound link title']() { + this.assertTransformed( + `{{link-to foo 'index'}}`, + `{{#link-to 'index'}}{{foo}}{{/link-to}}` + ); + + this.assertTransformed( + `{{link-to this.foo 'index'}}`, + `{{#link-to 'index'}}{{this.foo}}{{/link-to}}` + ); + + this.assertTransformed( + `{{link-to foo.bar.baz 'index'}}`, + `{{#link-to 'index'}}{{foo.bar.baz}}{{/link-to}}` + ); + + this.assertTransformed( + `{{link-to @foo 'index'}}`, + `{{#link-to 'index'}}{{@foo}}{{/link-to}}` + ); + } + + ['@test sexp link title']() { + this.assertTransformed( + `{{link-to (foo) 'index'}}`, + `{{#link-to 'index'}}{{foo}}{{/link-to}}` + ); + + this.assertTransformed( + `{{link-to (foo bar) 'index'}}`, + `{{#link-to 'index'}}{{foo bar}}{{/link-to}}` + ); - ['@test bound link title']() { - this.assertTransformed( - `{{{link-to foo 'index'}}}`, - `{{#link-to 'index'}}{{{foo}}}{{/link-to}}` - ); - - this.assertTransformed( - `{{{link-to this.foo 'index'}}}`, - `{{#link-to 'index'}}{{{this.foo}}}{{/link-to}}` - ); - - this.assertTransformed( - `{{{link-to foo.bar.baz 'index'}}}`, - `{{#link-to 'index'}}{{{foo.bar.baz}}}{{/link-to}}` - ); - - this.assertTransformed( - `{{{link-to @foo 'index'}}}`, - `{{#link-to 'index'}}{{{@foo}}}{{/link-to}}` - ); + this.assertTransformed( + `{{link-to (foo bar baz=bat) 'index'}}`, + `{{#link-to 'index'}}{{foo bar baz=bat}}{{/link-to}}` + ); + } } + ); + + moduleFor( + 'ember-template-compiler: transforming inline {{{link-to}}} into the block form', + class extends TransformTestCase { + ['@test it transforms an inline {{{link-to}}} into its block form']() { + this.assertTransformed( + `{{{link-to 'foo' 'index'}}}`, + `{{#link-to 'index'}}foo{{/link-to}}` + ); + } + + ['@test bound link title']() { + this.assertTransformed( + `{{{link-to foo 'index'}}}`, + `{{#link-to 'index'}}{{{foo}}}{{/link-to}}` + ); + + this.assertTransformed( + `{{{link-to this.foo 'index'}}}`, + `{{#link-to 'index'}}{{{this.foo}}}{{/link-to}}` + ); + + this.assertTransformed( + `{{{link-to foo.bar.baz 'index'}}}`, + `{{#link-to 'index'}}{{{foo.bar.baz}}}{{/link-to}}` + ); + + this.assertTransformed( + `{{{link-to @foo 'index'}}}`, + `{{#link-to 'index'}}{{{@foo}}}{{/link-to}}` + ); + } + + ['@test sexp link title']() { + this.assertTransformed( + `{{{link-to (foo) 'index'}}}`, + `{{#link-to 'index'}}{{{foo}}}{{/link-to}}` + ); + + this.assertTransformed( + `{{{link-to (foo bar) 'index'}}}`, + `{{#link-to 'index'}}{{{foo bar}}}{{/link-to}}` + ); - ['@test sexp link title']() { - this.assertTransformed( - `{{{link-to (foo) 'index'}}}`, - `{{#link-to 'index'}}{{{foo}}}{{/link-to}}` - ); - - this.assertTransformed( - `{{{link-to (foo bar) 'index'}}}`, - `{{#link-to 'index'}}{{{foo bar}}}{{/link-to}}` - ); - - this.assertTransformed( - `{{{link-to (foo bar baz=bat) 'index'}}}`, - `{{#link-to 'index'}}{{{foo bar baz=bat}}}{{/link-to}}` - ); + this.assertTransformed( + `{{{link-to (foo bar baz=bat) 'index'}}}`, + `{{#link-to 'index'}}{{{foo bar baz=bat}}}{{/link-to}}` + ); + } } - } -); + ); +} diff --git a/packages/ember-template-compiler/tests/utils/transform-test-case.ts b/packages/ember-template-compiler/tests/utils/transform-test-case.ts index 5da4d404387..1a18c7b975f 100644 --- a/packages/ember-template-compiler/tests/utils/transform-test-case.ts +++ b/packages/ember-template-compiler/tests/utils/transform-test-case.ts @@ -27,7 +27,9 @@ function ast(template: string): AST.Program { }; } - let options = compileOptions({}); + let options = compileOptions({ + moduleName: '-top-level', + }); options.plugins!.ast!.push(extractProgram);