From 800dab30e8a81a8cd4453824a244120945d24ede Mon Sep 17 00:00:00 2001 From: Chris Garrett Date: Fri, 1 Mar 2019 21:45:23 -0800 Subject: [PATCH] [BUGFIX] Ensure tagForProperty works on class constructors `tagForProperty` was returning the constant tag for functions, which meant it would return the constant tag for properties on class constructors. If a computed property was defined on the class constructor it would fail because of this. --- packages/@ember/-internals/metal/lib/tags.ts | 3 ++- .../metal/tests/computed_decorator_test.js | 19 +++++++++++++++++++ .../-internals/metal/tests/computed_test.js | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/@ember/-internals/metal/lib/tags.ts b/packages/@ember/-internals/metal/lib/tags.ts index 845e2abc1b9..f0ccec00ef8 100644 --- a/packages/@ember/-internals/metal/lib/tags.ts +++ b/packages/@ember/-internals/metal/lib/tags.ts @@ -22,7 +22,8 @@ function makeTag(): TagWrapper { } export function tagForProperty(object: any, propertyKey: string | symbol, _meta?: Meta): Tag { - if (typeof object !== 'object' || object === null) { + let objectType = typeof object; + if (objectType !== 'function' && (objectType !== 'object' || object === null)) { return CONSTANT_TAG; } let meta = _meta === undefined ? metaFor(object) : _meta; diff --git a/packages/@ember/-internals/metal/tests/computed_decorator_test.js b/packages/@ember/-internals/metal/tests/computed_decorator_test.js index d23787657c7..1e85bec51d7 100644 --- a/packages/@ember/-internals/metal/tests/computed_decorator_test.js +++ b/packages/@ember/-internals/metal/tests/computed_decorator_test.js @@ -70,6 +70,25 @@ if (EMBER_NATIVE_DECORATOR_SUPPORT) { get(obj, 'fullName'); } + ['@test computed property can be defined and accessed on a class constructor'](assert) { + let count = 0; + + class Obj { + static bar = 123; + + @computed + static get foo() { + count++; + return this.bar; + } + } + + assert.equal(Obj.foo, 123, 'should return value'); + Obj.foo; + + assert.equal(count, 1, 'should only call getter once'); + } + ['@test it works with computed desc'](assert) { assert.expect(4); diff --git a/packages/@ember/-internals/metal/tests/computed_test.js b/packages/@ember/-internals/metal/tests/computed_test.js index 7f9ed038c8c..52e3df08718 100644 --- a/packages/@ember/-internals/metal/tests/computed_test.js +++ b/packages/@ember/-internals/metal/tests/computed_test.js @@ -82,6 +82,25 @@ moduleFor( assert.equal(count, 1, 'should have invoked computed property'); } + ['@test computed property can be defined and accessed on a class constructor'](assert) { + let count = 0; + + let Obj = EmberObject.extend(); + Obj.reopenClass({ + bar: 123, + + foo: computed(function() { + count++; + return this.bar; + }), + }); + + assert.equal(Obj.foo, 123, 'should return value'); + Obj.foo; + + assert.equal(count, 1, 'should only call getter once'); + } + ['@test can override volatile computed property'](assert) { let obj = {};