Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DEPRECATE] Deprecate Ember.Binding #13424

Merged
merged 1 commit into from
May 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ moduleFor('Binding integration tests', class extends RenderingTest {
template: 'two way: {{twoWayTest}}, string: {{stringTest}}, object: {{twoWayObjectTest}}, string object: {{stringObjectTest}}'
});

this.render('{{foo-bar direction=direction displacement=displacement}}', {
direction: 'down',
displacement: {
distance: 10
}
});
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
' using an `alias` computed property instead.';

expectDeprecation(() => {
this.render('{{foo-bar direction=direction displacement=displacement}}', {
direction: 'down',
displacement: {
distance: 10
}
});
}, deprecationMessage);

this.assertText('two way: down, string: down, object: 10, string object: 10');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,10 @@ moduleFor('Helpers test: {{unbound}}', class extends RenderingTest {

this.render(`{{unbound (repeat foo count=bar)}} {{repeat foo count=bar}} {{unbound (repeat foo count=2)}} {{repeat foo count=4}}`, {
foo: 'X',
numRepeatsBinding: 'bar',
bar: 5
});


this.assertText('XXXXX XXXXX XX XXXX');

this.runTask(() => this.rerender());
Expand Down
37 changes: 34 additions & 3 deletions packages/ember-metal/lib/binding.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Logger from 'ember-console';
import { context, ENV } from 'ember-environment';
import run from 'ember-metal/run_loop';
import { assert } from 'ember-metal/debug';
import { assert, deprecate } from 'ember-metal/debug';
import { get } from 'ember-metal/property_get';
import { trySet } from 'ember-metal/property_set';
import { guidFor } from 'ember-metal/utils';
Expand Down Expand Up @@ -43,6 +43,7 @@ function Binding(toPath, fromPath) {
/**
@class Binding
@namespace Ember
@deprecated See http://emberjs.com/deprecations/v2.x#toc_ember-binding
@public
*/

Expand Down Expand Up @@ -144,13 +145,13 @@ Binding.prototype = {
connect(obj) {
assert('Must pass a valid object to Ember.Binding.connect()', !!obj);

let fromObj, fromPath;
let fromObj, fromPath, possibleGlobal;

// If the binding's "from" path could be interpreted as a global, verify
// whether the path refers to a global or not by consulting `Ember.lookup`.
if (isGlobalPath(this._from)) {
let name = getFirstKey(this._from);
let possibleGlobal = context.lookup[name];
possibleGlobal = context.lookup[name];

if (possibleGlobal) {
fromObj = possibleGlobal;
Expand All @@ -175,6 +176,10 @@ Binding.prototype = {

addListener(obj, 'willDestroy', this, 'disconnect');

fireDeprecations(possibleGlobal,
this._oneWay,
(!possibleGlobal && !this._oneWay));

this._readyToSync = true;
this._fromObj = fromObj;
this._fromPath = fromPath;
Expand Down Expand Up @@ -281,6 +286,32 @@ Binding.prototype = {

};

function fireDeprecations(deprecateGlobal, deprecateOneWay, deprecateAlias) {
let deprecateGlobalMessage = '`Ember.Binding` is deprecated. Since you' +
' are binding to a global consider using a service instead.';
let deprecateOneWayMessage = '`Ember.Binding` is deprecated. Since you' +
' are using a `oneWay` binding consider using a `readOnly` computed' +
' property instead.';
let deprecateAliasMessage = '`Ember.Binding` is deprecated. Consider' +
' using an `alias` computed property instead.';

deprecate(deprecateGlobalMessage, !deprecateGlobal, {
id: 'ember-metal.binding',
until: '3.0.0',
url: 'http://emberjs.com/deprecations/v2.x#toc_ember-binding'
});
deprecate(deprecateOneWayMessage, !deprecateOneWay, {
id: 'ember-metal.binding',
until: '3.0.0',
url: 'http://emberjs.com/deprecations/v2.x#toc_ember-binding'
});
deprecate(deprecateAliasMessage, !deprecateAlias, {
id: 'ember-metal.binding',
until: '3.0.0',
url: 'http://emberjs.com/deprecations/v2.x#toc_ember-binding'
});
}

function mixinProperties(to, from) {
for (var key in from) {
if (from.hasOwnProperty(key)) {
Expand Down
54 changes: 45 additions & 9 deletions packages/ember-metal/tests/binding/connect_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,26 @@ testBoth('Connecting a binding between two properties', function(get, set) {
// a.bar -> a.foo
var binding = new Binding('foo', 'bar');

performTest(binding, a, a, get, set);
let deprecationMessage = '`Ember.Binding` is deprecated. Consider using an' +
' `alias` computed property instead.';

expectDeprecation(() => {
performTest(binding, a, a, get, set);
}, deprecationMessage);
});

testBoth('Connecting a oneWay binding raises a deprecation',
function(get, set) {
var a = { foo: 'FOO', bar: 'BAR' };

// a.bar -> a.foo
var binding = new Binding('foo', 'bar').oneWay();

let deprecationMessage = '`Ember.Binding` is deprecated. Since you' +
' are using a `oneWay` binding consider using a `readOnly` computed' +
' property instead.';

expectDeprecation(() => { binding.connect(a); }, deprecationMessage);
});

testBoth('Connecting a binding between two objects', function(get, set) {
Expand All @@ -64,7 +83,12 @@ testBoth('Connecting a binding between two objects', function(get, set) {
// b.bar -> a.foo
var binding = new Binding('foo', 'b.bar');

performTest(binding, a, b, get, set);
let deprecationMessage = '`Ember.Binding` is deprecated. Consider using an' +
' `alias` computed property instead.';

expectDeprecation(() => {
performTest(binding, a, b, get, set);
}, deprecationMessage);
});

testBoth('Connecting a binding to path', function(get, set) {
Expand All @@ -78,7 +102,12 @@ testBoth('Connecting a binding to path', function(get, set) {
// globalB.b.bar -> a.foo
var binding = new Binding('foo', 'GlobalB.b.bar');

performTest(binding, a, b, get, set);
let deprecationMessage = '`Ember.Binding` is deprecated. Since you' +
' are binding to a global consider using a service instead.';

expectDeprecation(() => {
performTest(binding, a, b, get, set);
}, deprecationMessage);

// make sure modifications update
b = { bar: 'BIFF' };
Expand All @@ -97,11 +126,15 @@ testBoth('Calling connect more than once', function(get, set) {
// b.bar -> a.foo
var binding = new Binding('foo', 'b.bar');

performTest(binding, a, b, get, set, function () {
binding.connect(a);
let deprecationMessage = '`Ember.Binding` is deprecated. Consider using an' +
' `alias` computed property instead.';

binding.connect(a);
});
expectDeprecation(() => {
performTest(binding, a, b, get, set, function () {
binding.connect(a);
binding.connect(a);
});
}, deprecationMessage);
});

QUnit.test('inherited bindings should sync on create', function() {
Expand All @@ -111,10 +144,13 @@ QUnit.test('inherited bindings should sync on create', function() {
bind(this, 'foo', 'bar.baz');
};

a = new A();
let deprecationMessage = '`Ember.Binding` is deprecated. Consider using an' +
' `alias` computed property instead.';

expectDeprecation(() => { a = new A(); }, deprecationMessage);

set(a, 'bar', { baz: 'BAZ' });
});

equal(get(a, 'foo'), 'BAZ', 'should have synced binding on new obj');
});

45 changes: 39 additions & 6 deletions packages/ember-metal/tests/binding/sync_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ testBoth('bindings should not sync twice in a single run loop', function(get, se
b = {
a: a
};
bind(b, 'foo', 'a.foo');

let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
' using an `alias` computed property instead.';

expectDeprecation(() => {
bind(b, 'foo', 'a.foo');
}, deprecationMessage);
});

// reset after initial binding synchronization
Expand Down Expand Up @@ -68,7 +74,13 @@ testBoth('bindings should not infinite loop if computed properties return object
b = {
a: a
};
bind(b, 'foo', 'a.foo');

let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
' using an `alias` computed property instead.';

expectDeprecation(() => {
bind(b, 'foo', 'a.foo');
}, deprecationMessage);
});

deepEqual(get(b, 'foo'), ['foo', 'bar'], 'the binding should sync');
Expand All @@ -86,12 +98,21 @@ testBoth('bindings should do the right thing when observers trigger bindings in
b = {
a: a
};
bind(b, 'foo', 'a.foo');

let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
' using an `alias` computed property instead.';

expectDeprecation(() => {
bind(b, 'foo', 'a.foo');
}, deprecationMessage);

c = {
a: a
};
bind(c, 'foo', 'a.foo');

expectDeprecation(() => {
bind(c, 'foo', 'a.foo');
}, deprecationMessage);
});

addObserver(b, 'foo', function() {
Expand All @@ -116,7 +137,13 @@ testBoth('bindings should not try to sync destroyed objects', function(get, set)
b = {
a: a
};
bind(b, 'foo', 'a.foo');

let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
' using an `alias` computed property instead.';

expectDeprecation(() => {
bind(b, 'foo', 'a.foo');
}, deprecationMessage);
});

run(function() {
Expand All @@ -133,7 +160,13 @@ testBoth('bindings should not try to sync destroyed objects', function(get, set)
b = {
a: a
};
bind(b, 'foo', 'a.foo');

let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
' using an `alias` computed property instead.';

expectDeprecation(() => {
bind(b, 'foo', 'a.foo');
}, deprecationMessage);
});

run(function() {
Expand Down
14 changes: 12 additions & 2 deletions packages/ember-runtime/tests/ext/mixin_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ QUnit.test('Defining a property ending in Binding should setup binding when appl
var obj = { bar: { baz: 'BIFF' } };

run(function() {
MyMixin.apply(obj);
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
' using an `alias` computed property instead.';

expectDeprecation(() => {
MyMixin.apply(obj);
}, deprecationMessage);
});

ok(get(obj, 'fooBinding') instanceof Binding, 'should be a binding object');
Expand All @@ -33,7 +38,12 @@ QUnit.test('Defining a property ending in Binding should apply to prototype chil
obj = { bar: { baz: 'BIFF' } };

run(function() {
MyMixin.apply(obj);
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
' using an `alias` computed property instead.';

expectDeprecation(() => {
MyMixin.apply(obj);
}, deprecationMessage);
});


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,9 +528,14 @@ QUnit.test('nested dependent keys should propagate after they update', function(
})
});

bindObj = ObservableObject.extend({
priceBinding: 'DepObj.price'
}).create();
let deprecationMessage = '`Ember.Binding` is deprecated. Since you' +
' are binding to a global consider using a service instead.';

expectDeprecation(() => {
bindObj = ObservableObject.extend({
priceBinding: 'DepObj.price'
}).create();
}, deprecationMessage);
});

equal(bindObj.get('price'), 5, 'precond - binding propagates');
Expand Down Expand Up @@ -835,7 +840,7 @@ QUnit.test('removing an observer inside of an observer shouldn’t cause any pro



QUnit.module('Bind function ', {
QUnit.module('Bind function', {
setup() {
objectA = ObservableObject.create({
name: 'Sproutcore',
Expand Down Expand Up @@ -865,7 +870,12 @@ QUnit.module('Bind function ', {
QUnit.test('should bind property with method parameter as undefined', function() {
// creating binding
run(function() {
objectA.bind('name', 'Namespace.objectB.normal', undefined);
let deprecationMessage = '`Ember.Binding` is deprecated. Since you' +
' are binding to a global consider using a service instead.';

expectDeprecation(() => {
objectA.bind('name', 'Namespace.objectB.normal', undefined);
}, deprecationMessage);
});

// now make a change to see if the binding triggers.
Expand Down
Loading