Skip to content

Commit

Permalink
[BUGFIX] fix issue around how undefined stored in _values chain
Browse files Browse the repository at this point in the history
  • Loading branch information
bekzod committed Dec 22, 2018
1 parent 1f96b17 commit 3bcaa5d
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 22 deletions.
33 changes: 13 additions & 20 deletions packages/@ember/-internals/meta/lib/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -785,34 +785,27 @@ if (DEBUG) {
);

let map = this._getOrCreateOwnMap('_values');
map[subkey] = value;
map[subkey] = value === undefined ? UNDEFINED : value;
};

Meta.prototype.peekValues = function(subkey: string) {
return this._findInherited2('_values', subkey);
Meta.prototype.peekValues = function(key: string) {
let val = this._findInherited2('_values', key);
return val === UNDEFINED ? undefined : val;
};

Meta.prototype.deleteFromValues = function(subkey: string) {
delete this._getOrCreateOwnMap('_values')[subkey];
Meta.prototype.deleteFromValues = function(key: string) {
delete this._getOrCreateOwnMap('_values')[key];
};

Meta.prototype.readInheritedValue = function(key, subkey) {
let internalKey = `_${key}`;

let pointer: Meta | null = this;

while (pointer !== null) {
let map = pointer[internalKey];
if (map !== undefined) {
let value = map[subkey];
if (value !== undefined || subkey in map) {
return value;
}
}
pointer = pointer.parent;
Meta.prototype.readInheritedValue = function(key: string) {
let val = this._findInherited2('_values', key);
if (val === UNDEFINED) {
val = undefined
} else if (val === undefined) {
val = UNDEFINED;
}

return UNDEFINED;
return val;
};

Meta.prototype.writeValue = function(obj: object, key: string, value: any) {
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/metal/lib/properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function INHERITING_GETTER_FUNCTION(name: string): InheritingGetterFuncti
let meta = peekMeta(this);
let val;
if (meta !== undefined) {
val = meta.readInheritedValue('values', name);
val = meta.readInheritedValue(name);
}

if (val === UNDEFINED) {
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/metal/lib/watch_key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export function unwatchKey(obj: object, keyName: string, _meta?: Meta): void {
maybeMandatoryDescriptor.get &&
(maybeMandatoryDescriptor.get as InheritingGetterFunction).isInheritingGetter
) {
let possibleValue = meta.readInheritedValue('values', keyName);
let possibleValue = meta.readInheritedValue(keyName);
if (possibleValue === UNDEFINED) {
delete obj[keyName];
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,25 @@ moduleFor(
assert.equal(get(obj, 'count'), 1, 'should invoke observer after change');
}

['@test setting `undefined` value on observed property behaves correctly'](assert) {
let MyClass = EmberObject.extend({
mood: 'good',
foo: observer('mood', function() {}),
});

let obj = MyClass.create();
assert.equal(get(obj, 'mood'), 'good');

set(obj, 'mood', 'bad');
assert.equal(get(obj, 'mood'), 'bad');

set(obj, 'mood', undefined);
assert.equal(get(obj, 'mood'), undefined);

set(obj, 'mood', 'awesome');
assert.equal(get(obj, 'mood'), 'awesome');
}

['@test observer on subclass'](assert) {
let MyClass = EmberObject.extend({
count: 0,
Expand Down

0 comments on commit 3bcaa5d

Please sign in to comment.