Skip to content

Commit

Permalink
Merge pull request #12018 from rwjblue/deprecate-block-crap
Browse files Browse the repository at this point in the history
[BUGFIX release] Deprecate `{{unbound` block and multi param usage.
  • Loading branch information
mixonic committed Aug 8, 2015
2 parents 034f823 + 23fd2ae commit 95cec06
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/ember-htmlbars/lib/keywords/unbound.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default function unbound(morph, env, scope, originalParams, hash, templat
} else if (template === null) {
env.hooks.inline(morph, env, scope, valueStream.key, params, hash);
} else {
// deprecated via AST transform
env.hooks.block(morph, env, scope, valueStream.key, params, hash, template, inverse);
}

Expand Down
12 changes: 9 additions & 3 deletions packages/ember-htmlbars/tests/helpers/if_unless_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ QUnit.test("The `if` helper tests for `isTruthy` if available", function() {
QUnit.test("The `if` helper does not error on undefined", function() {
view = EmberView.create({
undefinedValue: undefined,
template: compile('{{#if view.undefinedValue}}Yep{{/if}}{{#unbound if view.undefinedValue}}Yep{{/unbound}}')
template: compile('{{#if view.undefinedValue}}Yep{{/if}}')
});

runAppend(view);
Expand All @@ -78,12 +78,12 @@ QUnit.test("The `if` helper does not error on undefined", function() {
QUnit.test("The `unless` helper does not error on undefined", function() {
view = EmberView.create({
undefinedValue: undefined,
template: compile('{{#unless view.undefinedValue}}YepBound{{/unless}}{{#unbound unless view.undefinedValue}}YepUnbound{{/unbound}}')
template: compile('{{#unless view.undefinedValue}}YepBound{{/unless}}')
});

runAppend(view);

equal(view.$().text(), 'YepBoundYepUnbound');
equal(view.$().text(), 'YepBound');
});

QUnit.test("The `if` helper does not print the contents for an object proxy without content", function() {
Expand Down Expand Up @@ -194,6 +194,8 @@ QUnit.test("The `if` helper updates when the value changes", function() {
});

QUnit.test("The `unbound if` helper does not update when the value changes", function() {
expectDeprecation(/Using the {{unbound}} helper with a block .* is deprecated and will be removed/);

view = EmberView.create({
conditional: true,
template: compile('{{#unbound if view.conditional}}Yep{{/unbound}}')
Expand All @@ -220,6 +222,8 @@ QUnit.test("The `unless` helper updates when the value changes", function() {
});

QUnit.test("The `unbound if` helper does not update when the value changes", function() {
expectDeprecation(/Using the {{unbound}} helper with a block .* is deprecated and will be removed/);

view = EmberView.create({
conditional: false,
template: compile('{{#unbound unless view.conditional}}Nope{{/unbound}}')
Expand All @@ -233,6 +237,8 @@ QUnit.test("The `unbound if` helper does not update when the value changes", fun
});

QUnit.test("The `unbound if` helper should work when its inverse is not present", function() {
expectDeprecation(/Using the {{unbound}} helper with a block .* is deprecated and will be removed/);

view = EmberView.create({
conditional: false,
template: compile('{{#unbound if view.conditional}}Yep{{/unbound}}')
Expand Down
2 changes: 2 additions & 0 deletions packages/ember-htmlbars/tests/helpers/unbound_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ QUnit.test('it should re-render if the parent view rerenders', function() {
});

QUnit.test('it should throw the helper missing error if multiple properties are provided', function() {
expectDeprecation(/Using the {{unbound}} helper with multiple params .* is deprecated and will be removed/);

expectAssertion(function() {
runAppend(EmberView.create({
template: compile('{{unbound foo bar}}'),
Expand Down
2 changes: 2 additions & 0 deletions packages/ember-template-compiler/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import TransformInputOnToOnEvent from "ember-template-compiler/plugins/transform
import DeprecateViewAndControllerPaths from "ember-template-compiler/plugins/deprecate-view-and-controller-paths";
import DeprecateViewHelper from "ember-template-compiler/plugins/deprecate-view-helper";
import DeprecateWithController from 'ember-template-compiler/plugins/deprecate-with-controller';
import DeprecateBlockStuff from 'ember-template-compiler/plugins/deprecate-unbound-block-and-multi-param';

// used for adding Ember.Handlebars.compile for backwards compat
import "ember-template-compiler/compat";
Expand All @@ -38,6 +39,7 @@ registerPlugin('ast', TransformInputOnToOnEvent);
registerPlugin('ast', DeprecateViewAndControllerPaths);
registerPlugin('ast', DeprecateViewHelper);
registerPlugin('ast', DeprecateWithController);
registerPlugin('ast', DeprecateBlockStuff);

export {
_Ember,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Ember from 'ember-metal/core';
import calculateLocationDisplay from 'ember-template-compiler/system/calculate-location-display';

function DeprecateUnboundBlockAndMultiParam(options) {
// set later within HTMLBars to the syntax package
this.syntax = null;
this.options = options || {};
}

DeprecateUnboundBlockAndMultiParam.prototype.transform = function(ast) {
const pluginContext = this;
const walker = new pluginContext.syntax.Walker();
const moduleName = pluginContext.options.moduleName;

walker.visit(ast, function(node) {

if (pluginContext.isBlockUsage(node)) {
let moduleInfo = calculateLocationDisplay(moduleName, node.loc);

Ember.deprecate(
`Using the {{unbound}} helper with a block ${moduleInfo}is deprecated and will be removed in 2.0.0.`,
false,
{ id: 'ember-template-compiler.unbound-block', until: '2.0.0' }
);
} else if (pluginContext.hasMultipleParams(node)) {
let moduleInfo = calculateLocationDisplay(moduleName, node.loc);

Ember.deprecate(
`Using the {{unbound}} helper with multiple params ${moduleInfo}is deprecated and will be removed in 2.0.0. Please refactor to nested helper usage.`,
false,
{ id: 'ember-template-compiler.unbound-multiple-params', until: '2.0.0' }
);
}
});

return ast;
};

DeprecateUnboundBlockAndMultiParam.prototype.isBlockUsage = function(node) {
return node.type === 'BlockStatement' &&
node.path.original === 'unbound';
};

DeprecateUnboundBlockAndMultiParam.prototype.hasMultipleParams = function(node) {
return (node.type === 'BlockStatement' || node.type === 'MustacheStatement') &&
node.path.original === 'unbound' &&
node.params.length > 1;
};

export default DeprecateUnboundBlockAndMultiParam;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { compile } from 'ember-template-compiler';

QUnit.module('ember-template-compiler: deprecate-unbound-block-and-multi-params');

QUnit.test('Using `{{unbound}}` with a block issues a deprecation', function() {
expect(1);

expectDeprecation(function() {
compile('{{#unbound "foo"}}{{/unbound}}', {
moduleName: 'foo/bar/baz'
});
}, `Using the {{unbound}} helper with a block ('foo/bar/baz' @ L1:C0) is deprecated and will be removed in 2.0.0.`);
});

QUnit.test('Using `{{unbound}}` with multiple params issues a deprecation', function() {
expect(1);

expectDeprecation(function() {
compile('{{unbound foo bar}}', {
moduleName: 'foo/bar/baz'
});
}, `Using the {{unbound}} helper with multiple params ('foo/bar/baz' @ L1:C0) is deprecated and will be removed in 2.0.0. Please refactor to nested helper usage.`);
});

QUnit.test('Using `{{unbound}}` with a single param is not deprecated', function() {
expect(1);

compile('{{unbound foo}}', {
moduleName: 'foo/bar/baz'
});

ok(true, 'no deprecations or assertions');
});

0 comments on commit 95cec06

Please sign in to comment.