Skip to content

Commit

Permalink
Merge pull request #16873 from emberjs/cleanup-test
Browse files Browse the repository at this point in the history
Cleanup chains fix
  • Loading branch information
rwjblue authored Aug 9, 2018
2 parents 223dc58 + 28fa343 commit e90ee66
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 24 deletions.
7 changes: 4 additions & 3 deletions packages/ember-meta/lib/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,13 @@ export class Meta {
: '',
!this.isMetaDestroyed()
);
let ret = this._chains;
let { _chains: ret } = this;
if (ret === undefined) {
this._chains = ret = create(this.source);

if (this.parent !== null) {
let parentChains = this.parent.writableChains(create);
let { parent } = this;
if (parent !== null) {
let parentChains = parent.writableChains(create);
parentChains.copyTo(ret);
}
}
Expand Down
45 changes: 24 additions & 21 deletions packages/ember-metal/tests/chains_test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
addObserver,
get,
set,
ChainNode,
finishChains,
defineProperty,
Expand Down Expand Up @@ -156,25 +157,26 @@ moduleFor(

['@test writable chains is not defined more than once'](assert) {
assert.expect(0);
function didChange() {}

let obj = {
foo: {
bar: {
baz: {
value: 123,
},
class Base {
constructor() {
finishChains(meta(this));
}

didChange() {}
}

Base.prototype.foo = {
bar: {
baz: {
value: 123,
},
},
};

// Setup object like a constructor, which delays initializing values in chains
let parentMeta = meta(obj);
parentMeta.proto = obj;

// Define a standard computed property, which will eventually setup dependencies
defineProperty(
obj,
Base.prototype,
'bar',
computed('foo.bar', {
get() {
Expand All @@ -184,24 +186,25 @@ moduleFor(
);

// Define some aliases, which will proxy chains along
defineProperty(obj, 'baz', alias('bar.baz'));
defineProperty(obj, 'value', alias('baz.value'));
defineProperty(Base.prototype, 'baz', alias('bar.baz'));
defineProperty(Base.prototype, 'value', alias('baz.value'));

// Define an observer, which will eagerly attempt to setup chains and watch
// their values. This follows the aliases eagerly, and forces the first
// computed to actually set up its values/dependencies for chains. If
// writableChains was not already defined, this results in multiple root
// chain nodes being defined on the same object meta.
addObserver(obj, 'value', null, didChange);

let childObj = Object.create(obj);
addObserver(Base.prototype, 'value', null, 'didChange');

let childMeta = meta(childObj);
class Child extends Base {}

finishChains(childMeta);
let childObj = new Child();

// If we can unwatch the root computed, then chains was not overwritten
unwatch(childObj, 'foo.bar');
set(childObj, 'foo.bar', {
baz: {
value: 456,
},
});
}
}
);

0 comments on commit e90ee66

Please sign in to comment.