Skip to content

Commit

Permalink
Use Application.create().buildInstance() when possible.
Browse files Browse the repository at this point in the history
  • Loading branch information
rwjblue committed Nov 8, 2017
1 parent f6a137c commit 93fc750
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 40 deletions.
9 changes: 9 additions & 0 deletions addon-test-support/application.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var __application__;

export function setApplication(application) {
__application__ = application;
}

export function getApplication() {
return __application__;
}
36 changes: 22 additions & 14 deletions addon-test-support/build-owner.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,37 @@ import global from './global';
import ApplicationInstance from '@ember/application/instance';
import Application from '@ember/application';
import EmberObject from '@ember/object';
import { Promise } from 'rsvp';

import require from 'require';
import Ember from 'ember';
import { getResolver } from './resolver';

const Owner = (function() {
// this module only supports Ember 2.4+ but is evaluated
// on older Ember versions (which we support via the legacy-0-6 API)
// and calling `.extend` with undefined is an issue
if (Ember._RegistryProxyMixin && Ember._ContainerProxyMixin) {
return EmberObject.extend(Ember._RegistryProxyMixin, Ember._ContainerProxyMixin);
}

return EmberObject.extend();
})();
let Owner;

// different than the legacy-0-6-x version (build-registry.js)
// in the following ways:
//
// * Accepts an application to _actually_ boot if possible
// * falls back to "fake owner" if application is not present
// * fewer fallbacks (supports only Ember 2.4+)
// * returns "owner" (instead of a POJO with registry/container)
// * directly calls getResolver if one was not provided
export default function(resolver = getResolver()) {
export default function({ application, resolver }) {
if (application) {
return application.boot().then(app => app.buildInstance().boot());
}

if (!resolver) {
throw new Error(
'You must set up the ember-test-helpers environment with either `setResolver` or `setApplication` before running any tests.'
);
}

if (Owner === undefined) {
Owner = EmberObject.extend(Ember._RegistryProxyMixin, Ember._ContainerProxyMixin, {
_emberTestHelpersMockOwner: true,
});
}

let fallbackRegistry, registry, container;
let namespace = EmberObject.create({
Resolver: {
Expand Down Expand Up @@ -104,5 +112,5 @@ export default function(resolver = getResolver()) {
}
}

return owner;
return Promise.resolve().then(() => owner);
}
1 change: 1 addition & 0 deletions addon-test-support/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { default as TestModuleForComponent } from './legacy-0-6-x/test-module-fo
export { default as TestModuleForModel } from './legacy-0-6-x/test-module-for-model';

export { setResolver } from './resolver';
export { setApplication } from './application';
export {
default as setupContext,
getContext,
Expand Down
4 changes: 0 additions & 4 deletions addon-test-support/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,5 @@ export function setResolver(resolver) {
}

export function getResolver() {
if (__resolver__ == null) {
throw new Error('you must set a resolver with `testResolver.set(resolver)`');
}

return __resolver__;
}
33 changes: 27 additions & 6 deletions addon-test-support/setup-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import Ember from 'ember';
import { Promise } from 'rsvp';
import { assert } from '@ember/debug';
import global from './global';
import { getResolver } from './resolver';
import { getApplication } from './application';

let __test_context__;

Expand Down Expand Up @@ -61,10 +63,30 @@ export default function(context, options = {}) {

return new Promise(resolve => {
// ensure "real" async and not "fake" RSVP based async
next(() => {
let resolver = options.resolver;
let owner = buildOwner(resolver);

next(resolve);
})
.then(() => {
let { resolver } = options;
let buildOwnerOptions;

// This handles precendence, specifying a specific option of
// resolver always trumps whatever is auto-detected, then we fallback to
// the suite-wide registrations
//
// At some later time this can be extended to support specifying a custom
// engine or application...
if (resolver) {
buildOwnerOptions = { resolver };
} else {
buildOwnerOptions = {
resolver: getResolver(),
application: getApplication(),
};
}

return buildOwner(buildOwnerOptions);
})
.then(owner => {
context.owner = owner;

context.set = function(key, value) {
Expand Down Expand Up @@ -110,7 +132,6 @@ export default function(context, options = {}) {
_setupAJAXHooks();
_setupPromiseListeners();

resolve(context);
return context;
});
});
}
11 changes: 9 additions & 2 deletions addon-test-support/setup-rendering-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,15 @@ export default function(context) {
next(() => {
let { owner } = context;

let dispatcher = owner.lookup('event_dispatcher:main') || Ember.EventDispatcher.create();
dispatcher.setup({}, '#ember-testing');
// When the host app uses `setApplication` (instead of `setResolver`) the event dispatcher has
// already been setup via `applicationInstance.boot()` in `./build-owner`. If using
// `setResolver` (instead of `setApplication`) a "mock owner" is created by extending
// `Ember._ContainerProxyMixin` and `Ember._RegistryProxyMixin` in this scenario we need to
// manually start the event dispatcher.
if (owner._emberTestHelpersMockOwner) {
let dispatcher = owner.lookup('event_dispatcher:main') || Ember.EventDispatcher.create();
dispatcher.setup({}, '#ember-testing');
}

let OutletView = owner.factoryFor
? owner.factoryFor('view:-outlet')
Expand Down
11 changes: 10 additions & 1 deletion tests/dummy/app/resolver.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import Resolver from 'ember-resolver';

export default Resolver;
export let registry = Object.create(null);
export function setRegistry(newRegistry) {
registry = newRegistry;
}

export default Resolver.extend({
resolve(fullName) {
return registry[fullName] || this._super(...arguments);
},
});
19 changes: 6 additions & 13 deletions tests/helpers/resolver.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
import Ember from 'ember';
import { run } from '@ember/runloop';
import { dasherize } from '@ember/string';
import AppResolver from '../../resolver';
import AppResolver, { setRegistry } from '../../resolver';
import config from '../../config/environment';
import { setResolver } from 'ember-test-helpers';
import { setResolver, setApplication } from 'ember-test-helpers';
import require from 'require';
import App from '../../app';

const Resolver = AppResolver.extend({
registry: {},

resolve(fullName) {
return this.registry[fullName] || this._super(...arguments);
},
});

const resolver = Resolver.create();
const resolver = AppResolver.create();

resolver.namespace = {
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
};

setResolver(resolver);
setApplication(App.create({ autoboot: false }));

export function setResolverRegistry(registry) {
run(resolver, 'set', 'registry', registry);
setRegistry(registry);
}

export default {
Expand Down

0 comments on commit 93fc750

Please sign in to comment.