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);