From 6e966b87eb17c538c22637d8fe399bd27f05370a Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Tue, 19 Jan 2021 16:11:22 -0800 Subject: [PATCH] [RFC 698] Deprecate `` positional arguments Implement [RFC 698](https://github.com/emberjs/rfcs/blob/master/text/0698-deprecate-link-to-positional-arguments.md) --- .../glimmer/lib/components/link-to.ts | 70 ++- .../glimmer/lib/helpers/query-param.ts | 18 +- .../integration/application/engine-test.js | 6 +- .../link-to/query-params-curly-test.js | 142 ++--- .../link-to/rendering-curly-test.js | 39 +- .../components/link-to/routing-angle-test.js | 20 +- .../components/link-to/routing-curly-test.js | 365 ++++++------ .../transitioning-classes-curly-test.js | 20 +- .../lib/plugins/transform-link-to.ts | 49 +- .../tests/plugins/transform-link-to-test.js | 556 ++++++++++-------- .../ember-testing/tests/acceptance_test.js | 2 +- .../ember/tests/routing/query_params_test.js | 10 +- ..._dependent_state_with_query_params_test.js | 10 +- .../query_param_async_get_handler_test.js | 6 +- .../query_params_paramless_link_to_test.js | 2 +- .../query_params_test/shared_state_test.js | 9 +- 16 files changed, 800 insertions(+), 524 deletions(-) diff --git a/packages/@ember/-internals/glimmer/lib/components/link-to.ts b/packages/@ember/-internals/glimmer/lib/components/link-to.ts index f3e3af24bc2..0693ee27a9a 100644 --- a/packages/@ember/-internals/glimmer/lib/components/link-to.ts +++ b/packages/@ember/-internals/glimmer/lib/components/link-to.ts @@ -6,7 +6,7 @@ import { alias, computed } from '@ember/-internals/metal'; import { getOwner } from '@ember/-internals/owner'; import RouterState from '@ember/-internals/routing/lib/system/router_state'; import { isSimpleClick } from '@ember/-internals/views'; -import { assert, warn } from '@ember/debug'; +import { assert, deprecate, runInDebug, warn } from '@ember/debug'; import { EngineInstance, getEngineParent } from '@ember/engine'; import { flaggedInstrument } from '@ember/instrumentation'; import { inject as injectService } from '@ember/service'; @@ -890,11 +890,13 @@ const LinkComponent = EmberComponent.extend({ return; } + let hasBlock = this[HAS_BLOCK]; + params = params.slice(); // Process the positional arguments, in order. // 1. Inline link title comes first, if present. - if (!this[HAS_BLOCK]) { + if (!hasBlock) { this.set('linkTitle', params.shift()); } @@ -917,6 +919,70 @@ const LinkComponent = EmberComponent.extend({ // 4. Any remaining indices (if any) are `models`. this.set('model', UNDEFINED); this.set('models', params); + + runInDebug(() => { + params = this.params.slice(); + + let equivalentNamedArgs = []; + let hasQueryParams = false; + + // Process the positional arguments, in order. + // 1. Inline link title comes first, if present. + if (!hasBlock) { + params.shift(); + } + + // 2. The last argument is possibly the `query` object. + let query = params[params.length - 1]; + + if (query && query.isQueryParams) { + params.pop(); + hasQueryParams = true; + } + + // 3. If there is a `route`, it is now at index 0. + if (params.length > 0) { + params.shift(); + equivalentNamedArgs.push('`@route`'); + } + + // 4. Any remaining params (if any) are `models`. + if (params.length === 1) { + equivalentNamedArgs.push('`@model`'); + } else if (params.length > 1) { + equivalentNamedArgs.push('`@models`'); + } + + if (hasQueryParams) { + equivalentNamedArgs.push('`@query`'); + } + + if (equivalentNamedArgs.length > 0) { + let message = 'Invoking the `` component with positional arguments is deprecated.'; + + message += `Please use the equivalent named arguments (${equivalentNamedArgs.join(', ')})`; + + if (hasQueryParams) { + message += ' along with the `hash` helper'; + } + + if (!hasBlock) { + message += " and pass a block for the link's content."; + } + + message += '.'; + + deprecate(message, false, { + id: 'ember-glimmer.link-to.positional-arguments', + until: '4.0.0', + for: 'ember-source', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-glimmer-link-to-positional-arguments', + since: { + enabled: '3.26.0-beta.1', + }, + }); + } + }); }, }); diff --git a/packages/@ember/-internals/glimmer/lib/helpers/query-param.ts b/packages/@ember/-internals/glimmer/lib/helpers/query-param.ts index a13b7efee16..98f4d047dbb 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/query-param.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/query-param.ts @@ -2,7 +2,7 @@ @module ember */ import { QueryParams } from '@ember/-internals/routing'; -import { assert } from '@ember/debug'; +import { assert, deprecate } from '@ember/debug'; import { assign } from '@ember/polyfills'; import { VMArguments } from '@glimmer/interfaces'; import { createComputeRef } from '@glimmer/reference'; @@ -35,10 +35,24 @@ export default internalHelper((args: VMArguments) => { return createComputeRef(() => { assert( - "The `query-params` helper only accepts hash parameters, e.g. (query-params queryParamPropertyName='foo') as opposed to just (query-params 'foo')", + "The `query-params` helper only accepts named arguments, e.g. (query-params queryParamPropertyName='foo') as opposed to (query-params 'foo')", positional.length === 0 ); + deprecate( + 'The `query-params` helper is deprecated. Invoke `` with the `@query` named argument and the `hash` helper instead.', + false, + { + id: 'ember-glimmer.link-to.positional-arguments', + until: '4.0.0', + for: 'ember-source', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-glimmer-link-to-positional-arguments', + since: { + enabled: '3.26.0-beta.1', + }, + } + ); + return new QueryParams(assign({}, reifyNamed(named) as any)); }); }); diff --git a/packages/@ember/-internals/glimmer/tests/integration/application/engine-test.js b/packages/@ember/-internals/glimmer/tests/integration/application/engine-test.js index e62f6cd86cb..b0e8c891186 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/application/engine-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/application/engine-test.js @@ -889,7 +889,9 @@ moduleFor( ["@test query params don't have stickiness by default between model"](assert) { assert.expect(1); - let tmpl = '{{#link-to "category" 1337}}Category 1337{{/link-to}}'; + + let tmpl = 'Category 1337'; + this.setupAppAndRoutableEngine(); this.additionalEngineRegistrations(function () { this.register('template:category', compile(tmpl)); @@ -928,7 +930,7 @@ moduleFor( ) { assert.expect(2); let tmpl = - '{{#link-to "author" 1337 class="author-1337"}}Author 1337{{/link-to}}{{#link-to "author" 1 class="author-1"}}Author 1{{/link-to}}'; + 'Author 1337Author 1'; this.setupAppAndRoutableEngine(); this.additionalEngineRegistrations(function () { this.register('template:author', compile(tmpl)); 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 730eb806f15..cbb84437ebd 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 @@ -29,7 +29,7 @@ moduleFor( ['@test populates href with fully supplied query param values']() { this.addTemplate( 'index', - `{{#link-to 'index' (query-params foo='456' bar='NAW')}}Index{{/link-to}}` + `{{#link-to route='index' query=(hash foo='456' bar='NAW')}}Index{{/link-to}}` ); return this.visit('/').then(() => { @@ -44,7 +44,7 @@ moduleFor( ['@test populates href with fully supplied query param values, but without @route param']() { this.addTemplate( 'index', - `{{#link-to (query-params foo='2' bar='NAW')}}QueryParams{{/link-to}}` + `{{#link-to query=(hash foo='2' bar='NAW')}}QueryParams{{/link-to}}` ); return this.visit('/').then(() => { @@ -57,7 +57,10 @@ moduleFor( } ['@test populates href with partially supplied query param values, but omits if value is default value']() { - this.addTemplate('index', `{{#link-to 'index' (query-params foo='123')}}Index{{/link-to}}`); + this.addTemplate( + 'index', + `{{#link-to route='index' query=(hash foo='123')}}Index{{/link-to}}` + ); return this.visit('/').then(() => { this.assertComponentElement(this.firstChild, { @@ -68,23 +71,27 @@ moduleFor( }); } - ['@test `(query-params)` can be used outside of `{{link-to}}'](assert) { + async ['@test [DEPRECATED] `query-params` can be used outside of `{{link-to}}'](assert) { if (!DEBUG) { assert.expect(0); return; } - this.addTemplate( - 'index', - `{{#let (query-params foo='456' alon='BUKAI') as |qp|}}{{link-to 'Index' 'index' qp}}{{/let}}` - ); + expectDeprecation(() => { + this.addTemplate( + 'index', + `{{#let (query-params foo='456' alon='BUKAI') as |qp|}}{{#link-to 'index' qp}}Index{{/link-to}}{{/let}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); - return this.visit('/').then(() => { - this.assertComponentElement(this.firstChild, { - tagName: 'a', - attrs: { href: '/?alon=BUKAI&foo=456', class: classMatcher('ember-view') }, - content: 'Index', - }); + await expectDeprecationAsync( + () => this.visit('/'), + /The `query-params` helper is deprecated/ + ); + this.assertComponentElement(this.firstChild, { + tagName: 'a', + attrs: { href: '/?alon=BUKAI&foo=456', class: classMatcher('ember-view') }, + content: 'Index', }); } } @@ -142,7 +149,7 @@ moduleFor( } [`@test doesn't update controller QP properties on current route when invoked`](assert) { - this.addTemplate('index', `{{#link-to 'index' id='the-link'}}Index{{/link-to}}`); + this.addTemplate('index', `{{#link-to route='index' id='the-link'}}Index{{/link-to}}`); return this.visit('/').then(() => { this.click('#the-link'); @@ -161,7 +168,7 @@ moduleFor( ) { this.addTemplate( 'index', - `{{#link-to 'index' (query-params) id='the-link'}}Index{{/link-to}}` + `{{#link-to route='index' query=(hash) id='the-link'}}Index{{/link-to}}` ); return this.visit('/').then(() => { @@ -179,7 +186,7 @@ moduleFor( [`@test doesn't update controller QP properties on current route when invoked (empty query-params obj, inferred route)`]( assert ) { - this.addTemplate('index', `{{#link-to (query-params) id='the-link'}}Index{{/link-to}}`); + this.addTemplate('index', `{{#link-to query=(hash) id='the-link'}}Index{{/link-to}}`); return this.visit('/').then(() => { this.click('#the-link'); @@ -197,7 +204,7 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to 'index' (query-params foo='456') id="the-link"}} + {{#link-to route='index' query=(hash foo='456') id="the-link"}} Index {{/link-to}} ` @@ -221,7 +228,7 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to (query-params foo='456') id="the-link"}} + {{#link-to query=(hash foo='456') id="the-link"}} Index {{/link-to}} ` @@ -249,7 +256,7 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to 'about' (query-params baz='lol') id='the-link'}} + {{#link-to route='about' query=(hash baz='lol') id='the-link'}} About {{/link-to}} ` @@ -274,7 +281,7 @@ moduleFor( ['@test supplied QP properties can be bound'](assert) { this.addTemplate( 'index', - `{{#link-to (query-params foo=this.boundThing) id='the-link'}}Index{{/link-to}}` + `{{#link-to query=(hash foo=this.boundThing) id='the-link'}}Index{{/link-to}}` ); return this.visit('/').then(() => { @@ -293,7 +300,7 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to (query-params abool=this.boundThing) id='the-link'}} + {{#link-to query=(hash abool=this.boundThing) id='the-link'}} Index {{/link-to}} ` @@ -322,7 +329,7 @@ moduleFor( async ['@test href updates when unsupplied controller QP props change'](assert) { this.addTemplate( 'index', - `{{#link-to (query-params foo='lol') id='the-link'}}Index{{/link-to}}` + `{{#link-to query=(hash foo='lol') id='the-link'}}Index{{/link-to}}` ); await this.visit('/'); @@ -350,15 +357,15 @@ moduleFor( this.addTemplate( 'cars', ` - {{#link-to 'cars.create' id='create-link'}}Create new car{{/link-to}} - {{#link-to (query-params page='2') id='page2-link'}}Page 2{{/link-to}} + {{#link-to route='cars.create' id='create-link'}}Create new car{{/link-to}} + {{#link-to query=(hash page='2') id='page2-link'}}Page 2{{/link-to}} {{outlet}} ` ); this.addTemplate( 'cars.create', - `{{#link-to 'cars' id='close-link'}}Close create form{{/link-to}}` + `{{#link-to route='cars' id='close-link'}}Close create form{{/link-to}}` ); this.router.map(function () { @@ -399,22 +406,22 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to (query-params foo='cat') id='cat-link'}}Index{{/link-to}} - {{#link-to (query-params foo='dog') id='dog-link'}}Index{{/link-to}} - {{#link-to 'index' id='change-nothing'}}Index{{/link-to}} + {{#link-to query=(hash foo='cat') id='cat-link'}}Index{{/link-to}} + {{#link-to query=(hash foo='dog') id='dog-link'}}Index{{/link-to}} + {{#link-to route='index' id='change-nothing'}}Index{{/link-to}} ` ); this.addTemplate( 'search', ` - {{#link-to (query-params search='same') id='same-search'}}Index{{/link-to}} - {{#link-to (query-params search='change') id='change-search'}}Index{{/link-to}} - {{#link-to (query-params search='same' archive=true) id='same-search-add-archive'}}Index{{/link-to}} - {{#link-to (query-params archive=true) id='only-add-archive'}}Index{{/link-to}} - {{#link-to (query-params search='same' archive=true) id='both-same'}}Index{{/link-to}} - {{#link-to (query-params search='different' archive=true) id='change-one'}}Index{{/link-to}} - {{#link-to (query-params search='different' archive=false) id='remove-one'}}Index{{/link-to}} + {{#link-to query=(hash search='same') id='same-search'}}Index{{/link-to}} + {{#link-to query=(hash search='change') id='change-search'}}Index{{/link-to}} + {{#link-to query=(hash search='same' archive=true) id='same-search-add-archive'}}Index{{/link-to}} + {{#link-to query=(hash archive=true) id='only-add-archive'}}Index{{/link-to}} + {{#link-to query=(hash search='same' archive=true) id='both-same'}}Index{{/link-to}} + {{#link-to query=(hash search='different' archive=true) id='change-one'}}Index{{/link-to}} + {{#link-to query=(hash search='different' archive=false) id='remove-one'}}Index{{/link-to}} {{outlet}} ` ); @@ -422,13 +429,13 @@ moduleFor( this.addTemplate( 'search.results', ` - {{#link-to (query-params sort='title') id='same-sort-child-only'}}Index{{/link-to}} - {{#link-to (query-params search='same') id='same-search-parent-only'}}Index{{/link-to}} - {{#link-to (query-params search='change') id='change-search-parent-only'}}Index{{/link-to}} - {{#link-to (query-params search='same' sort='title') id='same-search-same-sort-child-and-parent'}}Index{{/link-to}} - {{#link-to (query-params search='same' sort='author') id='same-search-different-sort-child-and-parent'}}Index{{/link-to}} - {{#link-to (query-params search='change' sort='title') id='change-search-same-sort-child-and-parent'}}Index{{/link-to}} - {{#link-to (query-params foo='dog') id='dog-link'}}Index{{/link-to}} + {{#link-to query=(hash sort='title') id='same-sort-child-only'}}Index{{/link-to}} + {{#link-to query=(hash search='same') id='same-search-parent-only'}}Index{{/link-to}} + {{#link-to query=(hash search='change') id='change-search-parent-only'}}Index{{/link-to}} + {{#link-to query=(hash search='same' sort='title') id='same-search-same-sort-child-and-parent'}}Index{{/link-to}} + {{#link-to query=(hash search='same' sort='author') id='same-search-different-sort-child-and-parent'}}Index{{/link-to}} + {{#link-to query=(hash search='change' sort='title') id='change-search-same-sort-child-and-parent'}}Index{{/link-to}} + {{#link-to query=(hash foo='dog') id='dog-link'}}Index{{/link-to}} ` ); @@ -505,7 +512,7 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to (query-params page=this.pageNumber) id='page-link'}} + {{#link-to query=(hash page=this.pageNumber) id='page-link'}} Index {{/link-to}} ` @@ -534,9 +541,9 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to (query-params pages=this.pagesArray) id='array-link'}}Index{{/link-to}} - {{#link-to (query-params pages=this.biggerArray) id='bigger-link'}}Index{{/link-to}} - {{#link-to (query-params pages=this.emptyArray) id='empty-link'}}Index{{/link-to}} + {{#link-to query=(hash pages=this.pagesArray) id='array-link'}}Index{{/link-to}} + {{#link-to query=(hash pages=this.biggerArray) id='bigger-link'}}Index{{/link-to}} + {{#link-to query=(hash pages=this.emptyArray) id='empty-link'}}Index{{/link-to}} ` ); @@ -587,9 +594,9 @@ moduleFor( this.addTemplate( 'application', ` - {{#link-to 'parent' id='parent-link'}}Parent{{/link-to}} - {{#link-to 'parent.child' id='parent-child-link'}}Child{{/link-to}} - {{#link-to 'parent' (query-params foo=this.cat) id='parent-link-qp'}}Parent{{/link-to}} + {{#link-to route='parent' id='parent-link'}}Parent{{/link-to}} + {{#link-to route='parent.child' id='parent-child-link'}}Child{{/link-to}} + {{#link-to route='parent' query=(hash foo=this.cat) id='parent-link-qp'}}Parent{{/link-to}} {{outlet}} ` ); @@ -627,7 +634,7 @@ moduleFor( this.addTemplate( 'application', ` - {{#link-to 'parent' (query-params page=1) current-when='parent' id='app-link'}} + {{#link-to route='parent' query=(hash page=1) current-when='parent' id='app-link'}} Parent {{/link-to}} {{outlet}} @@ -637,7 +644,7 @@ moduleFor( this.addTemplate( 'parent', ` - {{#link-to 'parent' (query-params page=1) current-when='parent' id='parent-link'}} + {{#link-to route='parent' query=(hash page=1) current-when='parent' id='parent-link'}} Parent {{/link-to}} {{outlet}} @@ -698,9 +705,9 @@ moduleFor( this.addTemplate( 'application', ` - {{link-to 'Foos' 'foos' id='foos-link'}} - {{link-to 'Baz Foos' 'foos' (query-params baz=true) id='baz-foos-link'}} - {{link-to 'Quux Bars' 'bars' (query-params quux=true) id='bars-link'}} + {{#link-to route='foos' id='foos-link'}}Foos{{/link-to}} + {{#link-to route='foos' query=(hash baz=true) id='baz-foos-link'}}Baz Foos{{/link-to}} + {{#link-to route='bars' query=(hash quux=true) id='bars-link'}}Quux Bars{{/link-to}} ` ); @@ -771,7 +778,7 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to (query-params page=this.pageNumber) id='page-link'}} + {{#link-to query=(hash page=this.pageNumber) id='page-link'}} Index {{/link-to}} ` @@ -809,7 +816,7 @@ moduleFor( }); } - ['@test [GH#17869] it does not cause shadowing assertion with `hash` local variable']() { + ['@test [DEPRECATED] [GH#17869] it does not cause shadowing assertion with `hash` local variable']() { this.router.map(function () { this.route('post', { path: '/post/:id' }); }); @@ -822,14 +829,16 @@ moduleFor( }) ); - this.addTemplate( - 'index', - ` - {{#let (hash id="1" title="Hello World!" body="Lorem ipsum dolor sit amet...") as |hash|}} - {{#link-to "post" hash (query-params showComments=false)}}View Post{{/link-to}} - {{/let}} - ` - ); + expectDeprecation(() => { + this.addTemplate( + 'index', + ` + {{#let (hash id="1" title="Hello World!" body="Lorem ipsum dolor sit amet...") as |hash|}} + {{#link-to "post" hash (query-params showComments=false)}}View Post{{/link-to}} + {{/let}} + ` + ); + }, /Invoking the `` component with positional arguments is deprecated/); return this.visit('/').then(() => { this.assertComponentElement(this.element.firstElementChild, { @@ -851,8 +860,7 @@ moduleFor( }); }); - this.addTemplate('foo.bar', `{{link-to 'Baz' 'foo.bar.baz' id='baz-link'}}`); - + this.addTemplate('foo.bar', `{{#link-to route='foo.bar.baz' id='baz-link'}}Baz{{/link-to}}`); this.addTemplate('foo.bar.loading', 'Loading'); this.add( 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 ab11e4f2a69..02478a8cc93 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 @@ -16,7 +16,7 @@ moduleFor( } ['@test should be able to be inserted in DOM when the router is not present']() { - this.addTemplate('application', `{{#link-to 'index'}}Go to Index{{/link-to}}`); + this.addTemplate('application', `{{#link-to route='index'}}Go to Index{{/link-to}}`); return this.visit('/').then(() => { this.assertText('Go to Index'); @@ -26,7 +26,7 @@ moduleFor( ['@test re-renders when title changes']() { let controller; - this.addTemplate('application', `{{link-to this.title 'index'}}`); + this.addTemplate('application', `{{#link-to route='index'}}{{this.title}}{{/link-to}}`); this.add( 'controller:application', @@ -49,7 +49,7 @@ moduleFor( ['@test re-computes active class when params change'](assert) { let controller; - this.addTemplate('application', '{{link-to "foo" this.routeName}}'); + this.addTemplate('application', '{{#link-to route=this.routeName}}foo{{/link-to}}'); this.add( 'controller:application', @@ -73,8 +73,10 @@ moduleFor( }); } - ['@test escaped inline form (double curlies) escapes link title']() { - this.addTemplate('application', `{{link-to this.title 'index'}}`); + ['@test [DEPRECATED] escaped inline form (double curlies) escapes link title']() { + expectDeprecation(() => { + this.addTemplate('application', `{{link-to this.title 'index'}}`); + }, /Invoking the `` component with positional arguments is deprecated/); this.add( 'controller:application', Controller.extend({ @@ -87,8 +89,10 @@ moduleFor( }); } - ['@test unescaped inline form (triple curlies) does not escape link title'](assert) { - this.addTemplate('application', `{{{link-to this.title 'index'}}}`); + ['@test [DEPRECATED] unescaped inline form (triple curlies) does not escape link title'](assert) { + expectDeprecation(() => { + this.addTemplate('application', `{{{link-to this.title 'index'}}}`); + }, /Invoking the `` component with positional arguments is deprecated/); this.add( 'controller:application', Controller.extend({ @@ -108,7 +112,7 @@ moduleFor( }); this.addTemplate( 'application', - `{{#custom-link-to 'index'}}{{this.title}}{{/custom-link-to}}` + `{{#custom-link-to route='index'}}{{this.title}}{{/custom-link-to}}` ); this.add( 'controller:application', @@ -122,7 +126,7 @@ moduleFor( }); } - ['@test [GH#13432] able to safely extend the built-in component and invoke it inline']() { + async ['@test [DEPRECATED] [GH#13432] able to safely extend the built-in component and invoke it inline']() { this.addComponent('custom-link-to', { ComponentClass: LinkComponent.extend(), }); @@ -134,9 +138,12 @@ moduleFor( }) ); - return this.visit('/').then(() => { - this.assertText('Hello'); - }); + await expectDeprecationAsync( + () => this.visit('/'), + /Invoking the `` component with positional arguments is deprecated/ + ); + + this.assertText('Hello'); } } ); @@ -145,13 +152,15 @@ moduleFor( '{{link-to}} component (rendering tests, without router)', class extends RenderingTestCase { ['@test should be able to be inserted in DOM when the router is not present - block']() { - this.render(`{{#link-to 'index'}}Go to Index{{/link-to}}`); + this.render(`{{#link-to route='index'}}Go to Index{{/link-to}}`); this.assertText('Go to Index'); } - ['@test should be able to be inserted in DOM when the router is not present - inline']() { - this.render(`{{link-to 'Go to Index' 'index'}}`); + ['@test [DEPRECATED] should be able to be inserted in DOM when the router is not present - inline']() { + expectDeprecation(() => { + this.render(`{{link-to 'Go to Index' 'index'}}`); + }, /Invoking the `` component with positional arguments is deprecated/); this.assertText('Go to Index'); } diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-angle-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-angle-test.js index 829ef19c71a..91ea9d91b1b 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-angle-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-angle-test.js @@ -1801,7 +1801,7 @@ moduleFor( }); } - [`@test The component can use dynamic params`](assert) { + async [`@test [DEPRECATED] The component can use dynamic params`](assert) { this.router.map(function () { this.route('foo', { path: 'foo/:some/:thing' }); this.route('bar', { path: 'bar/:some/:thing/:else' }); @@ -1825,18 +1825,24 @@ moduleFor( ` ); - return this.visit('/').then(() => { - let link = this.$('#dynamic-link'); + await expectDeprecationAsync( + () => this.visit('/'), + /Invoking the `` component with positional arguments is deprecated/ + ); - assert.equal(link.attr('href'), '/foo/one/two'); + let link = this.$('#dynamic-link'); - let controller = this.applicationInstance.lookup('controller:index'); + assert.equal(link.attr('href'), '/foo/one/two'); + + let controller = this.applicationInstance.lookup('controller:index'); + + expectDeprecation(() => { runTask(() => { controller.set('dynamicLinkParams', ['bar', 'one', 'two', 'three']); }); + }, /Invoking the `` component with positional arguments is deprecated/); - assert.equal(link.attr('href'), '/bar/one/two/three'); - }); + assert.equal(link.attr('href'), '/bar/one/two/three'); } [`@test GJ: to a parent root model hook which performs a 'transitionTo' has correct active class #13256`]( diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-curly-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-curly-test.js index 3e6a431564d..7bd4b34e3bb 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-curly-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-curly-test.js @@ -47,16 +47,16 @@ moduleFor( 'index', `

Home

- {{#link-to 'about' id='about-link'}}About{{/link-to}} - {{#link-to 'index' id='self-link'}}Self{{/link-to}} + {{#link-to route='about' id='about-link'}}About{{/link-to}} + {{#link-to route='index' id='self-link'}}Self{{/link-to}} ` ); this.addTemplate( 'about', `

About

- {{#link-to 'index' id='home-link'}}Home{{/link-to}} - {{#link-to 'about' id='self-link'}}Self{{/link-to}} + {{#link-to route='index' id='home-link'}}Home{{/link-to}} + {{#link-to route='about' id='self-link'}}Self{{/link-to}} ` ); } @@ -96,7 +96,7 @@ moduleFor( [`@test the {{link-to}} component doesn't add an href when the tagName isn't 'a'`](assert) { this.addTemplate( 'index', - `{{#link-to 'about' id='about-link' tagName='div'}}About{{/link-to}}` + `{{#link-to route='about' id='about-link' tagName='div'}}About{{/link-to}}` ); return this.visit('/').then(() => { @@ -108,8 +108,8 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to "about" id="about-link-static" disabledWhen="shouldDisable"}}About{{/link-to}} - {{#link-to "about" id="about-link-dynamic" disabledWhen=this.dynamicDisabledWhen}}About{{/link-to}} + {{#link-to route="about" id="about-link-static" disabledWhen="shouldDisable"}}About{{/link-to}} + {{#link-to route="about" id="about-link-dynamic" disabledWhen=this.dynamicDisabledWhen}}About{{/link-to}} ` ); @@ -147,7 +147,7 @@ moduleFor( [`@test the {{link-to}} component doesn't apply a 'disabled' class if disabledWhen is not provided`]( assert ) { - this.addTemplate('index', `{{#link-to "about" id="about-link"}}About{{/link-to}}`); + this.addTemplate('index', `{{#link-to route="about" id="about-link"}}About{{/link-to}}`); return this.visit('/').then(() => { assert.ok( @@ -160,7 +160,7 @@ moduleFor( [`@test the {{link-to}} component supports a custom disabledClass`](assert) { this.addTemplate( 'index', - `{{#link-to "about" id="about-link" disabledWhen=true disabledClass="do-not-want"}}About{{/link-to}}` + `{{#link-to route="about" id="about-link" disabledWhen=true disabledClass="do-not-want"}}About{{/link-to}}` ); return this.visit('/').then(() => { @@ -177,7 +177,7 @@ moduleFor( ) { this.addTemplate( 'index', - `{{#link-to "about" id="about-link" disabledWhen=true disabledClass=this.disabledClass}}About{{/link-to}}` + `{{#link-to route="about" id="about-link" disabledWhen=true disabledClass=this.disabledClass}}About{{/link-to}}` ); this.add( @@ -199,7 +199,7 @@ moduleFor( [`@test the {{link-to}} component does not respond to clicks when disabledWhen`](assert) { this.addTemplate( 'index', - `{{#link-to "about" id="about-link" disabledWhen=true}}About{{/link-to}}` + `{{#link-to route="about" id="about-link" disabledWhen=true}}About{{/link-to}}` ); return this.visit('/') @@ -214,7 +214,7 @@ moduleFor( [`@test the {{link-to}} component does not respond to clicks when disabled`](assert) { this.addTemplate( 'index', - `{{#link-to "about" id="about-link" disabled=true}}About{{/link-to}}` + `{{#link-to route="about" id="about-link" disabled=true}}About{{/link-to}}` ); return this.visit('/') @@ -231,7 +231,7 @@ moduleFor( ) { this.addTemplate( 'index', - `{{#link-to "about" id="about-link" disabledWhen=this.disabledWhen}}About{{/link-to}}` + `{{#link-to route="about" id="about-link" disabledWhen=this.disabledWhen}}About{{/link-to}}` ); this.add( @@ -270,8 +270,8 @@ moduleFor( 'index', `

Home

- {{#link-to 'about' id='about-link'}}About{{/link-to}} - {{#link-to 'index' id='self-link' activeClass='zomg-active'}}Self{{/link-to}} + {{#link-to route='about' id='about-link'}}About{{/link-to}} + {{#link-to route='index' id='self-link' activeClass='zomg-active'}}Self{{/link-to}} ` ); @@ -295,8 +295,8 @@ moduleFor( 'index', `

Home

- {{#link-to 'about' id='about-link'}}About{{/link-to}} - {{#link-to 'index' id='self-link' activeClass=this.activeClass}}Self{{/link-to}} + {{#link-to route='about' id='about-link'}}About{{/link-to}} + {{#link-to route='index' id='self-link' activeClass=this.activeClass}}Self{{/link-to}} ` ); @@ -333,7 +333,7 @@ moduleFor( 'index', `

Home

- {{#link-to 'about' id='about-link' classNameBindings='this.foo:foo-is-true:foo-is-false'}}About{{/link-to}} + {{#link-to route='about' id='about-link' classNameBindings='this.foo:foo-is-true:foo-is-false'}}About{{/link-to}} ` ); @@ -372,7 +372,7 @@ moduleFor( super.init(...arguments); this.register( 'template:application', - compile(`{{#link-to 'about'}}About{{/link-to}}`, { + compile(`{{#link-to route='about'}}About{{/link-to}}`, { moduleName: 'non-routable/templates/application.hbs', }) ); @@ -404,7 +404,7 @@ moduleFor( `

Routable Engine

{{outlet}} - {{#link-to 'application' id='engine-application-link'}}Engine Appliction{{/link-to}} + {{#link-to route='application' id='engine-application-link'}}Engine Application{{/link-to}} `, { moduleName: 'routable/templates/application.hbs', @@ -416,8 +416,8 @@ moduleFor( compile( `

Engine Home

- {{#link-to 'about' id='engine-about-link'}}Engine About{{/link-to}} - {{#link-to 'index' id='engine-self-link'}}Engine Self{{/link-to}} + {{#link-to route='about' id='engine-about-link'}}Engine About{{/link-to}} + {{#link-to route='index' id='engine-self-link'}}Engine Self{{/link-to}} `, { moduleName: 'routable/templates/index.hbs', @@ -429,8 +429,8 @@ moduleFor( compile( `

Engine About

- {{#link-to 'index' id='engine-home-link'}}Engine Home{{/link-to}} - {{#link-to 'about' id='engine-self-link'}}Engine Self{{/link-to}} + {{#link-to route='index' id='engine-home-link'}}Engine Home{{/link-to}} + {{#link-to route='about' id='engine-self-link'}}Engine Self{{/link-to}} `, { moduleName: 'routable/templates/about.hbs', @@ -454,8 +454,8 @@ moduleFor( `

Application

{{outlet}} - {{#link-to 'application' id='application-link'}}Appliction{{/link-to}} - {{#link-to 'routable' id='engine-link'}}Engine{{/link-to}} + {{#link-to route='application' id='application-link'}}Appliction{{/link-to}} + {{#link-to route='routable' id='engine-link'}}Engine{{/link-to}} ` ); @@ -599,16 +599,16 @@ moduleFor( 'index', `

Home

- {{#link-to 'about' id='about-link'}}About{{/link-to}} - {{#link-to 'index' id='self-link'}}Self{{/link-to}} + {{#link-to route='about' id='about-link'}}About{{/link-to}} + {{#link-to route='index' id='self-link'}}Self{{/link-to}} ` ); this.addTemplate( 'about', `

About

- {{#link-to 'index' id='home-link'}}Home{{/link-to}} - {{#link-to 'about' id='self-link'}}Self{{/link-to}} + {{#link-to route='index' id='home-link'}}Home{{/link-to}} + {{#link-to route='about' id='self-link'}}Self{{/link-to}} ` ); } @@ -625,7 +625,7 @@ moduleFor( 'index', `

Home

- {{#link-to 'about' id='about-link' replace=true}}About{{/link-to}} + {{#link-to route='about' id='about-link' replace=true}}About{{/link-to}} ` ); @@ -650,7 +650,7 @@ moduleFor( 'index', `

Home

- {{#link-to 'about' id='about-link' replace=this.boundTruthyThing}}About{{/link-to}} + {{#link-to route='about' id='about-link' replace=this.boundTruthyThing}}About{{/link-to}} ` ); @@ -680,7 +680,7 @@ moduleFor( 'index', `

Home

- {{#link-to 'about' id='about-link' replace=this.boundFalseyThing}}About{{/link-to}} + {{#link-to route='about' id='about-link' replace=this.boundFalseyThing}}About{{/link-to}} ` ); @@ -722,16 +722,16 @@ if (EMBER_IMPROVED_INSTRUMENTATION) { 'index', `

Home

- {{#link-to 'about' id='about-link'}}About{{/link-to}} - {{#link-to 'index' id='self-link'}}Self{{/link-to}} + {{#link-to route='about' id='about-link'}}About{{/link-to}} + {{#link-to route='index' id='self-link'}}Self{{/link-to}} ` ); this.addTemplate( 'about', `

About

- {{#link-to 'index' id='home-link'}}Home{{/link-to}} - {{#link-to 'about' id='self-link'}}Self{{/link-to}} + {{#link-to route='index' id='home-link'}}Home{{/link-to}} + {{#link-to route='about' id='self-link'}}Self{{/link-to}} ` ); } @@ -810,7 +810,10 @@ moduleFor( this.addTemplate('about', `

About

{{outlet}}`); this.addTemplate('about.index', `
Index
`); - this.addTemplate('about.item', `
{{#link-to 'about'}}About{{/link-to}}
`); + this.addTemplate( + 'about.item', + `
{{#link-to route='about'}}About{{/link-to}}
` + ); return this.visit('/about/item').then(() => { assert.equal(normalizeUrl(this.$('#item a').attr('href')), '/about'); @@ -829,7 +832,7 @@ moduleFor( this.addTemplate('index', `

Home

{{outlet}}`); this.addTemplate( 'index.about', - `{{#link-to 'item' id='other-link' current-when='index'}}ITEM{{/link-to}}` + `{{#link-to route='item' id='other-link' current-when='index'}}ITEM{{/link-to}}` ); return this.visit('/about').then(() => { @@ -857,7 +860,7 @@ moduleFor( this.addTemplate('index', `

Home

{{outlet}}`); this.addTemplate( 'index.about', - `{{#link-to 'items' id='other-link' current-when='index'}}ITEM{{/link-to}}` + `{{#link-to route='items' id='other-link' current-when='index'}}ITEM{{/link-to}}` ); return this.visit('/about').then(() => { @@ -892,7 +895,7 @@ moduleFor( this.addTemplate('index', `

Home

{{outlet}}`); this.addTemplate( 'index.about', - `{{#link-to 'items' id='other-link' current-when=this.currentWhen}}ITEM{{/link-to}}` + `{{#link-to route='items' id='other-link' current-when=this.currentWhen}}ITEM{{/link-to}}` ); return this.visit('/about').then(() => { @@ -916,15 +919,15 @@ moduleFor( this.addTemplate('index', `

Home

{{outlet}}`); this.addTemplate( 'index.about', - `{{#link-to 'item' id='link1' current-when='item index'}}ITEM{{/link-to}}` + `{{#link-to route='item' id='link1' current-when='item index'}}ITEM{{/link-to}}` ); this.addTemplate( 'item', - `{{#link-to 'item' id='link2' current-when='item index'}}ITEM{{/link-to}}` + `{{#link-to route='item' id='link2' current-when='item index'}}ITEM{{/link-to}}` ); this.addTemplate( 'foo', - `{{#link-to 'item' id='link3' current-when='item index'}}ITEM{{/link-to}}` + `{{#link-to route='item' id='link3' current-when='item index'}}ITEM{{/link-to}}` ); return this.visit('/about') @@ -966,8 +969,8 @@ moduleFor( this.addTemplate( 'index.about', ` - {{#link-to 'index' id='index-link' current-when=this.isCurrent}}index{{/link-to}} - {{#link-to 'item' id='about-link' current-when=true}}ITEM{{/link-to}} + {{#link-to route='index' id='index-link' current-when=this.isCurrent}}index{{/link-to}} + {{#link-to route='item' id='about-link' current-when=true}}ITEM{{/link-to}} ` ); @@ -998,7 +1001,7 @@ moduleFor( 'about', `
- {{#link-to 'about.contact' id='about-contact'}}About{{/link-to}} + {{#link-to route='about.contact' id='about-contact'}}About{{/link-to}}
{{outlet}} ` @@ -1041,7 +1044,7 @@ moduleFor( 'about', `
- {{#link-to 'about.contact' id='about-contact' bubbles=false}} + {{#link-to route='about.contact' id='about-contact' bubbles=false}} About {{/link-to}}
@@ -1085,7 +1088,7 @@ moduleFor( 'about', `
- {{#link-to 'about.contact' id='about-contact' bubbles=this.boundFalseyThing}} + {{#link-to route='about.contact' id='about-contact' bubbles=this.boundFalseyThing}} About {{/link-to}}
@@ -1144,13 +1147,13 @@ moduleFor(
    {{#each @model as |person|}}
  • - {{#link-to 'item' person id=person.id}} + {{#link-to route='item' model=person id=person.id}} {{person.name}} {{/link-to}}
  • {{/each}}
- {{#link-to 'index' id='home-link'}}Home{{/link-to}} + {{#link-to route='index' id='home-link'}}Home{{/link-to}} ` ); @@ -1159,7 +1162,7 @@ moduleFor( `

Item

{{@model.name}}

- {{#link-to 'index' id='home-link'}}Home{{/link-to}} + {{#link-to route='index' id='home-link'}}Home{{/link-to}} ` ); @@ -1167,7 +1170,7 @@ moduleFor( 'index', `

Home

- {{#link-to 'about' id='about-link'}}About{{/link-to}} + {{#link-to route='about' id='about-link'}}About{{/link-to}} ` ); @@ -1217,7 +1220,7 @@ moduleFor( 'index', `

Home

- {{#link-to 'index' id='self-link' title='title-attr' rel='rel-attr' tabindex='-1'}} + {{#link-to route='index' id='self-link' title='title-attr' rel='rel-attr' tabindex='-1'}} Self {{/link-to}} ` @@ -1236,7 +1239,7 @@ moduleFor( 'index', `

Home

- {{#link-to 'index' id='self-link' target='_blank'}}Self{{/link-to}} + {{#link-to route='index' id='self-link' target='_blank'}}Self{{/link-to}} ` ); @@ -1251,7 +1254,7 @@ moduleFor( ) { this.addTemplate( 'index', - `

Home

{{#link-to 'index' id='self-link' target=this.boundLinkTarget}}Self{{/link-to}}` + `

Home

{{#link-to route='index' id='self-link' target=this.boundLinkTarget}}Self{{/link-to}}` ); this.add( @@ -1272,7 +1275,7 @@ moduleFor( this.route('about'); }); - this.addTemplate('index', `{{#link-to 'about' id='about-link'}}About{{/link-to}}`); + this.addTemplate('index', `{{#link-to route='about' id='about-link'}}About{{/link-to}}`); return this.visit('/').then(() => { assertNav({ prevented: true }, () => this.$('#about-link').click(), assert); @@ -1288,7 +1291,7 @@ moduleFor( this.addTemplate( 'index', - `{{#link-to 'about' id='about-link' preventDefault=false}}About{{/link-to}}` + `{{#link-to route='about' id='about-link' preventDefault=false}}About{{/link-to}}` ); return this.visit('/').then(() => { @@ -1305,7 +1308,7 @@ moduleFor( this.addTemplate( 'index', - `{{#link-to 'about' id='about-link' preventDefault=this.boundFalseyThing}}About{{/link-to}}` + `{{#link-to route='about' id='about-link' preventDefault=this.boundFalseyThing}}About{{/link-to}}` ); this.add( @@ -1327,7 +1330,7 @@ moduleFor( 'index', `

Home

- {{#link-to 'index' id='self-link' target='_blank'}}Self{{/link-to}} + {{#link-to route='index' id='self-link' target='_blank'}}Self{{/link-to}} ` ); @@ -1341,7 +1344,7 @@ moduleFor( 'index', `

Home

- {{#link-to 'index' id='self-link' target='_self'}}Self{{/link-to}} + {{#link-to route='index' id='self-link' target='_self'}}Self{{/link-to}} ` ); @@ -1356,7 +1359,7 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to 'about' id='about-link' replace=true target='_blank'}} + {{#link-to route='about' id='about-link' replace=true target='_blank'}} About {{/link-to}} ` @@ -1402,11 +1405,11 @@ moduleFor( 'filter', `

{{this.filter}}

- {{#link-to "filter" "unpopular" id="link"}}Unpopular{{/link-to}} - {{#link-to "filter" this.filter id="path-link"}}Unpopular{{/link-to}} - {{#link-to "post" this.post_id id="post-path-link"}}Post{{/link-to}} - {{#link-to "post" 123 id="post-number-link"}}Post{{/link-to}} - {{#link-to "repo" this.repo id="repo-object-link"}}Repo{{/link-to}} + {{#link-to route="filter" model="unpopular" id="link"}}Unpopular{{/link-to}} + {{#link-to route="filter" model=this.filter id="path-link"}}Unpopular{{/link-to}} + {{#link-to route="post" model=this.post_id id="post-path-link"}}Post{{/link-to}} + {{#link-to route="post" model=123 id="post-number-link"}}Post{{/link-to}} + {{#link-to route="repo" model=this.repo id="repo-object-link"}}Repo{{/link-to}} ` ); @@ -1445,12 +1448,12 @@ moduleFor( this.addTemplate( 'lobby.index', - `{{#link-to 'lobby' 'foobar' id='lobby-link'}}Lobby{{/link-to}}` + `{{#link-to route='lobby' model='foobar' id='lobby-link'}}Lobby{{/link-to}}` ); this.addTemplate( 'lobby.list', - `{{#link-to 'lobby' 'foobar' id='lobby-link'}}Lobby{{/link-to}}` + `{{#link-to route='lobby' model='foobar' id='lobby-link'}}Lobby{{/link-to}}` ); return this.visit('/lobby/list') @@ -1466,8 +1469,8 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to 'index' id='string-link'}}string{{/link-to}} - {{#link-to this.foo id='path-link'}}path{{/link-to}} + {{#link-to route='index' id='string-link'}}string{{/link-to}} + {{#link-to route=this.foo id='path-link'}}path{{/link-to}} ` ); @@ -1501,7 +1504,10 @@ moduleFor( let post = { id: '1' }; let secondPost = { id: '2' }; - this.addTemplate('index', `{{#link-to "post" this.post id="post"}}post{{/link-to}}`); + this.addTemplate( + 'index', + `{{#link-to route="post" model=this.post id="post"}}post{{/link-to}}` + ); this.add('controller:index', Controller.extend()); @@ -1544,8 +1550,8 @@ moduleFor( 'about', `
- {{#link-to 'about' id='about-link'}}About{{/link-to}} - {{#link-to 'about.item' id='item-link'}}Item{{/link-to}} + {{#link-to route='about' id='about-link'}}About{{/link-to}} + {{#link-to route='about.item' id='item-link'}}Item{{/link-to}} {{outlet}}
` @@ -1584,13 +1590,13 @@ moduleFor( 'index', ` {{#each this.routeNames as |routeName|}} - {{#link-to routeName}}{{routeName}}{{/link-to}} + {{#link-to route=routeName}}{{routeName}}{{/link-to}} {{/each}} {{#each this.routeNames as |r|}} - {{#link-to r}}{{r}}{{/link-to}} + {{#link-to route=r}}{{r}}{{/link-to}} {{/each}} - {{#link-to this.route1}}a{{/link-to}} - {{#link-to this.route2}}b{{/link-to}} + {{#link-to route=this.route1}}a{{/link-to}} + {{#link-to route=this.route2}}b{{/link-to}} ` ); @@ -1623,28 +1629,32 @@ moduleFor( }); } - [`@test The non-block form {{link-to}} component moves into the named route`](assert) { - assert.expect(3); + [`@test [DEPRECATED] The non-block form {{link-to}} component moves into the named route`](assert) { + assert.expect(5); this.router.map(function () { this.route('contact'); }); - this.addTemplate( - 'index', - ` -

Home

- {{link-to 'Contact us' 'contact' id='contact-link'}} - {{#link-to 'index' id='self-link'}}Self{{/link-to}} - ` - ); - this.addTemplate( - 'contact', - ` -

Contact

- {{link-to 'Home' 'index' id='home-link'}} - {{link-to 'Self' 'contact' id='self-link'}} - ` - ); + expectDeprecation(() => { + this.addTemplate( + 'index', + ` +

Home

+ {{link-to 'Contact us' 'contact' id='contact-link'}} + {{#link-to route='index' id='self-link'}}Self{{/link-to}} + ` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + expectDeprecation(() => { + this.addTemplate( + 'contact', + ` +

Contact

+ {{link-to 'Home' 'index' id='home-link'}} + {{link-to 'Self' 'contact' id='self-link'}} + ` + ); + }, /Invoking the `` component with positional arguments is deprecated/); return this.visit('/') .then(() => { @@ -1665,10 +1675,10 @@ moduleFor( }); } - [`@test The non-block form {{link-to}} component updates the link text when it is a binding`]( + [`@test [DEPRECATED] The non-block form {{link-to}} component updates the link text when it is a binding`]( assert ) { - assert.expect(8); + assert.expect(10); this.router.map(function () { this.route('contact'); }); @@ -1680,22 +1690,26 @@ moduleFor( }) ); - this.addTemplate( - 'index', - ` -

Home

- {{link-to this.contactName 'contact' id='contact-link'}} - {{#link-to 'index' id='self-link'}}Self{{/link-to}} - ` - ); - this.addTemplate( - 'contact', - ` -

Contact

- {{link-to 'Home' 'index' id='home-link'}} - {{link-to 'Self' 'contact' id='self-link'}} - ` - ); + expectDeprecation(() => { + this.addTemplate( + 'index', + ` +

Home

+ {{link-to this.contactName 'contact' id='contact-link'}} + {{#link-to route='index' id='self-link'}}Self{{/link-to}} + ` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + expectDeprecation(() => { + this.addTemplate( + 'contact', + ` +

Contact

+ {{link-to 'Home' 'index' id='home-link'}} + {{link-to 'Self' 'contact' id='self-link'}} + ` + ); + }, /Invoking the `` component with positional arguments is deprecated/); return this.visit('/') .then(() => { @@ -1749,10 +1763,10 @@ moduleFor( }); } - async [`@test The non-block form {{link-to}} component moves into the named route with context`]( + async [`@test [DEPRECATED] The non-block form {{link-to}} component moves into the named route with context`]( assert ) { - assert.expect(5); + assert.expect(6); this.router.map(function () { this.route('item', { path: '/item/:id' }); @@ -1771,25 +1785,27 @@ moduleFor( }) ); - this.addTemplate( - 'index', - ` -

Home

-
    - {{#each @model as |person|}} -
  • - {{link-to person.name 'item' person id=person.id}} -
  • - {{/each}} -
- ` - ); + expectDeprecation(() => { + this.addTemplate( + 'index', + ` +

Home

+
    + {{#each @model as |person|}} +
  • + {{link-to person.name 'item' person id=person.id}} +
  • + {{/each}} +
+ ` + ); + }, /Invoking the `` component with positional arguments is deprecated/); this.addTemplate( 'item', `

Item

{{@model.name}}

- {{#link-to 'index' id='home-link'}}Home{{/link-to}} + {{#link-to route='index' id='home-link'}}Home{{/link-to}} ` ); @@ -1807,18 +1823,20 @@ moduleFor( assert.equal(normalizeUrl(this.$('li a#erik').attr('href')), '/item/erik'); } - [`@test The non-block form {{link-to}} performs property lookup`](assert) { + [`@test [DEPRECATED] The non-block form {{link-to}} performs property lookup`](assert) { this.router.map(function () { this.route('about'); }); - this.addTemplate( - 'index', - ` - {{link-to 'string' 'index' id='string-link'}} - {{link-to this.path this.foo id='path-link'}} - ` - ); + expectDeprecation(() => { + this.addTemplate( + 'index', + ` + {{link-to 'string' 'index' id='string-link'}} + {{link-to this.path this.foo id='path-link'}} + ` + ); + }, /Invoking the `` component with positional arguments is deprecated/); this.add( 'controller:index', @@ -1842,8 +1860,10 @@ moduleFor( }); } - [`@test The non-block form {{link-to}} protects against XSS`](assert) { - this.addTemplate('application', `{{link-to this.display 'index' id='link'}}`); + [`@test [DEPRECATED] The non-block form {{link-to}} protects against XSS`](assert) { + expectDeprecation(() => { + this.addTemplate('application', `{{link-to this.display 'index' id='link'}}`); + }, /Invoking the `` component with positional arguments is deprecated/); this.add( 'controller:application', @@ -1873,7 +1893,7 @@ moduleFor( this.route('post', { path: 'post/:post_id' }); }); - this.addTemplate('application', `{{#link-to 'post'}}Post{{/link-to}}`); + this.addTemplate('application', `{{#link-to route='post'}}Post{{/link-to}}`); return assert.rejectsAssertion( this.visit('/'), @@ -1891,10 +1911,10 @@ moduleFor( this.addTemplate( 'application', ` - {{#link-to 'index' id='home-link'}}Home{{/link-to}} - {{#link-to 'post' this.defaultPost id='default-post-link'}}Default Post{{/link-to}} + {{#link-to route='index' id='home-link'}}Home{{/link-to}} + {{#link-to route='post' model=this.defaultPost id='default-post-link'}}Default Post{{/link-to}} {{#if this.currentPost}} - {{#link-to 'post' this.currentPost id='current-post-link'}}Current Post{{/link-to}} + {{#link-to route='post' model=this.currentPost id='current-post-link'}}Current Post{{/link-to}} {{/if}} ` ); @@ -1939,8 +1959,8 @@ moduleFor( this.addTemplate( 'application', ` - {{link-to 'OMG' 'things' 'omg' id='omg-link'}} - {{link-to 'LOL' 'things' 'lol' id='lol-link'}} + {{#link-to route='things' model='omg' id='omg-link'}}OMG{{/link-to}} + {{#link-to route='things' model='lol' id='lol-link'}}LOL{{/link-to}} ` ); @@ -1968,7 +1988,7 @@ moduleFor( }) ); - this.addTemplate('index', `{{#link-to 'index' id='the-link'}}Index{{/link-to}}`); + this.addTemplate('index', `{{#link-to route='index' id='the-link'}}Index{{/link-to}}`); return this.visit('/').then(() => { assert.equal(this.$('#the-link').attr('href'), '/', 'link has right href'); @@ -1988,7 +2008,7 @@ moduleFor( this.addTemplate( 'index', - `{{#link-to 'index' (query-params) id='the-link'}}Index{{/link-to}}` + `{{#link-to route='index' query=(hash) id='the-link'}}Index{{/link-to}}` ); return this.visit('/').then(() => { @@ -2012,7 +2032,7 @@ moduleFor( this.addTemplate( 'application', - `{{#link-to (query-params foo='456' bar='NAW') id='the-link'}}Index{{/link-to}}` + `{{#link-to query=(hash foo='456' bar='NAW') id='the-link'}}Index{{/link-to}}` ); return this.visit('/') @@ -2034,7 +2054,7 @@ moduleFor( }); } - [`@test Block-less {{link-to}} with only query-params updates when route changes`](assert) { + [`@test [DEPRECATED] Block-less {{link-to}} with only query-params updates when route changes`](assert) { this.router.map(function () { this.route('about'); }); @@ -2048,10 +2068,12 @@ moduleFor( }) ); - this.addTemplate( - 'application', - `{{link-to "Index" (query-params foo='456' bar='NAW') id='the-link'}}` - ); + expectDeprecation(() => { + this.addTemplate( + 'application', + `{{link-to "Index" (query-params foo='456' bar='NAW') id='the-link'}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); return this.visit('/') .then(() => { @@ -2088,7 +2110,10 @@ moduleFor( }) ); - this.addTemplate('index', `{{link-to 'Post' 'post' (hash id="someId" user=@model.user)}}`); + this.addTemplate( + 'index', + `{{#link-to route='post' model=(hash id="someId" user=@model.user)}}Post{{/link-to}}` + ); this.addTemplate('post', 'Post: {{@model.user.name}}'); return this.visit('/') @@ -2106,7 +2131,7 @@ moduleFor( }); } - [`@test The {{link-to}} component can use dynamic params`](assert) { + async [`@test [DEPRECATED] The {{link-to}} component can use dynamic params`](assert) { this.router.map(function () { this.route('foo', { path: 'foo/:some/:thing' }); this.route('bar', { path: 'bar/:some/:thing/:else' }); @@ -2130,18 +2155,24 @@ moduleFor( ` ); - return this.visit('/').then(() => { - let link = this.$('#dynamic-link'); + await expectDeprecationAsync( + () => this.visit('/'), + /Invoking the `` component with positional arguments is deprecated/ + ); - assert.equal(link.attr('href'), '/foo/one/two'); + let link = this.$('#dynamic-link'); - let controller = this.applicationInstance.lookup('controller:index'); + assert.equal(link.attr('href'), '/foo/one/two'); + + let controller = this.applicationInstance.lookup('controller:index'); + + expectDeprecation(() => { runTask(() => { controller.set('dynamicLinkParams', ['bar', 'one', 'two', 'three']); }); + }, /Invoking the `` component with positional arguments is deprecated/); - assert.equal(link.attr('href'), '/bar/one/two/three'); - }); + assert.equal(link.attr('href'), '/bar/one/two/three'); } [`@test GJ: {{link-to}} to a parent root model hook which performs a 'transitionTo' has correct active class #13256`]( @@ -2165,8 +2196,10 @@ moduleFor( }, }) ); - - this.addTemplate('application', `{{link-to 'Parent' 'parent' id='parent-link'}}`); + this.addTemplate( + 'application', + `{{#link-to route='parent' id='parent-link'}}Parent{{/link-to}}` + ); return this.visit('/') .then(() => { @@ -2197,10 +2230,10 @@ moduleFor( this.addTemplate( 'index', ` - {{#link-to this.destinationRoute this.routeContext loadingClass='i-am-loading' id='context-link'}} + {{#link-to route=this.destinationRoute model=this.routeContext loadingClass='i-am-loading' id='context-link'}} string {{/link-to}} - {{#link-to this.secondRoute loadingClass=this.loadingClass id='static-link'}} + {{#link-to route=this.secondRoute loadingClass=this.loadingClass id='static-link'}} string {{/link-to}} ` diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/transitioning-classes-curly-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/transitioning-classes-curly-test.js index a54c5b76137..745e31356a5 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/transitioning-classes-curly-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/transitioning-classes-curly-test.js @@ -62,10 +62,10 @@ moduleFor( 'application', ` {{outlet}} - {{link-to 'Index' 'index' id='index-link'}} - {{link-to 'About' 'about' id='about-link'}} - {{link-to 'Other' 'other' id='other-link'}} - {{link-to 'News' 'news' activeClass=false id='news-link'}} + {{#link-to route='index' id='index-link'}}Index{{/link-to}} + {{#link-to route='about' id='about-link'}}About{{/link-to}} + {{#link-to route='other' id='other-link'}}Other{{/link-to}} + {{#link-to route='news' activeClass=false id='news-link'}}News{{/link-to}} ` ); } @@ -188,14 +188,14 @@ moduleFor( 'application', ` {{outlet}} - {{#link-to 'index' tagName='li'}} - {{link-to 'Index' 'index' id='index-link'}} + {{#link-to route='index' tagName='li'}} + {{#link-to route='index' id='index-link'}}Index{{/link-to}} {{/link-to}} - {{#link-to 'parent-route.about' tagName='li'}} - {{link-to 'About' 'parent-route.about' id='about-link'}} + {{#link-to route='parent-route.about' tagName='li'}} + {{#link-to route='parent-route.about' tagName='li' id='about-link'}}About{{/link-to}} {{/link-to}} - {{#link-to 'parent-route.other' tagName='li'}} - {{link-to 'Other' 'parent-route.other' id='other-link'}} + {{#link-to route='parent-route.other' tagName='li'}} + {{#link-to route='parent-route.other' id='other-link'}}Other{{/link-to}} {{/link-to}} ` ); 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 dce5af89144..5de93bfdbc3 100644 --- a/packages/ember-template-compiler/lib/plugins/transform-link-to.ts +++ b/packages/ember-template-compiler/lib/plugins/transform-link-to.ts @@ -1,4 +1,4 @@ -import { assert } from '@ember/debug'; +import { assert, deprecate } from '@ember/debug'; import { AST, ASTPlugin } from '@glimmer/syntax'; import calculateLocationDisplay from '../system/calculate-location-display'; import { Builders, EmberASTPluginEnvironment } from '../types'; @@ -39,7 +39,8 @@ function transformInlineLinkToIntoBlockForm( function transformPositionalLinkToIntoNamedArguments( env: EmberASTPluginEnvironment, - node: AST.BlockStatement + node: AST.BlockStatement, + hasBlock = true ): AST.BlockStatement { let { builders: b } = env.syntax; let { moduleName } = env.meta; @@ -114,6 +115,9 @@ function transformPositionalLinkToIntoNamedArguments( params.length > 0 ); + let equivalentNamedArgs = []; + let hasQueryParams = false; + // 1. The last argument is possibly the `query` object. let query = params[params.length - 1]; @@ -136,6 +140,8 @@ function transformPositionalLinkToIntoNamedArguments( query.loc ) ); + + hasQueryParams = true; } // 2. If there is a `route`, it is now at index 0. @@ -144,16 +150,53 @@ function transformPositionalLinkToIntoNamedArguments( if (route) { pairs.push(b.pair('route', route, route.loc)); + equivalentNamedArgs.push('`@route`'); } // 3. Any remaining indices (if any) are `models`. if (params.length === 1) { pairs.push(b.pair('model', params[0], params[0].loc)); + equivalentNamedArgs.push('`@model`'); } else if (params.length > 1) { pairs.push( b.pair('models', b.sexpr(b.path('array', node.loc), params, undefined, node.loc), node.loc) ); + equivalentNamedArgs.push('`@models`'); + } + + if (hasQueryParams) { + equivalentNamedArgs.push('`@query`'); + } + + if (equivalentNamedArgs.length > 0) { + let message = 'Invoking the `` component with positional arguments is deprecated.'; + + message += `Please use the equivalent named arguments (${equivalentNamedArgs.join(', ')})`; + + if (hasQueryParams) { + message += ' along with the `hash` helper'; + } + + if (!hasBlock) { + message += " and pass a block for the link's content."; + } + + message += '.'; + + if (node.loc?.source) { + message += ` ${calculateLocationDisplay(moduleName, node.loc)}`; + } + + deprecate(message, false, { + id: 'ember-glimmer.link-to.positional-arguments', + until: '4.0.0', + for: 'ember-source', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-glimmer-link-to-positional-arguments', + since: { + enabled: '3.26.0-beta.1', + }, + }); } return b.block( @@ -188,7 +231,7 @@ export default function transformLinkTo(env: EmberASTPluginEnvironment): ASTPlug MustacheStatement(node: AST.MustacheStatement): AST.Node | void { if (isInlineLinkTo(node)) { let block = transformInlineLinkToIntoBlockForm(env, node); - return transformPositionalLinkToIntoNamedArguments(env, block); + return transformPositionalLinkToIntoNamedArguments(env, block, false); } }, 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 087a72d35f7..01a9d8185a3 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 @@ -5,50 +5,66 @@ 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 route='index'}}foo{{/link-to}}` - ); + ['@test [DEPRECATED] it transforms an inline {{link-to}} into its block form']() { + expectDeprecation(() => { + this.assertTransformed( + `{{link-to 'foo' 'index'}}`, + `{{#link-to route='index'}}foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } - ['@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}}` - ); - - this.assertTransformed( - `{{link-to @foo 'index'}}`, - `{{#link-to route='index'}}{{@foo}}{{/link-to}}` - ); + ['@test [DEPRECATED] bound link title']() { + expectDeprecation(() => { + this.assertTransformed( + `{{link-to foo 'index'}}`, + `{{#link-to route='index'}}{{foo}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{link-to this.foo 'index'}}`, + `{{#link-to route='index'}}{{this.foo}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{link-to foo.bar.baz 'index'}}`, + `{{#link-to route='index'}}{{foo.bar.baz}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{link-to @foo 'index'}}`, + `{{#link-to route='index'}}{{@foo}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } - ['@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}}` - ); + ['@test [DEPRECATED] sexp link title']() { + expectDeprecation(() => { + this.assertTransformed( + `{{link-to (foo) 'index'}}`, + `{{#link-to route='index'}}{{foo}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{link-to (foo bar) 'index'}}`, + `{{#link-to route='index'}}{{foo bar}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{link-to (foo bar baz=bat) 'index'}}`, + `{{#link-to route='index'}}{{foo bar baz=bat}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } } ); @@ -56,50 +72,66 @@ moduleFor( 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 [DEPRECATED] it transforms an inline {{{link-to}}} into its block form']() { + expectDeprecation(() => { + this.assertTransformed( + `{{{link-to 'foo' 'index'}}}`, + `{{#link-to route='index'}}foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } - ['@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}}` - ); - - this.assertTransformed( - `{{{link-to @foo 'index'}}}`, - `{{#link-to route='index'}}{{{@foo}}}{{/link-to}}` - ); + ['@test [DEPRECATED] bound link title']() { + expectDeprecation(() => { + this.assertTransformed( + `{{{link-to foo 'index'}}}`, + `{{#link-to route='index'}}{{{foo}}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{{link-to this.foo 'index'}}}`, + `{{#link-to route='index'}}{{{this.foo}}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{{link-to foo.bar.baz 'index'}}}`, + `{{#link-to route='index'}}{{{foo.bar.baz}}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{{link-to @foo 'index'}}}`, + `{{#link-to route='index'}}{{{@foo}}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } - ['@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}}` - ); + ['@test [DEPRECATED] sexp link title']() { + expectDeprecation(() => { + this.assertTransformed( + `{{{link-to (foo) 'index'}}}`, + `{{#link-to route='index'}}{{{foo}}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{{link-to (foo bar) 'index'}}}`, + `{{#link-to route='index'}}{{{foo bar}}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{{link-to (foo bar baz=bat) 'index'}}}`, + `{{#link-to route='index'}}{{{foo bar baz=bat}}}{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } } ); @@ -107,7 +139,7 @@ moduleFor( moduleFor( 'ember-template-compiler: transforming positional arguments into named arguments', class extends TransformTestCase { - ['@test no arguments']() { + ['@test [DEPRECATED] 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\)/ @@ -127,7 +159,7 @@ moduleFor( compile('{{#link-to query=foo}}zomg{{/link-to}}', { moduleName: '-top-level' }); } - ['@test mixing positional and named arguments']() { + ['@test [DEPRECATED] 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\)/ @@ -154,164 +186,224 @@ moduleFor( ); } - ['@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 [DEPRECATED] route only']() { + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo'}}Foo{{/link-to}}`, + `{{#link-to route='foo'}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to foo}}Foo{{/link-to}}`, + `{{#link-to route=foo}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to this.foo}}Foo{{/link-to}}`, + `{{#link-to route=this.foo}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to foo.bar.baz}}Foo{{/link-to}}`, + `{{#link-to route=foo.bar.baz}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to @foo}}Foo{{/link-to}}`, + `{{#link-to route=@foo}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to @foo}}Foo{{/link-to}}`, + `{{#link-to route=@foo}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to (foo)}}Foo{{/link-to}}`, + `{{#link-to route=(foo)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to (foo bar)}}Foo{{/link-to}}`, + `{{#link-to route=(foo bar)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to (foo bar baz=bat)}}Foo{{/link-to}}`, + `{{#link-to route=(foo bar baz=bat)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } - ['@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 [DEPRECATED] single model']() { + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' 'bar'}}Foo{{/link-to}}`, + `{{#link-to route='foo' model='bar'}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' bar}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=bar}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' this.bar}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=this.bar}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' bar.baz.bat}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=bar.baz.bat}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' @bar}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=@bar}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' (bar)}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=(bar)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' (bar baz)}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=(bar baz)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' (bar baz bat=wat)}}Foo{{/link-to}}`, + `{{#link-to route='foo' model=(bar baz bat=wat)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } - ['@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 [DEPRECATED] multi models']() { + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' 'bar' 'baz' 'bat'}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array 'bar' 'baz' 'bat')}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' bar baz bat}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array bar baz bat)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + 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}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + 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}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' @bar @baz @bat}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array @bar @baz @bat)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to 'foo' (bar) (baz) (bat)}}Foo{{/link-to}}`, + `{{#link-to route='foo' models=(array (bar) (baz) (bat))}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + 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}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + 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}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } - ['@test query params']() { + ['@test [DEPRECATED] query params']() { QUnit.dump.maxDepth = 100; - 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}}` - ); + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to (query-params)}}Foo{{/link-to}}`, + `{{#link-to query=(-hash)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + this.assertTransformed( + `{{#link-to (query-params foo='bar' baz=bat)}}Foo{{/link-to}}`, + `{{#link-to query=(-hash foo='bar' baz=bat)}}Foo{{/link-to}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + 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}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + 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}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); + + expectDeprecation(() => { + 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}}` + ); + }, /Invoking the `` component with positional arguments is deprecated/); } } ); diff --git a/packages/ember-testing/tests/acceptance_test.js b/packages/ember-testing/tests/acceptance_test.js index 682beae36bd..6ed764cb5e0 100644 --- a/packages/ember-testing/tests/acceptance_test.js +++ b/packages/ember-testing/tests/acceptance_test.js @@ -63,7 +63,7 @@ if (!jQueryDisabled) {
` diff --git a/packages/ember/tests/routing/query_params_test.js b/packages/ember/tests/routing/query_params_test.js index a5cf01d99a1..342d4141d6f 100644 --- a/packages/ember/tests/routing/query_params_test.js +++ b/packages/ember/tests/routing/query_params_test.js @@ -972,7 +972,7 @@ moduleFor( this.addTemplate('parent', '{{outlet}}'); this.addTemplate( 'parent.child', - "{{link-to 'Parent' 'parent' (query-params foo='change') id='parent-link'}}" + "{{#link-to route='parent' query=(hash foo='change') id='parent-link'}}Parent{{/link-to}}" ); this.router.map(function () { @@ -1116,7 +1116,7 @@ moduleFor( this.addTemplate( 'application', - "{{link-to 'A' 'abc.def' (query-params foo='123') id='one'}}{{link-to 'B' 'abc.def.zoo' (query-params foo='123' bar='456') id='two'}}{{outlet}}" + "{{#link-to route='abc.def' query=(hash foo='123') id='one'}}A{{/link-to}}{{#link-to route='abc.def.zoo' query=(hash foo='123' bar='456') id='two'}}B{{/link-to}}{{outlet}}" ); this.setSingleQPController('abc.def', 'foo', 'lol'); @@ -1447,7 +1447,7 @@ moduleFor( this.addTemplate( 'home', - "{{link-to 'Home' 'home' (query-params foo=this.nullValue) id='null-link'}}{{link-to 'Home' 'home' (query-params foo=this.undefinedValue) id='undefined-link'}}" + "{{#link-to route='home' query=(hash foo=this.nullValue) id='null-link'}}Home{{/link-to}}{{#link-to route='home' query=(hash foo=this.undefinedValue) id='undefined-link'}}Home{{/link-to}}" ); this.router.map(function () { @@ -1504,7 +1504,7 @@ moduleFor( this.addTemplate( 'application', - "{{link-to 'Foo' 'foo' id='foo-link'}}{{link-to 'Bar' 'bar' id='bar-no-qp-link'}}{{link-to 'Bar' 'bar' (query-params raytiley='isthebest') id='bar-link'}}{{outlet}}" + "{{#link-to route='foo' id='foo-link'}}Foo{{/link-to}}{{#link-to route='bar' id='bar-no-qp-link'}}Bar{{/link-to}}{{#link-to route='bar' query=(hash raytiley='isthebest') id='bar-link'}}Bar{{/link-to}}{{outlet}}" ); this.router.map(function () { @@ -1553,7 +1553,7 @@ moduleFor( this.addTemplate( 'application', - "{{link-to 'Example' 'example' (query-params foo=undefined) id='the-link'}}" + "{{#link-to route='example' query=(hash foo=undefined) id='the-link'}}Example{{/link-to}}" ); this.setSingleQPController('example', 'foo', undefined, { diff --git a/packages/ember/tests/routing/query_params_test/model_dependent_state_with_query_params_test.js b/packages/ember/tests/routing/query_params_test/model_dependent_state_with_query_params_test.js index 37f7c12c8f6..590a86de02c 100644 --- a/packages/ember/tests/routing/query_params_test/model_dependent_state_with_query_params_test.js +++ b/packages/ember/tests/routing/query_params_test/model_dependent_state_with_query_params_test.js @@ -104,7 +104,7 @@ class ModelDependentQPTestCase extends QueryParamTestCase { this.addTemplate( 'application', - `{{#each articles as |a|}} {{link-to 'Article' '${articleLookup}' a.id id=a.id}} {{/each}}` + `{{#each articles as |a|}} {{#link-to route='${articleLookup}' model=a.id id=a.id}}Article{{/link-to}} {{/each}}` ); await this.boot(); @@ -246,7 +246,7 @@ class ModelDependentQPTestCase extends QueryParamTestCase { this.addTemplate( 'about', - `{{link-to 'A' '${commentsLookup}' 'a-1' id='one'}} {{link-to 'B' '${commentsLookup}' 'a-2' id='two'}}` + `{{#link-to route='${commentsLookup}' model='a-1' id='one'}}A{{/link-to}} {{#link-to route='${commentsLookup}' model='a-2' id='two'}}B{{/link-to}}` ); await this.visitApplication(); @@ -334,7 +334,7 @@ moduleFor( this.addTemplate( 'application', - "{{#each this.articles as |a|}} 1{{link-to 'Article' 'article' a id=a.id}} {{/each}} {{outlet}}" + "{{#each this.articles as |a|}} 1{{#link-to route='article' model=a id=a.id}}Article{{/link-to}} {{/each}} {{outlet}}" ); } @@ -440,7 +440,7 @@ moduleFor( this.addTemplate( 'application', - "{{#each this.articles as |a|}} {{link-to 'Article' 'site.article' a id=a.id}} {{/each}} {{outlet}}" + "{{#each this.articles as |a|}} {{#link-to route='site.article' model=a id=a.id}}Article{{/link-to}} {{/each}} {{outlet}}" ); } @@ -591,7 +591,7 @@ moduleFor( this.addTemplate( 'application', - "{{#each this.allSitesAllArticles as |a|}} {{#link-to 'site.article' a.site_id a.article_id id=a.id}}Article [{{a.site_id}}] [{{a.article_id}}]{{/link-to}} {{/each}} {{outlet}}" + "{{#each this.allSitesAllArticles as |a|}} {{#link-to route='site.article' models=(array a.site_id a.article_id) id=a.id}}Article [{{a.site_id}}] [{{a.article_id}}]{{/link-to}} {{/each}} {{outlet}}" ); } diff --git a/packages/ember/tests/routing/query_params_test/query_param_async_get_handler_test.js b/packages/ember/tests/routing/query_params_test/query_param_async_get_handler_test.js index 629cb4777b5..71fb2e84a6f 100644 --- a/packages/ember/tests/routing/query_params_test/query_param_async_get_handler_test.js +++ b/packages/ember/tests/routing/query_params_test/query_param_async_get_handler_test.js @@ -72,8 +72,8 @@ moduleFor( this.addTemplate( 'application', ` - {{link-to 'Post' 'post' 1337 (query-params foo='bar') class='post-link is-1337'}} - {{link-to 'Post' 'post' 7331 (query-params foo='boo') class='post-link is-7331'}} + {{#link-to route='post' model=1337 query=(hash foo='bar') class='post-link is-1337'}}Post{{/link-to}} + {{#link-to route='post' model=7331 query=(hash foo='boo') class='post-link is-7331'}}Post{{/link-to}} {{outlet}} ` ); @@ -296,7 +296,7 @@ moduleFor( this.addTemplate( 'application', - "{{link-to 'Example' 'example' (query-params foo=undefined) id='the-link'}}" + "{{#link-to route='example' query=(hash foo=undefined) id='the-link'}}Example{{/link-to}}" ); this.setSingleQPController('example', 'foo', undefined, { diff --git a/packages/ember/tests/routing/query_params_test/query_params_paramless_link_to_test.js b/packages/ember/tests/routing/query_params_test/query_params_paramless_link_to_test.js index 9ce6e77452a..b68be96ff5f 100644 --- a/packages/ember/tests/routing/query_params_test/query_params_paramless_link_to_test.js +++ b/packages/ember/tests/routing/query_params_test/query_params_paramless_link_to_test.js @@ -7,7 +7,7 @@ moduleFor( testParamlessLinks(assert, routeName) { assert.expect(1); - this.addTemplate(routeName, "{{link-to 'index' 'index' id='index-link'}}"); + this.addTemplate(routeName, `index`); this.add( `controller:${routeName}`, diff --git a/packages/ember/tests/routing/query_params_test/shared_state_test.js b/packages/ember/tests/routing/query_params_test/shared_state_test.js index 0b09bc31310..b731581d645 100644 --- a/packages/ember/tests/routing/query_params_test/shared_state_test.js +++ b/packages/ember/tests/routing/query_params_test/shared_state_test.js @@ -39,12 +39,15 @@ moduleFor( }) ); - this.addTemplate('application', `{{link-to 'Home' 'home' }}
{{outlet}}
`); + this.addTemplate( + 'application', + `Home
{{outlet}}
` + ); this.addTemplate( 'home', - `{{link-to 'Dashboard' 'dashboard' }}{{input type="checkbox" id='filters-checkbox' checked=(mut this.filters.shared) }}` + `Dashboard{{input type="checkbox" id='filters-checkbox' checked=(mut this.filters.shared) }}` ); - this.addTemplate('dashboard', `{{link-to 'Home' 'home' }}`); + this.addTemplate('dashboard', `Home`); } visitApplication() { return this.visit('/');