Skip to content

Commit

Permalink
Merge pull request #18993 from chrisrng/deprecate-getwithdefault
Browse files Browse the repository at this point in the history
  • Loading branch information
rwjblue committed May 29, 2020
2 parents c0606a4 + f2d8364 commit 4e8863e
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 78 deletions.
13 changes: 12 additions & 1 deletion packages/@ember/-internals/metal/lib/property_get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@module @ember/object
*/
import { HAS_NATIVE_PROXY, isEmberArray, isProxy, symbol } from '@ember/-internals/utils';
import { assert } from '@ember/debug';
import { assert, deprecate } from '@ember/debug';
import { DEBUG } from '@glimmer/env';
import {
consumeTag,
Expand Down Expand Up @@ -181,12 +181,23 @@ export function _getPath<T extends object>(root: T, path: string | string[]): an
@param {Object} defaultValue The value to return if the property value is undefined
@return {Object} The property value or the defaultValue.
@public
@deprecated
*/
export function getWithDefault<T extends object, K extends Extract<keyof T, string>>(
root: T,
key: K,
defaultValue: T[K]
): T[K] {
deprecate(
'Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined.',
false,
{
id: 'ember-metal.get-with-default',
until: '4.0.0',
url: 'https://deprecations.emberjs.com/v3.x#toc_ember-metal-get-with-default',
}
);

let value = get(root, key);

if (value === undefined) {
Expand Down
120 changes: 63 additions & 57 deletions packages/@ember/-internals/metal/tests/accessors/get_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,35 +207,37 @@ moduleFor(
'getWithDefault',
class extends AbstractTestCase {
['@test should get arbitrary properties on an object'](assert) {
let obj = {
string: 'string',
number: 23,
boolTrue: true,
boolFalse: false,
nullValue: null,
};
expectDeprecation(() => {
let obj = {
string: 'string',
number: 23,
boolTrue: true,
boolFalse: false,
nullValue: null,
};

for (let key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
for (let key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
}
assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key);
}
assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key);
}

obj = {
undef: undefined,
};
obj = {
undef: undefined,
};

assert.equal(
getWithDefault(obj, 'undef', 'default'),
'default',
'explicit undefined retrieves the default'
);
assert.equal(
getWithDefault(obj, 'not-present', 'default'),
'default',
'non-present key retrieves the default'
);
assert.equal(
getWithDefault(obj, 'undef', 'default'),
'default',
'explicit undefined retrieves the default'
);
assert.equal(
getWithDefault(obj, 'not-present', 'default'),
'default',
'non-present key retrieves the default'
);
}, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./);
}

['@test should call unknownProperty if defined and value is undefined'](assert) {
Expand All @@ -253,24 +255,26 @@ moduleFor(
}

['@test if unknownProperty is present, it is called using getFromEmberMetal()/set()'](assert) {
let obj = {
unknownProperty(key) {
if (key === 'foo') {
assert.equal(key, 'foo', 'should pass key');
return 'FOO';
}
},
};
assert.equal(
getWithDefault(obj, 'foo', 'fail'),
'FOO',
'should return value from unknownProperty'
);
assert.equal(
getWithDefault(obj, 'bar', 'default'),
'default',
'should convert undefined from unknownProperty into default'
);
expectDeprecation(() => {
let obj = {
unknownProperty(key) {
if (key === 'foo') {
assert.equal(key, 'foo', 'should pass key');
return 'FOO';
}
},
};
assert.equal(
getWithDefault(obj, 'foo', 'fail'),
'FOO',
'should return value from unknownProperty'
);
assert.equal(
getWithDefault(obj, 'bar', 'default'),
'default',
'should convert undefined from unknownProperty into default'
);
}, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./);
}

['@test if unknownProperty is present, it is called using accessors'](assert) {
Expand Down Expand Up @@ -320,23 +324,25 @@ moduleFor(
['@test (regression) watched properties on unmodified inherited objects should still return their original value'](
assert
) {
let MyMixin = Mixin.create({
someProperty: 'foo',
propertyDidChange: observer('someProperty', () => {
/* nothing to do */
}),
});
expectDeprecation(() => {
let MyMixin = Mixin.create({
someProperty: 'foo',
propertyDidChange: observer('someProperty', () => {
/* nothing to do */
}),
});

let baseObject = MyMixin.apply({});
let theRealObject = Object.create(baseObject);
let baseObject = MyMixin.apply({});
let theRealObject = Object.create(baseObject);

assert.equal(
getWithDefault(theRealObject, 'someProperty', 'fail'),
'foo',
'should return the set value, not false'
);
assert.equal(
getWithDefault(theRealObject, 'someProperty', 'fail'),
'foo',
'should return the set value, not false'
);

run(() => destroy(baseObject));
run(() => destroy(baseObject));
}, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./);
}

['@test should respect prototypical inheritance when subclasses override CPs'](assert) {
Expand Down
38 changes: 20 additions & 18 deletions packages/@ember/-internals/metal/tests/tracked/get_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,30 @@ moduleFor(
}

['@test should get arbitrary properties on an object']() {
let obj = createObj();
expectDeprecation(() => {
let obj = createObj();

for (let key in obj) {
this.assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key);
}
for (let key in obj) {
this.assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key);
}

class Obj {
@tracked undef = undefined;
}
class Obj {
@tracked undef = undefined;
}

let obj2 = new Obj();
let obj2 = new Obj();

this.assert.equal(
getWithDefault(obj2, 'undef', 'default'),
'default',
'explicit undefined retrieves the default'
);
this.assert.equal(
getWithDefault(obj2, 'not-present', 'default'),
'default',
'non-present key retrieves the default'
);
this.assert.equal(
getWithDefault(obj2, 'undef', 'default'),
'default',
'explicit undefined retrieves the default'
);
this.assert.equal(
getWithDefault(obj2, 'not-present', 'default'),
'default',
'non-present key retrieves the default'
);
}, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./);
}
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ export default Mixin.create({
@param {Object} defaultValue The value to return if the property value is undefined
@return {Object} The property value or the defaultValue.
@public
@deprecated
*/
getWithDefault(keyName, defaultValue) {
return getWithDefault(this, keyName, defaultValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ function K() {

function testWithDefault(assert, expect, x, y, z) {
assert.equal(get(x, y), expect);
assert.equal(getWithDefault(x, y, z), expect);
assert.equal(x.getWithDefault(y, z), expect);
expectDeprecation(() => {
assert.equal(getWithDefault(x, y, z), expect);
assert.equal(x.getWithDefault(y, z), expect);
}, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./);
}

moduleFor(
Expand Down

0 comments on commit 4e8863e

Please sign in to comment.