From abdc4428e2fa6b5a4f0d665eef2234bf300dfadb Mon Sep 17 00:00:00 2001 From: Matthew Beale Date: Wed, 12 Aug 2015 23:13:38 -0400 Subject: [PATCH] [CLEANUP beta] Assert on view and controller keywords (cherry picked from commit 8f72bf23c26260ff2233d64588c3be82edcd9f12) --- .../tests/compat/controller_keyword_test.js | 60 ++++++++---- .../tests/compat/view_helper_test.js | 60 +++++++++--- .../tests/compat/view_keyword_test.js | 17 ++-- .../tests/helpers/collection_test.js | 1 + .../ember-htmlbars/tests/helpers/each_test.js | 14 +++ packages/ember-template-compiler/lib/main.js | 9 +- .../assert-no-view-and-controller-paths.js | 78 +++++++++++++++ ...iew-helper.js => assert-no-view-helper.js} | 20 ++-- .../deprecate-view-and-controller-paths.js | 73 -------------- packages/ember-views/lib/main.js | 4 +- packages/ember-views/lib/views/select.js | 25 ----- .../tests/views/collection_test.js | 7 +- .../tests/views/container_view_test.js | 65 +++++++------ .../ember-views/tests/views/select_test.js | 20 +--- .../tests/views/view/child_views_test.js | 8 ++ .../tests/views/view/nearest_of_type_test.js | 94 ++++++++++--------- packages/ember-views/tests/views/view_test.js | 5 +- tests/index.html | 4 +- 18 files changed, 306 insertions(+), 258 deletions(-) create mode 100644 packages/ember-template-compiler/lib/plugins/assert-no-view-and-controller-paths.js rename packages/ember-template-compiler/lib/plugins/{deprecate-view-helper.js => assert-no-view-helper.js} (51%) delete mode 100644 packages/ember-template-compiler/lib/plugins/deprecate-view-and-controller-paths.js diff --git a/packages/ember-htmlbars/tests/compat/controller_keyword_test.js b/packages/ember-htmlbars/tests/compat/controller_keyword_test.js index ebac7a945e3..c422ee61fd7 100644 --- a/packages/ember-htmlbars/tests/compat/controller_keyword_test.js +++ b/packages/ember-htmlbars/tests/compat/controller_keyword_test.js @@ -1,17 +1,44 @@ +import Ember from 'ember-metal/core'; import EmberComponent from 'ember-views/views/component'; import { runAppend, runDestroy } from 'ember-runtime/tests/utils'; import compile from 'ember-template-compiler/system/compile'; import { registerAstPlugin, removeAstPlugin } from 'ember-htmlbars/tests/utils'; import TransformEachIntoCollection from 'ember-template-compiler/plugins/transform-each-into-collection'; -import DeprecateViewAndControllerPaths from 'ember-template-compiler/plugins/deprecate-view-and-controller-paths'; +import AssertNoViewAndControllerPaths from 'ember-template-compiler/plugins/assert-no-view-and-controller-paths'; let component; QUnit.module('ember-htmlbars: compat - controller keyword (use as a path)', { + setup() { + Ember.ENV._ENABLE_LEGACY_CONTROLLER_SUPPORT = false; + registerAstPlugin(AssertNoViewAndControllerPaths); + + component = null; + }, + teardown() { + runDestroy(component); + + removeAstPlugin(AssertNoViewAndControllerPaths); + Ember.ENV._ENABLE_LEGACY_CONTROLLER_SUPPORT = true; + } +}); + +QUnit.test('reading the controller keyword fails assertion', function() { + var text = 'a-prop'; + expectAssertion(function() { + component = EmberComponent.extend({ + prop: text, + layout: compile('{{controller.prop}}') + }).create(); + + runAppend(component); + }, /Using `{{controller}}` or any path based on it .*/); +}); + +QUnit.module('ember-htmlbars: compat - controller keyword (use as a path) [LEGACY]', { setup() { registerAstPlugin(TransformEachIntoCollection); - registerAstPlugin(DeprecateViewAndControllerPaths); component = null; }, @@ -19,54 +46,55 @@ QUnit.module('ember-htmlbars: compat - controller keyword (use as a path)', { runDestroy(component); removeAstPlugin(TransformEachIntoCollection); - removeAstPlugin(DeprecateViewAndControllerPaths); } }); -QUnit.test('reading the controller keyword is deprecated [DEPRECATED]', function() { +QUnit.test('reading the controller keyword works [LEGACY]', function() { var text = 'a-prop'; - expectDeprecation(function() { + ignoreAssertion(function() { component = EmberComponent.extend({ prop: text, layout: compile('{{controller.prop}}') }).create(); + }, /Using `{{controller}}` or any path based on it .*/); - runAppend(component); - }, /Using `{{controller}}` or any path based on it .* has been deprecated./); + runAppend(component); equal(component.$().text(), text, 'controller keyword is read'); }); -QUnit.test('reading the controller keyword for hash is deprecated [DEPRECATED]', function() { - expectDeprecation(function() { +QUnit.test('reading the controller keyword for hash [LEGACY]', function() { + ignoreAssertion(function() { component = EmberComponent.extend({ prop: true, layout: compile('{{if true \'hiho\' option=controller.prop}}') }).create(); runAppend(component); - }, /Using `{{controller}}` or any path based on it .* has been deprecated./); + }, /Using `{{controller}}` or any path based on it .*/); + ok(true, 'access keyword'); }); -QUnit.test('reading the controller keyword for param is deprecated [DEPRECATED]', function() { +QUnit.test('reading the controller keyword for param [LEGACY]', function() { var text = 'a-prop'; - expectDeprecation(function() { + ignoreAssertion(function() { component = EmberComponent.extend({ prop: true, layout: compile(`{{if controller.prop '${text}'}}`) }).create(); runAppend(component); - }, /Using `{{controller}}` or any path based on it .* has been deprecated./); + }, /Using `{{controller}}` or any path based on it .*/); equal(component.$().text(), text, 'controller keyword is read'); }); -QUnit.test('reading the controller keyword for param with block is deprecated [DEPRECATED]', function() { - expectDeprecation(function() { +QUnit.test('reading the controller keyword for param with block fails assertion [LEGACY]', function() { + ignoreAssertion(function() { component = EmberComponent.extend({ prop: true, layout: compile(`{{#each controller as |things|}}{{/each}}`) }).create(); runAppend(component); - }, /Using `{{controller}}` or any path based on it .* has been deprecated./); + }, /Using `{{controller}}` or any path based on it .*/); + ok(true, 'access keyword'); }); diff --git a/packages/ember-htmlbars/tests/compat/view_helper_test.js b/packages/ember-htmlbars/tests/compat/view_helper_test.js index ee37731ab42..cb4fe1222f8 100644 --- a/packages/ember-htmlbars/tests/compat/view_helper_test.js +++ b/packages/ember-htmlbars/tests/compat/view_helper_test.js @@ -1,3 +1,4 @@ +import Ember from 'ember-metal/core'; import EmberComponent from 'ember-views/views/component'; import EmberView from 'ember-views/views/view'; import EmberSelectView from 'ember-views/views/select'; @@ -6,7 +7,7 @@ import compile from 'ember-template-compiler/system/compile'; import Registry from 'container/registry'; import { registerAstPlugin, removeAstPlugin } from 'ember-htmlbars/tests/utils'; -import DeprecateViewHelper from 'ember-template-compiler/plugins/deprecate-view-helper'; +import AssertNoViewHelper from 'ember-template-compiler/plugins/assert-no-view-helper'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; import viewKeyword from 'ember-htmlbars/keywords/view'; @@ -15,7 +16,8 @@ let component, registry, container, originalViewKeyword; QUnit.module('ember-htmlbars: compat - view helper', { setup() { - registerAstPlugin(DeprecateViewHelper); + Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT = false; + registerAstPlugin(AssertNoViewHelper); originalViewKeyword = registerKeyword('view', viewKeyword); @@ -25,61 +27,93 @@ QUnit.module('ember-htmlbars: compat - view helper', { teardown() { runDestroy(component); runDestroy(container); - removeAstPlugin(DeprecateViewHelper); + removeAstPlugin(AssertNoViewHelper); + Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT = true; registry = container = component = null; resetKeyword('view', originalViewKeyword); } }); -QUnit.test('using the view helper with a string (inline form) is deprecated [DEPRECATED]', function(assert) { +QUnit.test('using the view helper fails assertion', function(assert) { const ViewClass = EmberView.extend({ template: compile('fooView') }); registry.register('view:foo', ViewClass); - expectDeprecation(function() { + expectAssertion(function() { component = EmberComponent.extend({ layout: compile('{{view \'foo\'}}'), container }).create(); runAppend(component); - }, /Using the `{{view "string"}}` helper is deprecated/); + }, /Using the `{{view "string"}}` helper/); +}); + +QUnit.module('ember-htmlbars: compat - view helper [LEGACY]', { + setup() { + originalViewKeyword = registerKeyword('view', viewKeyword); + + registry = new Registry(); + container = registry.container(); + }, + teardown() { + runDestroy(component); + runDestroy(container); + registry = container = component = null; + + resetKeyword('view', originalViewKeyword); + } +}); + +QUnit.test('using the view helper with a string (inline form) fails assertion [LEGACY]', function(assert) { + const ViewClass = EmberView.extend({ + template: compile('fooView') + }); + registry.register('view:foo', ViewClass); + + ignoreAssertion(function() { + component = EmberComponent.extend({ + layout: compile('{{view \'foo\'}}'), + container + }).create(); + + runAppend(component); + }); assert.equal(component.$().text(), 'fooView', 'view helper is still rendered'); }); -QUnit.test('using the view helper with a string (block form) is deprecated [DEPRECATED]', function(assert) { +QUnit.test('using the view helper with a string (block form) fails assertion [LEGACY]', function(assert) { const ViewClass = EmberView.extend({ template: compile('Foo says: {{yield}}') }); registry.register('view:foo', ViewClass); - expectDeprecation(function() { + ignoreAssertion(function() { component = EmberComponent.extend({ layout: compile('{{#view \'foo\'}}I am foo{{/view}}'), container }).create(); runAppend(component); - }, /Using the `{{view "string"}}` helper is deprecated/); + }); assert.equal(component.$().text(), 'Foo says: I am foo', 'view helper is still rendered'); }); -QUnit.test('using the view helper with string "select" has its own deprecation message [DEPRECATED]', function(assert) { +QUnit.test('using the view helper with string "select" fails assertion [LEGACY]', function(assert) { registry.register('view:select', EmberSelectView); - expectDeprecation(function() { + ignoreAssertion(function() { component = EmberComponent.extend({ layout: compile('{{view \'select\'}}'), container }).create(); runAppend(component); - }, /Using `{{view "select"}}` is deprecated/); + }); assert.ok(!!component.$('select').length, 'still renders select'); }); - diff --git a/packages/ember-htmlbars/tests/compat/view_keyword_test.js b/packages/ember-htmlbars/tests/compat/view_keyword_test.js index 8e745706043..dba86aaca3d 100644 --- a/packages/ember-htmlbars/tests/compat/view_keyword_test.js +++ b/packages/ember-htmlbars/tests/compat/view_keyword_test.js @@ -1,34 +1,35 @@ +import Ember from 'ember-metal/core'; import EmberComponent from 'ember-views/views/component'; import { runAppend, runDestroy } from 'ember-runtime/tests/utils'; import compile from 'ember-template-compiler/system/compile'; import { registerAstPlugin, removeAstPlugin } from 'ember-htmlbars/tests/utils'; -import DeprecateViewAndControllerPaths from 'ember-template-compiler/plugins/deprecate-view-and-controller-paths'; +import AssertNoViewAndControllerPaths from 'ember-template-compiler/plugins/assert-no-view-and-controller-paths'; let component; QUnit.module('ember-htmlbars: compat - view keyword (use as a path)', { setup() { - registerAstPlugin(DeprecateViewAndControllerPaths); + Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT = false; + registerAstPlugin(AssertNoViewAndControllerPaths); component = null; }, teardown() { runDestroy(component); - removeAstPlugin(DeprecateViewAndControllerPaths); + removeAstPlugin(AssertNoViewAndControllerPaths); + Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT = true; } }); -QUnit.test('reading the view keyword is deprecated [DEPRECATED]', function() { +QUnit.test('reading the view keyword fails assertion', function() { var text = 'a-prop'; - expectDeprecation(function() { + expectAssertion(function() { component = EmberComponent.extend({ prop: text, layout: compile('{{view.prop}}') }).create(); runAppend(component); - }, /Using `{{view}}` or any path based on it .* has been deprecated./); - - equal(component.$().text(), text, 'view keyword is read'); + }, /Using `{{view}}` or any path based on it .*/); }); diff --git a/packages/ember-htmlbars/tests/helpers/collection_test.js b/packages/ember-htmlbars/tests/helpers/collection_test.js index ed4a40cad40..1b41d1c9960 100644 --- a/packages/ember-htmlbars/tests/helpers/collection_test.js +++ b/packages/ember-htmlbars/tests/helpers/collection_test.js @@ -186,6 +186,7 @@ QUnit.test('empty views should be removed when content is added to the collectio }); view = EmberView.create({ + _viewRegistry: {}, listView: ListView, listController: listController, template: compile('{{#collection view.listView content=view.listController tagName="table"}} {{view.content.title}} {{/collection}}') diff --git a/packages/ember-htmlbars/tests/helpers/each_test.js b/packages/ember-htmlbars/tests/helpers/each_test.js index b3e8577cf40..4bacac1e617 100644 --- a/packages/ember-htmlbars/tests/helpers/each_test.js +++ b/packages/ember-htmlbars/tests/helpers/each_test.js @@ -250,6 +250,7 @@ QUnit.test('it works inside a table element', function() { }); QUnit.test('it supports {{itemView=}}', function() { + runDestroy(view); var itemView = EmberView.extend({ template: compile('itemView:{{name}}') }); @@ -270,6 +271,7 @@ QUnit.test('it supports {{itemView=}}', function() { }); QUnit.test('it defers all normalization of itemView names to the resolver', function() { + runDestroy(view); var itemView = EmberView.extend({ template: compile('itemView:{{name}}') }); @@ -289,6 +291,7 @@ QUnit.test('it defers all normalization of itemView names to the resolver', func }); QUnit.test('it supports {{itemViewClass=}} via container', function() { + runDestroy(view); expectDeprecation(() => { view = EmberView.create({ container: container, @@ -303,6 +306,7 @@ QUnit.test('it supports {{itemViewClass=}} via container', function() { }); QUnit.test('it supports {{itemViewClass=}} with each view tagName (DEPRECATED)', function() { + runDestroy(view); expectDeprecation(() => { view = EmberView.create({ template: compile('{{each view.people itemViewClass="my-view" tagName="ul"}}'), @@ -318,6 +322,7 @@ QUnit.test('it supports {{itemViewClass=}} with each view tagName (DEPRECATED)', }); QUnit.test('it supports {{itemViewClass=}} with tagName in itemViewClass (DEPRECATED)', function() { + runDestroy(view); registry.register('view:li-view', EmberView.extend({ tagName: 'li' })); @@ -338,6 +343,7 @@ QUnit.test('it supports {{itemViewClass=}} with tagName in itemViewClass (DEPREC }); QUnit.test('it supports {{itemViewClass=}} with {{else}} block (DEPRECATED)', function() { + runDestroy(view); expectDeprecation(() => { view = EmberView.create({ template: compile(` @@ -357,6 +363,7 @@ QUnit.test('it supports {{itemViewClass=}} with {{else}} block (DEPRECATED)', fu }); QUnit.test('it supports {{emptyView=}}', function() { + runDestroy(view); var emptyView = EmberView.extend({ template: compile('emptyView:sad panda') }); @@ -377,6 +384,7 @@ QUnit.test('it supports {{emptyView=}}', function() { }); QUnit.test('it defers all normalization of emptyView names to the resolver', function() { + runDestroy(view); var emptyView = EmberView.extend({ template: compile('emptyView:sad panda') }); @@ -397,6 +405,7 @@ QUnit.test('it defers all normalization of emptyView names to the resolver', fun }); QUnit.test('it supports {{emptyViewClass=}} via container', function() { + runDestroy(view); expectDeprecation(() => { view = EmberView.create({ container: container, @@ -411,6 +420,7 @@ QUnit.test('it supports {{emptyViewClass=}} via container', function() { }); QUnit.test('it supports {{emptyViewClass=}} with tagName (DEPRECATED)', function() { + runDestroy(view); expectDeprecation(() => { view = EmberView.create({ template: compile('{{each view.people emptyViewClass="my-empty-view" tagName="b"}}'), @@ -426,6 +436,7 @@ QUnit.test('it supports {{emptyViewClass=}} with tagName (DEPRECATED)', function }); QUnit.test('it supports {{emptyViewClass=}} with in format', function() { + runDestroy(view); expectDeprecation(() => { view = EmberView.create({ container: container, @@ -440,6 +451,7 @@ QUnit.test('it supports {{emptyViewClass=}} with in format', function() { }); QUnit.test('it uses {{else}} when replacing model with an empty array', function() { + runDestroy(view); view = EmberView.create({ template: compile('{{#each view.items as |item|}}{{item}}{{else}}Nothing{{/each}}'), items: A(['one', 'two']) @@ -457,6 +469,7 @@ QUnit.test('it uses {{else}} when replacing model with an empty array', function }); QUnit.test('it uses {{else}} when removing all items in an array', function() { + runDestroy(view); var items = A(['one', 'two']); view = EmberView.create({ template: compile('{{#each view.items as |item|}}{{item}}{{else}}Nothing{{/each}}'), @@ -476,6 +489,7 @@ QUnit.test('it uses {{else}} when removing all items in an array', function() { }); QUnit.test('it can move to and from {{else}} properly when the backing array gains and looses items (#11140)', function() { + runDestroy(view); var items = A(['one', 'two']); view = EmberView.create({ template: compile('{{#each view.items as |item|}}{{item}}{{else}}Nothing{{/each}}'), diff --git a/packages/ember-template-compiler/lib/main.js b/packages/ember-template-compiler/lib/main.js index 3a4adf66e43..4fe5b4072b6 100644 --- a/packages/ember-template-compiler/lib/main.js +++ b/packages/ember-template-compiler/lib/main.js @@ -12,8 +12,8 @@ import TransformComponentCurlyToReadonly from 'ember-template-compiler/plugins/t import TransformAngleBracketComponents from 'ember-template-compiler/plugins/transform-angle-bracket-components'; import TransformInputOnToOnEvent from 'ember-template-compiler/plugins/transform-input-on-to-onEvent'; import TransformEachIntoCollection from 'ember-template-compiler/plugins/transform-each-into-collection'; -import DeprecateViewAndControllerPaths from 'ember-template-compiler/plugins/deprecate-view-and-controller-paths'; -import DeprecateViewHelper from 'ember-template-compiler/plugins/deprecate-view-helper'; +import AssertNoViewAndControllerPaths from 'ember-template-compiler/plugins/assert-no-view-and-controller-paths'; +import AssertNoViewHelper from 'ember-template-compiler/plugins/assert-no-view-helper'; // used for adding Ember.Handlebars.compile for backwards compat import 'ember-template-compiler/compat'; @@ -28,8 +28,9 @@ registerPlugin('ast', TransformInputOnToOnEvent); if (_Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT) { registerPlugin('ast', TransformEachIntoCollection); - registerPlugin('ast', DeprecateViewAndControllerPaths); - registerPlugin('ast', DeprecateViewHelper); +} else { + registerPlugin('ast', AssertNoViewAndControllerPaths); + registerPlugin('ast', AssertNoViewHelper); } export { diff --git a/packages/ember-template-compiler/lib/plugins/assert-no-view-and-controller-paths.js b/packages/ember-template-compiler/lib/plugins/assert-no-view-and-controller-paths.js new file mode 100644 index 00000000000..d552659da5c --- /dev/null +++ b/packages/ember-template-compiler/lib/plugins/assert-no-view-and-controller-paths.js @@ -0,0 +1,78 @@ +import Ember from 'ember-metal/core'; +import calculateLocationDisplay from 'ember-template-compiler/system/calculate-location-display'; + +function AssertNoViewAndControllerPaths(options) { + // set later within HTMLBars to the syntax package + this.syntax = null; + this.options = options || {}; +} + +/** + @private + @method transform + @param {AST} ast The AST to be transformed. +*/ +AssertNoViewAndControllerPaths.prototype.transform = function AssertNoViewAndControllerPaths_transform(ast) { + var walker = new this.syntax.Walker(); + var moduleName = this.options && this.options.moduleName; + + walker.visit(ast, function(node) { + if (!validate(node)) { return; } + + assertPath(moduleName, node, node.path); + assertPaths(moduleName, node, node.params); + assertHash(moduleName, node, node.hash); + }); + + return ast; +}; + +function assertHash(moduleName, node, hash) { + if (!hash || !hash.pairs) { + return; + } + var i, l, pair, paths; + for (i = 0, l = hash.pairs.length;i < l;i++) { + pair = hash.pairs[i]; + paths = pair.value.params; + assertPaths(moduleName, pair, paths); + } +} + +function assertPaths(moduleName, node, paths) { + if (!paths) { + return; + } + var i, l, path; + for (i = 0, l = paths.length;i < l;i++) { + path = paths[i]; + assertPath(moduleName, node, path); + } +} + +function assertPath(moduleName, node, path) { + Ember.assert( + `Using \`{{${path && path.type === 'PathExpression' && path.parts[0]}}}\` or any path based on it ${calculateLocationDisplay(moduleName, node.loc)}has been removed in Ember 2.0`, + function assertPath_test() { + let noAssertion = true; + + const viewKeyword = path && path.type === 'PathExpression' && path.parts && path.parts[0]; + if (viewKeyword === 'view') { + noAssertion = Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT; + } else if (viewKeyword === 'controller') { + noAssertion = Ember.ENV._ENABLE_LEGACY_CONTROLLER_SUPPORT; + } + + return noAssertion; + }, { + id: (path.parts && path.parts[0] === 'view' ? 'view.keyword.view' : 'view.keyword.controller'), + until: '2.0.0' + } + ); +} + +function validate(node) { + return node.type === 'MustacheStatement' || node.type === 'BlockStatement'; +} + +export default AssertNoViewAndControllerPaths; diff --git a/packages/ember-template-compiler/lib/plugins/deprecate-view-helper.js b/packages/ember-template-compiler/lib/plugins/assert-no-view-helper.js similarity index 51% rename from packages/ember-template-compiler/lib/plugins/deprecate-view-helper.js rename to packages/ember-template-compiler/lib/plugins/assert-no-view-helper.js index cc78c722aef..074cd967087 100644 --- a/packages/ember-template-compiler/lib/plugins/deprecate-view-helper.js +++ b/packages/ember-template-compiler/lib/plugins/assert-no-view-helper.js @@ -1,7 +1,7 @@ import Ember from 'ember-metal/core'; import calculateLocationDisplay from 'ember-template-compiler/system/calculate-location-display'; -function DeprecateViewHelper(options) { +function AssertNoViewHelper(options) { // set later within HTMLBars to the syntax package this.syntax = null; this.options = options || {}; @@ -12,7 +12,7 @@ function DeprecateViewHelper(options) { @method transform @param {AST} ast The AST to be transformed. */ -DeprecateViewHelper.prototype.transform = function DeprecateViewHelper_transform(ast) { +AssertNoViewHelper.prototype.transform = function AssertNoViewHelper_transform(ast) { if (!!Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT) { return ast; } @@ -22,31 +22,27 @@ DeprecateViewHelper.prototype.transform = function DeprecateViewHelper_transform walker.visit(ast, function(node) { if (!validate(node)) { return; } - deprecateHelper(moduleName, node); + assertHelper(moduleName, node); }); return ast; }; -function deprecateHelper(moduleName, node) { +function assertHelper(moduleName, node) { const paramValue = node.params.length && node.params[0].value; if (!paramValue) { return; - } else if (paramValue === 'select') { - deprecateSelect(moduleName, node); } else { - Ember.deprecate(`Using the \`{{view "string"}}\` helper is deprecated. ${calculateLocationDisplay(moduleName, node.loc)}`, false, { url: 'http://emberjs.com/deprecations/v1.x#toc_ember-view', id: 'view.helper' }); + Ember.assert(`Using the \`{{view "string"}}\` helper is removed in 2.0. ${calculateLocationDisplay(moduleName, node.loc)}`, + Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT, + { id: 'view.helper', until: '2.0.0' }); } } -function deprecateSelect(moduleName, node) { - Ember.deprecate(`Using \`{{view "select"}}\` is deprecated. ${calculateLocationDisplay(moduleName, node.loc)}`, false, { url: 'http://emberjs.com/deprecations/v1.x#toc_ember-select', id: 'view.helper.select' }); -} - function validate(node) { return (node.type === 'MustacheStatement' || node.type === 'BlockStatement') && (node.path.parts[0] === 'view'); } -export default DeprecateViewHelper; +export default AssertNoViewHelper; diff --git a/packages/ember-template-compiler/lib/plugins/deprecate-view-and-controller-paths.js b/packages/ember-template-compiler/lib/plugins/deprecate-view-and-controller-paths.js deleted file mode 100644 index 6848dda5b5a..00000000000 --- a/packages/ember-template-compiler/lib/plugins/deprecate-view-and-controller-paths.js +++ /dev/null @@ -1,73 +0,0 @@ -import Ember from 'ember-metal/core'; -import calculateLocationDisplay from 'ember-template-compiler/system/calculate-location-display'; - -function DeprecateViewAndControllerPaths(options) { - // set later within HTMLBars to the syntax package - this.syntax = null; - this.options = options || {}; -} - -/** - @private - @method transform - @param {AST} ast The AST to be transformed. -*/ -DeprecateViewAndControllerPaths.prototype.transform = function DeprecateViewAndControllerPaths_transform(ast) { - var walker = new this.syntax.Walker(); - var moduleName = this.options && this.options.moduleName; - - walker.visit(ast, function(node) { - if (!validate(node)) { return; } - - deprecatePath(moduleName, node, node.path); - deprecatePaths(moduleName, node, node.params); - deprecateHash(moduleName, node, node.hash); - - }); - - return ast; -}; - -function deprecateHash(moduleName, node, hash) { - if (!hash || !hash.pairs) { - return; - } - var i, l, pair, paths; - for (i=0, l=hash.pairs.length;i iterable.indexOf(item)); } @@ -699,7 +675,6 @@ function indexesOf(iterable, elements) { export default Select; export { Select, - DeprecatedSelect, SelectOption, SelectOptgroup }; diff --git a/packages/ember-views/tests/views/collection_test.js b/packages/ember-views/tests/views/collection_test.js index 4f757bd144f..cdee17e14db 100644 --- a/packages/ember-views/tests/views/collection_test.js +++ b/packages/ember-views/tests/views/collection_test.js @@ -673,7 +673,7 @@ QUnit.test('Collection with style attribute supports changing content', function }); -QUnit.module('DeprecatedCollectionView'); +QUnit.module('DeprecatedCollectionView [LEGACY]'); QUnit.test('calling reopen on DeprecatedCollectionView delegates to CollectionView', function() { expect(2); @@ -682,9 +682,8 @@ QUnit.test('calling reopen on DeprecatedCollectionView delegates to CollectionVi CollectionView.reopen = function(arg) { ok(arg === obj); }; - expectDeprecation(() => { - DeprecatedCollectionView.reopen(obj); - }, /Ember.CollectionView is deprecated./); + expectNoDeprecation(); + DeprecatedCollectionView.reopen(obj); CollectionView.reopen = originalReopen; }); diff --git a/packages/ember-views/tests/views/container_view_test.js b/packages/ember-views/tests/views/container_view_test.js index 9609502d01b..49e6fe32bb7 100644 --- a/packages/ember-views/tests/views/container_view_test.js +++ b/packages/ember-views/tests/views/container_view_test.js @@ -457,46 +457,46 @@ QUnit.test('if a ContainerView starts with a currentView and then a different cu equal(trim(container.$().text()), 'This is the tertiary view.', 'should render its child'); }); -QUnit.test('should be able to modify childViews many times during an run loop', function () { - - container = ContainerView.create(); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - var one = View.create({ - template: compile('one') - }); - - var two = View.create({ - template: compile('two') - }); - - var three = View.create({ - template: compile('three') - }); +var child, count; +QUnit.module('Ember.ContainerView - modify childViews', { + setup() { + originalViewKeyword = registerKeyword('view', viewKeyword); + registry = new Registry(); + container = ContainerView.create({ + _viewRegistry: { } + }); - run(function() { - // initial order - container.pushObjects([three, one, two]); - // sort - container.removeObject(three); - container.pushObject(three); - }); + run(function() { + container.appendTo('#qunit-fixture'); + }); - // Remove whitespace added by IE 8 - equal(trim(container.$().text()), 'onetwothree'); + count = 0; + child = View.create({ + template: function () { + count++; + return 'child'; + } + }); + }, + teardown() { + run(function() { + container.destroy(); + if (view) { view.destroy(); } + if (child) { child.destroy(); } + if (otherContainer) { otherContainer.destroy(); } + }); + } }); - QUnit.test('should be able to modify childViews then rerender the ContainerView in same run loop', function () { - container = ContainerView.create(); + container = ContainerView.create({ + }); run(function() { container.appendTo('#qunit-fixture'); }); var child = View.create({ + _viewRegistry: { }, template: compile('child') }); @@ -814,9 +814,8 @@ QUnit.test('calling reopen on DeprecatedContainerView delegates to ContainerView ContainerView.reopen = function(arg) { ok(arg === obj); }; - expectDeprecation(() => { - DeprecatedContainerView.reopen(obj); - }, /Ember.ContainerView is deprecated./); + expectNoDeprecation(); + DeprecatedContainerView.reopen(obj); ContainerView.reopen = originalReopen; }); diff --git a/packages/ember-views/tests/views/select_test.js b/packages/ember-views/tests/views/select_test.js index 2a6e963b9e9..a6d2f6cd010 100644 --- a/packages/ember-views/tests/views/select_test.js +++ b/packages/ember-views/tests/views/select_test.js @@ -1,7 +1,7 @@ import Ember from 'ember-metal/core'; import run from 'ember-metal/run_loop'; import EmberObject from 'ember-runtime/system/object'; -import EmberSelect, { DeprecatedSelect } from 'ember-views/views/select'; +import EmberSelect from 'ember-views/views/select'; import jQuery from 'ember-views/system/jquery'; import EventDispatcher from 'ember-views/system/event_dispatcher'; import SafeString from 'htmlbars-util/safe-string'; @@ -14,7 +14,7 @@ var trim = jQuery.trim; var dispatcher, select; var originalViewKeyword; -QUnit.module('Ember.Select', { +QUnit.module('Ember.Select [LEGACY]', { setup() { originalViewKeyword = registerKeyword('view', viewKeyword); dispatcher = EventDispatcher.create(); @@ -805,19 +805,3 @@ QUnit.test('should be able to set the current selection by value', function() { equal(select.get('value'), 'ebryn'); equal(select.get('selection'), ebryn); }); - -QUnit.module('DeprecatedSelect'); - -QUnit.test('calling reopen on DeprecatedSelect delegates to Select', function() { - expect(2); - var originalReopen = EmberSelect.reopen; - var obj = {}; - - EmberSelect.reopen = function(arg) { ok(arg === obj); }; - - expectDeprecation(() => { - DeprecatedSelect.reopen(obj); - }, /Ember.Select is deprecated./); - - EmberSelect.reopen = originalReopen; -}); diff --git a/packages/ember-views/tests/views/view/child_views_test.js b/packages/ember-views/tests/views/view/child_views_test.js index 03aeaa25be5..ef24996ac6b 100644 --- a/packages/ember-views/tests/views/view/child_views_test.js +++ b/packages/ember-views/tests/views/view/child_views_test.js @@ -109,6 +109,10 @@ QUnit.test('should remove childViews inside {{if}} on destroy', function() { run(outerView, 'set', 'value', false); equal(outerView.get('childViews.length'), 0, 'expected no views to be leaked'); + + run(function() { + outerView.destroy(); + }); }); QUnit.test('should remove childViews inside {{each}} on destroy', function() { @@ -157,4 +161,8 @@ QUnit.test('should remove childViews inside {{each}} on destroy', function() { run(outerView, 'set', 'value', false); equal(outerView.get('childViews.length'), 0, 'expected no views to be leaked'); + + run(function() { + outerView.destroy(); + }); }); diff --git a/packages/ember-views/tests/views/view/nearest_of_type_test.js b/packages/ember-views/tests/views/view/nearest_of_type_test.js index 49e965e2fb5..9298b256d13 100644 --- a/packages/ember-views/tests/views/view/nearest_of_type_test.js +++ b/packages/ember-views/tests/views/view/nearest_of_type_test.js @@ -4,14 +4,23 @@ import View from 'ember-views/views/view'; import compile from 'ember-template-compiler/system/compile'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; +import { registerAstPlugin, removeAstPlugin } from 'ember-htmlbars/tests/utils'; +import AssertNoViewAndControllerPaths from 'ember-template-compiler/plugins/assert-no-view-and-controller-paths'; import viewKeyword from 'ember-htmlbars/keywords/view'; var parentView, view; var originalViewKeyword; +var Mixin, Parent; + QUnit.module('View#nearest*', { setup() { + removeAstPlugin(AssertNoViewAndControllerPaths); originalViewKeyword = registerKeyword('view', viewKeyword); + Mixin = EmberMixin.create({}); + Parent = View.extend(Mixin, { + template: compile(`{{view}}`) + }); }, teardown() { run(function() { @@ -19,67 +28,60 @@ QUnit.module('View#nearest*', { if (view) { view.destroy(); } }); resetKeyword('view', originalViewKeyword); + registerAstPlugin(AssertNoViewAndControllerPaths); } }); -(function() { - var Mixin = EmberMixin.create({}); - var Parent = View.extend(Mixin, { - template: compile(`{{view}}`) - }); - - QUnit.test('nearestOfType should find the closest view by view class', function() { - var child; +QUnit.test('nearestOfType should find the closest view by view class', function() { + var child; - run(function() { - parentView = Parent.create(); - parentView.appendTo('#qunit-fixture'); - }); - - child = parentView.get('childViews')[0]; - equal(child.nearestOfType(Parent), parentView, 'finds closest view in the hierarchy by class'); + run(function() { + parentView = Parent.create(); + parentView.appendTo('#qunit-fixture'); }); - QUnit.test('nearestOfType should find the closest view by mixin', function() { - var child; + child = parentView.get('childViews')[0]; + equal(child.nearestOfType(Parent), parentView, 'finds closest view in the hierarchy by class'); +}); - run(function() { - parentView = Parent.create(); - parentView.appendTo('#qunit-fixture'); - }); +QUnit.test('nearestOfType should find the closest view by mixin', function() { + var child; - child = parentView.get('childViews')[0]; - equal(child.nearestOfType(Mixin), parentView, 'finds closest view in the hierarchy by class'); + run(function() { + parentView = Parent.create(); + parentView.appendTo('#qunit-fixture'); }); - QUnit.test('nearestWithProperty should search immediate parent', function() { - var childView; - - view = View.create({ - myProp: true, - template: compile('{{view}}') - }); + child = parentView.get('childViews')[0]; + equal(child.nearestOfType(Mixin), parentView, 'finds closest view in the hierarchy by class'); +}); - run(function() { - view.appendTo('#qunit-fixture'); - }); +QUnit.test('nearestWithProperty should search immediate parent', function() { + var childView; - childView = view.get('childViews')[0]; - equal(childView.nearestWithProperty('myProp'), view); + view = View.create({ + myProp: true, + template: compile('{{view}}') + }); + run(function() { + view.appendTo('#qunit-fixture'); }); - QUnit.test('nearestChildOf should be deprecated', function() { - var child; + childView = view.get('childViews')[0]; + equal(childView.nearestWithProperty('myProp'), view); +}); - run(function() { - parentView = Parent.create(); - parentView.appendTo('#qunit-fixture'); - }); +QUnit.test('nearestChildOf should be deprecated', function() { + var child; - child = parentView.get('childViews')[0]; - expectDeprecation(function() { - child.nearestChildOf(Parent); - }, 'nearestChildOf has been deprecated.'); + run(function() { + parentView = Parent.create(); + parentView.appendTo('#qunit-fixture'); }); -}()); + + child = parentView.get('childViews')[0]; + expectDeprecation(function() { + child.nearestChildOf(Parent); + }, 'nearestChildOf has been deprecated.'); +}); diff --git a/packages/ember-views/tests/views/view_test.js b/packages/ember-views/tests/views/view_test.js index 19245eb61dd..51c4b72635e 100644 --- a/packages/ember-views/tests/views/view_test.js +++ b/packages/ember-views/tests/views/view_test.js @@ -169,9 +169,8 @@ QUnit.test('calling reopen on DeprecatedView delegates to View', function() { EmberView.reopen = function(arg) { ok(arg === obj); }; - expectDeprecation(() => { - DeprecatedView.reopen(obj); - }, /Ember.View is deprecated./); + expectNoDeprecation(); + DeprecatedView.reopen(obj); EmberView.reopen = originalReopen; }); diff --git a/tests/index.html b/tests/index.html index ca718ab752c..323449e42e2 100644 --- a/tests/index.html +++ b/tests/index.html @@ -35,7 +35,9 @@ window.Ember = { testing: true }; - window.ENV = window.ENV || {}; + window.ENV = window.ENV || { + _ENABLE_LEGACY_VIEW_SUPPORT: true + }; window.printTestCounts = function() { var passing = $("li[id^='qunit-'].pass").length;