diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js
index 80a864e5418..1a11155d4fc 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js
@@ -13,7 +13,7 @@ import {
import { run } from '@ember/runloop';
import { DEBUG } from '@glimmer/env';
-import { set, get, observer, on, computed } from '@ember/-internals/metal';
+import { alias, set, get, observer, on, computed } from '@ember/-internals/metal';
import Service, { inject as injectService } from '@ember/service';
import { Object as EmberObject, A as emberA } from '@ember/-internals/runtime';
import { jQueryDisabled } from '@ember/-internals/views';
@@ -3576,6 +3576,67 @@ moduleFor(
this.render('{{foo-bar}}');
}
+
+ ['@test ensure aliases are watched properly [GH#17243]']() {
+ let fooInstance, barInstance;
+
+ let FooComponent = Component.extend({
+ source: 'first',
+ foo: alias('source'),
+
+ init() {
+ this._super(...arguments);
+ fooInstance = this;
+ },
+ });
+
+ this.registerComponent('foo', {
+ ComponentClass: FooComponent,
+ template: '{{this.foo}}',
+ });
+
+ let BarComponent = Component.extend({
+ target: null,
+
+ init() {
+ this._super(...arguments);
+ barInstance = this;
+ },
+
+ bar: computed('target.foo', function() {
+ if (this.target) {
+ return this.target.foo.toUpperCase();
+ }
+ }),
+ });
+
+ this.registerComponent('bar', {
+ ComponentClass: BarComponent,
+ template: '{{this.bar}}',
+ });
+
+ this.render('[][]');
+
+ this.assertText('[first][]');
+
+ // addObserver
+ runTask(() => set(barInstance, 'target', fooInstance));
+
+ this.assertText('[first][FIRST]');
+
+ runTask(() => set(fooInstance, 'source', 'second'));
+
+ this.assertText('[second][SECOND]');
+
+ // removeObserver
+ runTask(() => set(barInstance, 'target', null));
+
+ this.assertText('[second][]');
+
+ runTask(() => set(fooInstance, 'source', 'third'));
+
+ this.assertText('[third][]');
+ }
}
);
diff --git a/packages/@ember/-internals/metal/lib/alias.ts b/packages/@ember/-internals/metal/lib/alias.ts
index 38471c23882..b8f3b6cdb1e 100644
--- a/packages/@ember/-internals/metal/lib/alias.ts
+++ b/packages/@ember/-internals/metal/lib/alias.ts
@@ -46,10 +46,6 @@ export class AliasedProperty extends Descriptor implements DescriptorWithDepende
this.consume(obj, keyName, meta);
}
- didUnwatch(obj: object, keyName: string, meta: Meta): void {
- this.unconsume(obj, keyName, meta);
- }
-
get(obj: object, keyName: string): any {
let ret = get(obj, this.altKey);
this.consume(obj, keyName, metaFor(obj));
diff --git a/packages/@ember/-internals/metal/tests/alias_test.js b/packages/@ember/-internals/metal/tests/alias_test.js
index 0546b99ea32..29a7defff42 100644
--- a/packages/@ember/-internals/metal/tests/alias_test.js
+++ b/packages/@ember/-internals/metal/tests/alias_test.js
@@ -7,6 +7,7 @@ import {
addObserver,
removeObserver,
tagFor,
+ tagForProperty,
} from '..';
import { meta } from '@ember/-internals/meta';
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';
@@ -164,5 +165,57 @@ moduleFor(
assert.equal(count, 2);
}
+
+ ['@test property tags are bumped when the source changes [GH#17243]'](assert) {
+ function assertPropertyTagChanged(obj, keyName, callback) {
+ let tag = tagForProperty(obj, keyName);
+ let before = tag.value();
+
+ callback();
+
+ let after = tag.value();
+
+ assert.notEqual(after, before, `tagForProperty ${keyName} should change`);
+ }
+
+ function assertPropertyTagUnchanged(obj, keyName, callback) {
+ let tag = tagForProperty(obj, keyName);
+ let before = tag.value();
+
+ callback();
+
+ let after = tag.value();
+
+ assert.equal(after, before, `tagForProperty ${keyName} should not change`);
+ }
+
+ defineProperty(obj, 'bar', alias('foo.faz'));
+
+ assertPropertyTagUnchanged(obj, 'bar', () => {
+ assert.equal(get(obj, 'bar'), 'FOO');
+ });
+
+ assertPropertyTagChanged(obj, 'bar', () => {
+ set(obj, 'foo.faz', 'BAR');
+ });
+
+ assertPropertyTagUnchanged(obj, 'bar', () => {
+ assert.equal(get(obj, 'bar'), 'BAR');
+ });
+
+ assertPropertyTagUnchanged(obj, 'bar', () => {
+ // trigger willWatch, then didUnwatch
+ addObserver(obj, 'bar', incrementCount);
+ removeObserver(obj, 'bar', incrementCount);
+ });
+
+ assertPropertyTagChanged(obj, 'bar', () => {
+ set(obj, 'foo.faz', 'FOO');
+ });
+
+ assertPropertyTagUnchanged(obj, 'bar', () => {
+ assert.equal(get(obj, 'bar'), 'FOO');
+ });
+ }
}
);