Skip to content

Commit

Permalink
add more cases and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Garrett committed Feb 5, 2021
1 parent e924821 commit bb60764
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 6 deletions.
2 changes: 1 addition & 1 deletion packages/@ember/-internals/metal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export {
export { Mixin, aliasMethod, mixin, observer, applyMixin } from './lib/mixin';
export { default as inject, DEBUG_INJECTION_FUNCTIONS } from './lib/injected_property';
export { tagForProperty, tagForObject, markObjectAsDirty } from './lib/tags';
export { tracked } from './lib/tracked';
export { tracked, TrackedDescriptor } from './lib/tracked';
export { createCache, getValue, isConst } from './lib/cache';

export {
Expand Down
6 changes: 3 additions & 3 deletions packages/@ember/-internals/metal/lib/tracked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,16 @@ function descriptorForField([target, key, desc]: [
return newDesc;
}

class TrackedDescriptor {
export class TrackedDescriptor {
constructor(private _get: () => unknown, private _set: (value: unknown) => void) {
CHAIN_PASS_THROUGH.add(this);
}

get(obj: object) {
get(obj: object): unknown {
return this._get.call(obj);
}

set(obj: object, _key: string, value: unknown) {
set(obj: object, _key: string, value: unknown): void {
this._set.call(obj, value);
}
}
23 changes: 22 additions & 1 deletion packages/@ember/-internals/runtime/lib/system/core_object.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
classToString,
isClassicDecorator,
DEBUG_INJECTION_FUNCTIONS,
TrackedDescriptor,
} from '@ember/-internals/metal';
import ActionHandler from '../mixins/action_handler';
import { assert, deprecate } from '@ember/debug';
Expand Down Expand Up @@ -129,7 +130,7 @@ function initialize(obj, properties) {
}

if (isDescriptor) {
if (DEBUG) {
if (DEBUG && injectedProperties.indexOf(keyName) !== -1) {
// need to check if implicit injection owner.inject('component:my-component', 'foo', 'service:bar') does not match explicit injection @service foo
// implicit injection takes precedence so need to tell user to rename property on obj
let isInjectedProperty = DEBUG_INJECTION_FUNCTIONS.has(possibleDesc._getter);
Expand All @@ -140,6 +141,26 @@ function initialize(obj, properties) {
obj
)}. However, a different service or value was injected via implicit injections which overrode your explicit injection. Implicit injections have been deprecated, and will be removed in the near future. In order to prevent breakage, you should inject the same value explicitly that is currently being injected implicitly.`
);
} else if (possibleDesc instanceof TrackedDescriptor) {
let descValue = possibleDesc.get(obj, keyName);

if (value !== descValue) {
implicitInjectionDeprecation(
keyName,
`A value was injected implicitly on the '${keyName}' tracked property of an instance of ${inspect(
obj
)}, overwriting the original value which was ${inspect(
descValue
)}. Implicit injection is now deprecated, please add an explicit injection for this value. If the injected value is a service, consider using the @service decorator.`
);
}
} else if (possibleDesc._setter === undefined) {
implicitInjectionDeprecation(
keyName,
`A value was injected implicitly on the '${keyName}' computed property of an instance of ${inspect(
obj
)}. Implicit injection is now deprecated, please add an explicit injection for this value. If the injected value is a service, consider using the @service decorator.`
);
}
}

Expand Down
114 changes: 113 additions & 1 deletion packages/@ember/-internals/runtime/tests/system/object/create_test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getFactoryFor, Registry } from '@ember/-internals/container';
import { inspect } from '@ember/-internals/utils';
import { getOwner, setOwner } from '@ember/-internals/owner';
import { computed, Mixin, observer, addObserver, alias } from '@ember/-internals/metal';
import { computed, Mixin, observer, addObserver, alias, tracked } from '@ember/-internals/metal';
import Service, { inject as service } from '@ember/service';
import { DEBUG } from '@glimmer/env';
import EmberObject from '../../../lib/system/object';
Expand Down Expand Up @@ -182,6 +182,118 @@ moduleFor(
}, /A value was injected implicitly on the 'foo' property of an instance of <.*>, overwriting the original value which was <.*>. Implicit injection is now deprecated, please add an explicit injection for this value/);
}

['@test does not raise deprecation if descriptor is a tracked property and equal to the implicit deprecation'](
assert
) {
expectNoDeprecation();

let owner = buildOwner();

class FooService extends Service {
bar = 'foo';
}
class BarService extends Service {
bar = 'bar';
}
class FooObject extends EmberObject {
@tracked foo = getOwner(this).lookup('service:foo');
}
owner.register('service:foo', FooService);
owner.register('service:bar', BarService);
owner.register('foo:main', FooObject);
owner.inject('foo:main', 'foo', 'service:foo');

let result = owner.lookup('foo:main');
assert.equal(result.foo.bar, 'foo');
}

['@test does raise deprecation if descriptor is a tracked property and not equal to the implicit deprecation'](
assert
) {
let owner = buildOwner();

class FooService extends Service {
bar = 'foo';
}
class BarService extends Service {
bar = 'bar';
}
class FooObject extends EmberObject {
@tracked foo = getOwner(this).lookup('service:foo');
}
owner.register('service:foo', FooService);
owner.register('service:bar', BarService);
owner.register('foo:main', FooObject);
owner.inject('foo:main', 'foo', 'service:bar');

expectDeprecation(() => {
let result = owner.lookup('foo:main');
assert.equal(result.foo.bar, 'bar');
}, /A value was injected implicitly on the 'foo' tracked property of an instance of <.*>, overwriting the original value which was <.*>. Implicit injection is now deprecated, please add an explicit injection for this value/);
}

['@test does not raise deprecation if descriptor is a computed property with a setter'](
assert
) {
expectNoDeprecation();

let owner = buildOwner();

class FooService extends Service {
bar = 'foo';
}
class BarService extends Service {
bar = 'bar';
}
class FooObject extends EmberObject {
@computed
get foo() {
return getOwner(this).lookup('service:foo');
}

set foo(val) {}
}
owner.register('service:foo', FooService);
owner.register('service:bar', BarService);
owner.register('foo:main', FooObject);
owner.inject('foo:main', 'foo', 'service:foo');

let result = owner.lookup('foo:main');
assert.equal(result.foo.bar, 'foo');
}

['@test does raise deprecation if descriptor is a computed property without a setter'](assert) {
let owner = buildOwner();

class FooService extends Service {
bar = 'foo';
}
class BarService extends Service {
bar = 'bar';
}
class FooObject extends EmberObject {
@computed
get foo() {
return getOwner(this).lookup('service:foo');
}
}
owner.register('service:foo', FooService);
owner.register('service:bar', BarService);
owner.register('foo:main', FooObject);
owner.inject('foo:main', 'foo', 'service:bar');

expectDeprecation(
/The <.*>#foo computed property was just overridden. This removes the computed property and replaces it with a plain value, and has been deprecated. If you want this behavior, consider defining a setter which does it manually./
);

expectDeprecation(
/A value was injected implicitly on the 'foo' computed property of an instance of <.*>. Implicit injection is now deprecated, please add an explicit injection for this value/
);

let result = owner.lookup('foo:main');
assert.equal(result.foo.bar, 'bar');
}

['@test does not raise deprecation if descriptor is a getter and equal to the implicit deprecation'](
assert
) {
Expand Down

0 comments on commit bb60764

Please sign in to comment.