From cf18a2dd40dd0f61d003f6362ce7fb6f6a7e703d Mon Sep 17 00:00:00 2001 From: Peter Wagenet Date: Thu, 10 Feb 2022 17:24:45 -0800 Subject: [PATCH 1/2] Make test owners more realistic --- .../routing/tests/ext/controller_test.js | 6 ++- .../routing/tests/system/dsl_test.js | 29 ++++++----- .../routing/tests/system/route_test.js | 12 +++++ .../-internals/runtime/tests/inject_test.js | 4 +- .../runtime/tests/system/core_object_test.js | 10 +++- .../tests/system/object/create_test.js | 6 ++- .../controller/tests/controller_test.js | 16 +++++- packages/@ember/service/tests/service_test.js | 10 +++- .../@ember/service/tests/service_ts_test.ts | 10 +++- .../internal-test-helpers/lib/build-owner.js | 51 ++++++++----------- .../lib/test-cases/router-non-application.js | 1 + 11 files changed, 105 insertions(+), 50 deletions(-) diff --git a/packages/@ember/-internals/routing/tests/ext/controller_test.js b/packages/@ember/-internals/routing/tests/ext/controller_test.js index 83db6e54c88..0905dddd148 100644 --- a/packages/@ember/-internals/routing/tests/ext/controller_test.js +++ b/packages/@ember/-internals/routing/tests/ext/controller_test.js @@ -1,6 +1,6 @@ import { setOwner } from '@ember/-internals/owner'; import Controller from '@ember/controller'; -import { buildOwner, moduleFor, AbstractTestCase } from 'internal-test-helpers'; +import { buildOwner, moduleFor, runDestroy, AbstractTestCase } from 'internal-test-helpers'; moduleFor( '@ember/-internals/routing/ext/controller', @@ -51,6 +51,8 @@ moduleFor( 'passes query param only transitions through' ); }, /Calling transitionToRoute on a controller is deprecated/); + + runDestroy(engineInstance); } ["@test replaceRoute considers an engine's mountPoint"](assert) { @@ -96,6 +98,8 @@ moduleFor( 'passes query param only transitions through' ); }, /Calling replaceRoute on a controller is deprecated/); + + runDestroy(engineInstance); } } ); diff --git a/packages/@ember/-internals/routing/tests/system/dsl_test.js b/packages/@ember/-internals/routing/tests/system/dsl_test.js index ad57892e99e..2da4e2281cd 100644 --- a/packages/@ember/-internals/routing/tests/system/dsl_test.js +++ b/packages/@ember/-internals/routing/tests/system/dsl_test.js @@ -1,5 +1,5 @@ import EmberRouter from '../../lib/system/router'; -import { buildOwner, moduleFor, AbstractTestCase } from 'internal-test-helpers'; +import { buildOwner, moduleFor, runDestroy, AbstractTestCase } from 'internal-test-helpers'; moduleFor( 'Ember Router DSL', @@ -8,19 +8,20 @@ moduleFor( super(); this.Router = class extends EmberRouter {}; - this.routerInstance = new this.Router( - buildOwner({ - ownerOptions: { routable: true }, - }) - ); + this.owner = buildOwner({ + ownerOptions: { routable: true }, + }); + this.routerInstance = new this.Router(this.owner); } teardown() { this.Router = null; this.routerInstance = null; + runDestroy(this.owner); } ['@test should fail when using a reserved route name'](assert) { + let owners = []; let reservedNames = ['basic', 'application']; assert.expect(reservedNames.length); @@ -33,9 +34,13 @@ moduleFor( this.route(reservedName); }); - new Router(buildOwner())._initRouterJs(); + let owner = buildOwner(); + owners.push(owner); + new Router(owner)._initRouterJs(); }, "'" + reservedName + "' cannot be used as a route name."); }); + + owners.forEach((o) => runDestroy(o)); } ['@test [GH#16642] better error when using a colon in a route name']() { @@ -186,14 +191,14 @@ moduleFor( constructor() { super(); this.Router = class extends EmberRouter {}; - this.routerInstance = new this.Router( - buildOwner({ - ownerOptions: { routable: true }, - }) - ); + this.owner = buildOwner({ + ownerOptions: { routable: true }, + }); + this.routerInstance = new this.Router(this.owner); } teardown() { + runDestroy(this.owner); this.Router = null; this.routerInstance = null; } diff --git a/packages/@ember/-internals/routing/tests/system/route_test.js b/packages/@ember/-internals/routing/tests/system/route_test.js index b4693c2a4d1..9b542330852 100644 --- a/packages/@ember/-internals/routing/tests/system/route_test.js +++ b/packages/@ember/-internals/routing/tests/system/route_test.js @@ -385,6 +385,8 @@ moduleFor( let authService = owner.lookup('service:auth'); assert.equal(authService, appRoute.get('authService'), 'service.auth is injected'); + + runDestroy(owner); } } ); @@ -448,6 +450,8 @@ moduleFor( { c: 'd' }, 'params match for `posts` route in engine' ); + + runDestroy(engineInstance); } ["@test modelFor considers an engine's mountPoint"](assert) { @@ -497,6 +501,8 @@ moduleFor( assert.strictEqual(route.modelFor('application'), applicationModel); assert.strictEqual(route.modelFor('posts'), postsModel); + + runDestroy(engineInstance); } ["@test transitionTo considers an engine's mountPoint"](assert) { @@ -542,6 +548,8 @@ moduleFor( 'passes query param only transitions through' ); }, /Calling transitionTo on a route is deprecated/); + + runDestroy(engineInstance); } ["@test intermediateTransitionTo considers an engine's mountPoint"](assert) { @@ -576,6 +584,8 @@ moduleFor( let queryParams = {}; route.intermediateTransitionTo(queryParams); assert.strictEqual(lastRoute, queryParams, 'passes query param only transitions through'); + + runDestroy(engineInstance); } ["@test replaceWith considers an engine's mountPoint"](assert) { @@ -621,6 +631,8 @@ moduleFor( 'passes query param only transitions through' ); }, /Calling replaceWith on a route is deprecated/); + + runDestroy(engineInstance); } } ); diff --git a/packages/@ember/-internals/runtime/tests/inject_test.js b/packages/@ember/-internals/runtime/tests/inject_test.js index 79375e0fcc5..408e2064a7e 100644 --- a/packages/@ember/-internals/runtime/tests/inject_test.js +++ b/packages/@ember/-internals/runtime/tests/inject_test.js @@ -2,7 +2,7 @@ import { inject } from '@ember/-internals/metal'; import { DEBUG } from '@glimmer/env'; import EmberObject from '../lib/system/object'; import { buildOwner } from 'internal-test-helpers'; -import { moduleFor, AbstractTestCase } from 'internal-test-helpers'; +import { runDestroy, moduleFor, AbstractTestCase } from 'internal-test-helpers'; moduleFor( 'inject', @@ -18,6 +18,8 @@ moduleFor( expectAssertion(() => { owner.lookup('foo:main'); }, /Attempting to inject an unknown injection: 'bar:baz'/); + + runDestroy(owner); } ['@test factories should return a list of lazy injection full names'](assert) { diff --git a/packages/@ember/-internals/runtime/tests/system/core_object_test.js b/packages/@ember/-internals/runtime/tests/system/core_object_test.js index 9dd0687b498..611b863c488 100644 --- a/packages/@ember/-internals/runtime/tests/system/core_object_test.js +++ b/packages/@ember/-internals/runtime/tests/system/core_object_test.js @@ -1,7 +1,13 @@ import { getOwner, setOwner } from '@ember/-internals/owner'; import { get, set, observer } from '@ember/-internals/metal'; import CoreObject from '../../lib/system/core_object'; -import { moduleFor, AbstractTestCase, buildOwner, runLoopSettled } from 'internal-test-helpers'; +import { + moduleFor, + AbstractTestCase, + buildOwner, + runDestroy, + runLoopSettled, +} from 'internal-test-helpers'; import { track } from '@glimmer/validator'; import { destroy } from '@glimmer/destroyable'; import { run } from '@ember/runloop'; @@ -54,6 +60,8 @@ moduleFor( owner.register('thing:one', someProxyishThing, { instantiate: false }); assert.equal(owner.lookup('thing:one'), someProxyishThing); + + runDestroy(owner); } ['@test should not trigger proxy assertion when probing for a "symbol"'](assert) { diff --git a/packages/@ember/-internals/runtime/tests/system/object/create_test.js b/packages/@ember/-internals/runtime/tests/system/object/create_test.js index a48ff2a8466..38717ebdc69 100644 --- a/packages/@ember/-internals/runtime/tests/system/object/create_test.js +++ b/packages/@ember/-internals/runtime/tests/system/object/create_test.js @@ -4,7 +4,7 @@ import { computed, Mixin, observer, addObserver, alias } from '@ember/-internals import Service, { service } from '@ember/service'; import { DEBUG } from '@glimmer/env'; import EmberObject from '../../../lib/system/object'; -import { buildOwner, moduleFor, AbstractTestCase } from 'internal-test-helpers'; +import { buildOwner, moduleFor, runDestroy, AbstractTestCase } from 'internal-test-helpers'; import { destroy } from '@glimmer/destroyable'; moduleFor( @@ -33,6 +33,8 @@ moduleFor( let obj = owner.lookup('foo:main'); assert.equal(obj.foo.bar, 'foo'); + + runDestroy(owner); } ['@test implicit injections raises deprecation']() { @@ -49,6 +51,8 @@ moduleFor( () => owner.inject('foo:main', 'foo', 'service:foo'), /As of Ember 4.0.0, owner.inject no longer injects values into resolved instances, and calling the method has been deprecated. Since this method no longer does anything, it is fully safe to remove this injection. As an alternative to this API, you can refactor to explicitly inject `foo` on `foo:main`, or look it up directly using the `getOwner` API./ ); + + runDestroy(owner); } ['@test calls computed property setters'](assert) { diff --git a/packages/@ember/controller/tests/controller_test.js b/packages/@ember/controller/tests/controller_test.js index 4b99455e8bc..f6340ae8202 100644 --- a/packages/@ember/controller/tests/controller_test.js +++ b/packages/@ember/controller/tests/controller_test.js @@ -113,6 +113,8 @@ moduleFor( setOwner(controller, owner); controller.send('poke'); + + runDestroy(owner); } ["@test Action can be handled by a superclass' actions object"](assert) { @@ -223,9 +225,9 @@ moduleFor( 'Controller deprecations -> Controller injected properties', class extends AbstractTestCase { ['@test defining a controller on a non-controller should fail assertion']() { - expectAssertion(function () { - let owner = buildOwner(); + let owner = buildOwner(); + expectAssertion(function () { let AnObject = EmberObject.extend({ foo: injectController('bar'), }); @@ -235,6 +237,8 @@ moduleFor( owner.lookup('foo:main'); }, /Defining `foo` as an injected controller property on a non-controller \(`foo:main`\) is not allowed/); + + runDestroy(owner); } ['@test controllers can be injected into controllers'](assert) { @@ -257,6 +261,8 @@ moduleFor( postController.get('postsController'), 'controller.posts is injected' ); + + runDestroy(owner); } ['@test services can be injected into controllers'](assert) { @@ -275,6 +281,8 @@ moduleFor( let authService = owner.lookup('service:auth'); assert.equal(authService, appController.get('authService'), 'service.auth is injected'); + + runDestroy(owner); } } ); @@ -297,6 +305,8 @@ moduleFor( let index = owner.lookup('controller:index'); assert.ok(index.main instanceof Controller, 'controller injected correctly'); + + runDestroy(owner); } ['@test uses the decorated property key if not provided'](assert) { @@ -314,6 +324,8 @@ moduleFor( let index = owner.lookup('controller:index'); assert.ok(index.main instanceof Controller, 'controller injected correctly'); + + runDestroy(owner); } } ); diff --git a/packages/@ember/service/tests/service_test.js b/packages/@ember/service/tests/service_test.js index 5c07fafae4a..37726a3ace3 100644 --- a/packages/@ember/service/tests/service_test.js +++ b/packages/@ember/service/tests/service_test.js @@ -1,6 +1,6 @@ import Service, { inject, service } from '@ember/service'; import { Object as EmberObject } from '@ember/-internals/runtime'; -import { buildOwner } from 'internal-test-helpers'; +import { buildOwner, runDestroy } from 'internal-test-helpers'; import { moduleFor, AbstractTestCase } from 'internal-test-helpers'; moduleFor( @@ -21,6 +21,8 @@ moduleFor( let foo = owner.lookup('foo:main'); assert.ok(foo.main instanceof Service, 'service injected correctly'); + + runDestroy(owner); } ['@test uses the decorated property key if not provided'](assert) { @@ -38,6 +40,8 @@ moduleFor( let foo = owner.lookup('foo:main'); assert.ok(foo.main instanceof Service, 'service injected correctly'); + + runDestroy(owner); } } ); @@ -60,6 +64,8 @@ moduleFor( let foo = owner.lookup('foo:main'); assert.ok(foo.main instanceof Service, 'service injected correctly'); + + runDestroy(owner); } ['@test uses the decorated property key if not provided'](assert) { @@ -77,6 +83,8 @@ moduleFor( let foo = owner.lookup('foo:main'); assert.ok(foo.main instanceof Service, 'service injected correctly'); + + runDestroy(owner); } } ); diff --git a/packages/@ember/service/tests/service_ts_test.ts b/packages/@ember/service/tests/service_ts_test.ts index 41bcdc9b61d..dca6de5ca43 100644 --- a/packages/@ember/service/tests/service_ts_test.ts +++ b/packages/@ember/service/tests/service_ts_test.ts @@ -1,6 +1,6 @@ import Service, { inject, service } from '@ember/service'; import { Object as EmberObject } from '@ember/-internals/runtime'; -import { buildOwner } from 'internal-test-helpers'; +import { buildOwner, runDestroy } from 'internal-test-helpers'; import { moduleFor, AbstractTestCase } from 'internal-test-helpers'; moduleFor( @@ -21,6 +21,8 @@ moduleFor( let foo = owner.lookup('foo:main'); assert.ok(foo.main instanceof Service, 'service injected correctly'); + + runDestroy(owner); } ['@test uses the decorated property key if not provided'](assert: QUnit['assert']) { @@ -38,6 +40,8 @@ moduleFor( let foo = owner.lookup('foo:main'); assert.ok(foo.main instanceof Service, 'service injected correctly'); + + runDestroy(owner); } } ); @@ -60,6 +64,8 @@ moduleFor( let foo = owner.lookup('foo:main'); assert.ok(foo.main instanceof Service, 'service injected correctly'); + + runDestroy(owner); } ['@test uses the decorated property key if not provided'](assert: QUnit['assert']) { @@ -77,6 +83,8 @@ moduleFor( let foo = owner.lookup('foo:main'); assert.ok(foo.main instanceof Service, 'service injected correctly'); + + runDestroy(owner); } } ); diff --git a/packages/internal-test-helpers/lib/build-owner.js b/packages/internal-test-helpers/lib/build-owner.js index 1efb678a238..04c2e56a29d 100644 --- a/packages/internal-test-helpers/lib/build-owner.js +++ b/packages/internal-test-helpers/lib/build-owner.js @@ -1,12 +1,7 @@ -import { Registry } from '@ember/-internals/container'; -import { Router } from '@ember/-internals/routing'; -import ApplicationInstance from '@ember/application/instance'; import Application from '@ember/application'; -import { - RegistryProxyMixin, - ContainerProxyMixin, - Object as EmberObject, -} from '@ember/-internals/runtime'; +import ApplicationInstance from '@ember/application/instance'; +import Engine from '@ember/engine'; +import { registerDestructor } from '@ember/destroyable'; class ResolverWrapper { constructor(resolver) { @@ -19,35 +14,31 @@ class ResolverWrapper { } export default function buildOwner(options = {}) { + let ownerType = options.ownerType || 'application'; let ownerOptions = options.ownerOptions || {}; let resolver = options.resolver; let bootOptions = options.bootOptions || {}; - let Owner = EmberObject.extend(RegistryProxyMixin, ContainerProxyMixin); - - let namespace = EmberObject.create({ - Resolver: new ResolverWrapper(resolver), - }); - - let fallbackRegistry = Application.buildRegistry(namespace); - fallbackRegistry.register('router:main', Router); - - let registry = new Registry({ - fallback: fallbackRegistry, - }); + let namespace; + if (ownerType === 'application') { + namespace = Application.create({ + autoboot: false, + Resolver: new ResolverWrapper(resolver), + }); + } else { + namespace = Engine.create({ + buildRegistry() { + return (this.__registry__ = Application.buildRegistry(this)); + }, + Resolver: new ResolverWrapper(resolver), + }); + } - ApplicationInstance.setupRegistry(registry, bootOptions); + let owner = namespace.buildInstance(ownerOptions); - let owner = Owner.create( - { - __registry__: registry, - __container__: null, - }, - ownerOptions - ); + ApplicationInstance.setupRegistry(owner.__registry__, bootOptions); - let container = registry.container({ owner }); - owner.__container__ = container; + registerDestructor(owner, () => namespace.destroy()); return owner; } diff --git a/packages/internal-test-helpers/lib/test-cases/router-non-application.js b/packages/internal-test-helpers/lib/test-cases/router-non-application.js index ed31bb3f6ef..4802aa5ad93 100644 --- a/packages/internal-test-helpers/lib/test-cases/router-non-application.js +++ b/packages/internal-test-helpers/lib/test-cases/router-non-application.js @@ -13,6 +13,7 @@ export default class RouterNonApplicationTestCase extends AbstractTestCase { let bootOptions = this.getBootOptions(); let owner = (this.owner = buildOwner({ + ownerType: 'engine', ownerOptions: this.getOwnerOptions(), resolver: this.getResolver(), bootOptions, From bd02b0fb72dfb7ed79d7e013da34e046b0e587db Mon Sep 17 00:00:00 2001 From: Peter Wagenet Date: Thu, 10 Feb 2022 15:54:04 -0800 Subject: [PATCH 2/2] Refactor Owner handling with better public API --- .../glimmer/lib/component-managers/mount.ts | 2 ++ .../glimmer/lib/component-managers/outlet.ts | 12 +++---- .../glimmer/lib/components/link-to.ts | 7 ++-- .../application/debug-render-tree-test.ts | 4 +-- packages/@ember/-internals/owner/index.ts | 34 +++++++++++-------- .../-internals/routing/lib/system/route.ts | 7 ++-- .../-internals/routing/lib/system/router.ts | 8 ++--- .../@ember/-internals/routing/lib/utils.ts | 3 +- .../runtime/lib/mixins/container_proxy.d.ts | 11 ++++-- .../runtime/lib/mixins/registry_proxy.d.ts | 25 +++++++++----- .../runtime/lib/mixins/registry_proxy.js | 1 + .../@ember/application/lib/application.d.ts | 2 +- packages/@ember/engine/index.d.ts | 3 +- packages/@ember/engine/instance.d.ts | 10 ++++-- 14 files changed, 76 insertions(+), 53 deletions(-) diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/mount.ts b/packages/@ember/-internals/glimmer/lib/component-managers/mount.ts index cf0bd78b57f..c1911994289 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/mount.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/mount.ts @@ -1,5 +1,6 @@ import { Owner } from '@ember/-internals/owner'; import { generateControllerFactory } from '@ember/-internals/routing'; +import { assert } from '@ember/debug'; import EngineInstance from '@ember/engine/instance'; import { associateDestroyableChild } from '@glimmer/destroyable'; import { @@ -74,6 +75,7 @@ class MountManager // we should resolve the engine app template in the helper // it also should use the owner that looked up the mount helper. + assert('Expected owner to be an EngineInstance', owner instanceof EngineInstance); let engine = owner.buildChildEngineInstance(name); engine.boot(); diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts b/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts index a2f904ea418..0ad930765ba 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts @@ -95,14 +95,14 @@ class OutletComponentManager let currentOwner = valueForRef(currentStateRef)!.render!.owner; if (parentOwner && parentOwner !== currentOwner) { - let engine = currentOwner as EngineInstance; + assert( + 'Expected currentOwner to be an EngineInstance', + currentOwner instanceof EngineInstance + ); - assert('invalid engine: missing mountPoint', typeof currentOwner.mountPoint === 'string'); - assert('invalid engine: missing routable', currentOwner.routable === true); + let mountPoint = currentOwner.mountPoint; - let mountPoint = engine.mountPoint!; - - state.engine = engine; + state.engine = currentOwner; state.engineBucket = { mountPoint }; } } diff --git a/packages/@ember/-internals/glimmer/lib/components/link-to.ts b/packages/@ember/-internals/glimmer/lib/components/link-to.ts index 0320e62a57c..5025ff4ef57 100644 --- a/packages/@ember/-internals/glimmer/lib/components/link-to.ts +++ b/packages/@ember/-internals/glimmer/lib/components/link-to.ts @@ -1,4 +1,3 @@ -import { Owner } from '@ember/-internals/owner'; import { Route, RouterState, RoutingService } from '@ember/-internals/routing'; import { isSimpleClick } from '@ember/-internals/views'; import { assert, debugFreeze, inspect, warn } from '@ember/debug'; @@ -490,11 +489,13 @@ class LinkTo extends InternalComponent { } private get isEngine(): boolean { - return getEngineParent(this.owner as EngineInstance) !== undefined; + let owner = this.owner; + return owner instanceof EngineInstance && getEngineParent(owner) !== undefined; } private get engineMountPoint(): string | undefined { - return (this.owner as Owner | EngineInstance).mountPoint; + let owner = this.owner; + return owner instanceof EngineInstance ? owner.mountPoint : undefined; } private classFor(state: 'active' | 'loading' | 'disabled'): string { diff --git a/packages/@ember/-internals/glimmer/tests/integration/application/debug-render-tree-test.ts b/packages/@ember/-internals/glimmer/tests/integration/application/debug-render-tree-test.ts index 05cde32219d..8ec31d978e2 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/application/debug-render-tree-test.ts +++ b/packages/@ember/-internals/glimmer/tests/integration/application/debug-render-tree-test.ts @@ -7,12 +7,12 @@ import { import { ENV } from '@ember/-internals/environment'; import { Component, setComponentManager } from '@ember/-internals/glimmer'; -import { EngineInstanceOptions, Owner } from '@ember/-internals/owner'; +import { Owner } from '@ember/-internals/owner'; import { Route } from '@ember/-internals/routing'; import Controller from '@ember/controller'; import { assert, captureRenderTree } from '@ember/debug'; import Engine from '@ember/engine'; -import EngineInstance from '@ember/engine/instance'; +import EngineInstance, { EngineInstanceOptions } from '@ember/engine/instance'; import { CapturedRenderNode } from '@glimmer/interfaces'; import { componentCapabilities, setComponentTemplate } from '@glimmer/manager'; import { templateOnlyComponent } from '@glimmer/runtime'; diff --git a/packages/@ember/-internals/owner/index.ts b/packages/@ember/-internals/owner/index.ts index b355f45ea5d..4448d616c1e 100644 --- a/packages/@ember/-internals/owner/index.ts +++ b/packages/@ember/-internals/owner/index.ts @@ -1,9 +1,12 @@ import { getOwner as glimmerGetOwner, setOwner as glimmerSetOwner } from '@glimmer/owner'; +import { TypeOptions } from '../container/lib/registry'; /** @module @ember/application */ +export { TypeOptions }; + export interface FactoryClass { positionalParams?: string | string[] | undefined | null; } @@ -16,25 +19,26 @@ export interface Factory { create(props?: { [prop: string]: any }): T; } -export interface EngineInstanceOptions { - mountPoint: string; - routable: boolean; -} - -import EngineInstance from '@ember/engine/instance'; -import { TypeOptions } from '../container/lib/registry'; +// A combination of the public methods on ContainerProxyMixin and RegistryProxyMixin export interface Owner { + // From ContainerProxy + ownerInjection(): void; lookup(fullName: string, options?: TypeOptions): unknown; factoryFor(fullName: string): Factory | undefined; - register(fullName: string, factory: Factory, options?: TypeOptions): void; - hasRegistration(name: string): boolean; - /** @internal */ - mountPoint?: string; - /** @internal */ - routable?: boolean; - /** @internal */ - buildChildEngineInstance(name: string, options?: EngineInstanceOptions): EngineInstance; + // From RegistryProxy + resolveRegistration(fullName: string): Factory | undefined; + register(fullName: string, factory: Factory, options?: TypeOptions): void; + unregister(fullName: string): void; + hasRegistration(fullName: string): boolean; + registeredOption( + fullName: string, + optionName: K + ): TypeOptions[K] | undefined; + registerOptions(fullName: string, options: TypeOptions): void; + registeredOptions(fullName: string): TypeOptions | undefined; + registerOptionsForType(type: string, options: TypeOptions): void; + registeredOptionsForType(type: string): TypeOptions | undefined; } /** diff --git a/packages/@ember/-internals/routing/lib/system/route.ts b/packages/@ember/-internals/routing/lib/system/route.ts index 6cc78f42568..ccee0955350 100644 --- a/packages/@ember/-internals/routing/lib/system/route.ts +++ b/packages/@ember/-internals/routing/lib/system/route.ts @@ -23,6 +23,7 @@ import { import { isProxy, lookupDescriptor, symbol } from '@ember/-internals/utils'; import Controller from '@ember/controller'; import { assert, info, isTesting } from '@ember/debug'; +import EngineInstance from '@ember/engine/instance'; import { dependentKeyCompat } from '@ember/object/compat'; import { once } from '@ember/runloop'; import { DEBUG } from '@glimmer/env'; @@ -548,7 +549,7 @@ class Route _setRouteName(name: string) { this.routeName = name; let owner = getOwner(this); - assert('Route is unexpectedly missing an owner', owner); + assert('Expected route to have EngineInstance as owner', owner instanceof EngineInstance); this.fullRouteName = getEngineRouteName(owner, name)!; } @@ -1679,7 +1680,7 @@ class Route modelFor(_name: string): unknown | undefined { let name; let owner = getOwner(this); - assert('Route is unexpectedly missing an owner', owner); + assert('Expected router owner to be an EngineInstance', owner instanceof EngineInstance); let transition = this._router && this._router._routerMicrolib ? this._router._routerMicrolib.activeTransition @@ -2332,7 +2333,7 @@ function addQueryParamsObservers(controller: any, propNames: string[]) { }); } -function getEngineRouteName(engine: Owner, routeName: string) { +function getEngineRouteName(engine: EngineInstance, routeName: string) { if (engine.routable) { let prefix = engine.mountPoint; diff --git a/packages/@ember/-internals/routing/lib/system/router.ts b/packages/@ember/-internals/routing/lib/system/router.ts index bf2907212d7..22a815443b4 100644 --- a/packages/@ember/-internals/routing/lib/system/router.ts +++ b/packages/@ember/-internals/routing/lib/system/router.ts @@ -46,6 +46,7 @@ import Router, { TransitionState, } from 'router_js'; import { EngineRouteInfo } from './engines'; +import EngineInstance from '@ember/engine/instance'; function defaultDidTransition( this: EmberRouter, @@ -113,11 +114,6 @@ interface OutletState { wasUsed?: boolean; } -interface EngineInstance extends Owner { - boot(): void; - destroy(): void; -} - export interface QueryParam { prop: string; urlKey: string; @@ -1409,7 +1405,7 @@ class EmberRouter extends EmberObject.extend(Evented) i if (!engineInstance) { let owner = getOwner(this); - assert('Router is unexpectedly missing an owner', owner); + assert('Expected router to have EngineInstance as owner', owner instanceof EngineInstance); assert( `You attempted to mount the engine '${name}' in your router map, but the engine can not be found.`, diff --git a/packages/@ember/-internals/routing/lib/utils.ts b/packages/@ember/-internals/routing/lib/utils.ts index 6589ccff7d1..cb97efa92fb 100644 --- a/packages/@ember/-internals/routing/lib/utils.ts +++ b/packages/@ember/-internals/routing/lib/utils.ts @@ -1,6 +1,7 @@ import { get } from '@ember/-internals/metal'; import { getOwner } from '@ember/-internals/owner'; import { assert, deprecate } from '@ember/debug'; +import EngineInstance from '@ember/engine/instance'; import EmberError from '@ember/error'; import Router, { STATE_SYMBOL, InternalRouteInfo, ModelFor } from 'router_js'; import Route from './system/route'; @@ -247,7 +248,7 @@ export function prefixRouteNameArg | UnnamedRout ): T { let routeName: string; let owner = getOwner(route); - assert('Route is unexpectedly missing an owner', owner); + assert('Expected route to have EngineInstance as owner', owner instanceof EngineInstance); let prefix = owner.mountPoint; diff --git a/packages/@ember/-internals/runtime/lib/mixins/container_proxy.d.ts b/packages/@ember/-internals/runtime/lib/mixins/container_proxy.d.ts index 31d9dbee6b1..2f9cbf8e112 100644 --- a/packages/@ember/-internals/runtime/lib/mixins/container_proxy.d.ts +++ b/packages/@ember/-internals/runtime/lib/mixins/container_proxy.d.ts @@ -1,10 +1,15 @@ import { Container } from '@ember/-internals/container'; +import { TypeOptions } from '@ember/-internals/container/lib/registry'; +import { Factory } from '@ember/-internals/owner'; import Mixin from '../../types/mixin'; interface ContainerProxy { - ownerInjection: Container['ownerInjection']; - lookup: Container['lookup']; - factoryFor: Container['factoryFor']; + /** @internal */ + __container__: Container; + + ownerInjection(): void; + lookup(fullName: string, options?: TypeOptions): unknown; + factoryFor(fullName: string): Factory | undefined; } declare const ContainerProxy: Mixin; diff --git a/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.d.ts b/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.d.ts index b18c207573b..08b5901250a 100644 --- a/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.d.ts +++ b/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.d.ts @@ -1,16 +1,23 @@ import { Registry } from '@ember/-internals/container'; +import { TypeOptions } from '@ember/-internals/container/lib/registry'; +import { Factory } from '@ember/-internals/owner'; import Mixin from '../../types/mixin'; interface RegistryProxyMixin { - resolveRegistration: Registry['resolve']; - register: Registry['register']; - unregister: Registry['unregister']; - hasRegistration: Registry['has']; - registeredOption: Registry['getOption']; - registerOptions: Registry['options']; - registeredOptions: Registry['getOptions']; - registerOptionsForType: Registry['optionsForType']; - registeredOptionsForType: Registry['getOptionsForType']; + /** @internal */ + __registry__: Registry; + resolveRegistration(fullName: string): Factory | undefined; + register(fullName: string, factory: Factory, options?: TypeOptions): void; + unregister(fullName: string): void; + hasRegistration(fullName: string): boolean; + registeredOption( + fullName: string, + optionName: K + ): TypeOptions[K] | undefined; + registerOptions(fullName: string, options: TypeOptions): void; + registeredOptions(fullName: string): TypeOptions | undefined; + registerOptionsForType(type: string, options: TypeOptions): void; + registeredOptionsForType(type: string): TypeOptions | undefined; } declare const RegistryProxyMixin: Mixin; diff --git a/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js b/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js index 5f7a011dca9..59d1c4f70e1 100644 --- a/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js +++ b/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js @@ -254,6 +254,7 @@ export default Mixin.create({ @param factoryNameOrType {String} @param property {String} @param injectionName {String} + @deprecated **/ inject: registryAlias('injection'), }); diff --git a/packages/@ember/application/lib/application.d.ts b/packages/@ember/application/lib/application.d.ts index bb3f709db98..96c93190ac6 100644 --- a/packages/@ember/application/lib/application.d.ts +++ b/packages/@ember/application/lib/application.d.ts @@ -1,6 +1,6 @@ -import { EngineInstanceOptions } from '@ember/-internals/owner'; import { EventDispatcher } from '@ember/-internals/views'; import Engine from '@ember/engine'; +import { EngineInstanceOptions } from '@ember/engine/instance'; import ApplicationInstance, { BootOptions } from '../instance'; export default class Application extends Engine { diff --git a/packages/@ember/engine/index.d.ts b/packages/@ember/engine/index.d.ts index 36a691b14a1..a867217311b 100644 --- a/packages/@ember/engine/index.d.ts +++ b/packages/@ember/engine/index.d.ts @@ -1,5 +1,4 @@ -import EngineInstance from './instance'; -import { EngineInstanceOptions } from '@ember/-internals/owner'; +import EngineInstance, { EngineInstanceOptions } from './instance'; import { Namespace, RegistryProxyMixin } from '@ember/-internals/runtime'; export { getEngineParent } from '@ember/engine/lib/engine-parent'; diff --git a/packages/@ember/engine/instance.d.ts b/packages/@ember/engine/instance.d.ts index 76516f6f970..7dd7f96164f 100644 --- a/packages/@ember/engine/instance.d.ts +++ b/packages/@ember/engine/instance.d.ts @@ -3,12 +3,18 @@ import { Owner } from '@ember/-internals/owner'; import { BootOptions } from '@ember/application/instance'; import EmberObject from '@ember/object'; +export interface EngineInstanceOptions { + mountPoint: string; + routable: boolean; +} + interface EngineInstance extends RegistryProxyMixin, ContainerProxyMixin, Owner {} declare class EngineInstance extends EmberObject { - init(...args: unknown[]): void; boot(options?: BootOptions): void; - unregister(fullName: string): void; + mountPoint: string; + routable: boolean; + buildChildEngineInstance(name: string, options?: EngineInstanceOptions): EngineInstance; } export default EngineInstance;