
(lifted some of this introduction from #15055)
The Ember test suite is very coupled to the default globals-mode resolver. For example:
- Tests often make a controller available to an application as
App.FooController
- Tests often use
setTemplates to set a template onto Ember.TEMPLATES
- Even more tests use
App.Router to set location or other configuration
All of these ways of passing things to Ember are considered part of the globals-mode resolver API.
At some far future date, we would like to drop the default resolver and its globals API from Ember. Nearly all (but not all) Ember apps are built using Ember-CLI. Those applications (with a few minor tweaks) do not need the default resolver. Already they use the ember-resolver, however this itself is a subclass of the default resolver and retains globals loading as a fallback behavior.
The first step (of many) toward removal of the globals-mode default resolver is to refactor Ember's test suite to not be reliant upon it. To this end #15055 introduced a configurable resolver mock to be used in Ember tests, ideally through the class-based testing abstraction added during the Glimmer2 test porting effort. For example:
/*
* internal-test-helpers provides several testcase classes.
*/
import { moduleFor, ApplicationTestCase } from 'internal-test-helpers';
/*
* Pass an anonymous class extending from the testcase to moduleFor.
*/
moduleFor('Link-to component', class extends ApplicationTestCase {
/*
* As you are defining an ES class for your test module, you may
* override APIs from the parent class and call super. If needed, you
* can even create a whole new test case in internal-test-helpers
*/
/*
* In this format, tests are any property on the class that starts
* with "@test".
*/
['@test should be able to be inserted in DOM when the router is not present']() {
/*
* Inside the test the class instance is `this`. For example
*
* this.addTemplate('application', '<p>{{prop}}</p>');
*
* Will add a template to the test resolver. To add a controller
* you would use the specifier and `add`:
*
* this.add('controller:application', Controller.extend());
*
* This replaces older test styles where App.ApplicationController
* would be set.
*
* Exactly what the API of `this` is changes based on what class
* is extended, of course.
*
* Here is a real link-to test as an example:
*/
this.addTemplate('application', `{{#link-to 'index'}}Go to Index{{/link-to}}`);
return this.visit('/').then(() => {
this.assertText('Go to Index');
});
}
});
Roughly taken from link-to-test.js.
ApplicationTestCase will default to the ModuleBasedTestResolver mock. To break it down:
Our goal is to migrate all tests in Ember that implicitly rely on the globals resolver to this improved testing style. Note that the aim really is to use the test resolver: Some tests may be avoiding the implicit default resolver by registering factories into the registry. Those tests should also be migrated to the mock resolver.
How to help

Figuring out what tests use the default resolver to pass is a little tricky since it is, well, default. Once you identify a test that uses the default resolver, you still must ascertain if that test is testing the default resolver or if it the dependency is only implicit. Most tests using the default resolver should be candidates for refactoring: They are not testing interaction with the resolver.
Running this ag call:
ag -H -C 1 -G test.js "setTemplate|\.Router|App\." packages/
Spits out a list of tests possibly using the globals resolver. I've narrowed that list to 28 files that look like good candidates for refactoring:
Your mission, should you choose to accept it, is to pick a file from that list and port it from the old style to a test that uses the class-based testing framework and does not use the global resolver.
A successfully converted file will:
- Use the class-based testing harness. It may not use
ApplicationTestCase though. In fact, there are already other test cases that might be more appropriate such as RenderTestCase or AutobootApplicationTestCase. However, all these class-based systems should default to the TestResolver or ModuleBasedTestResolver. If you add or modify a test case, be sure it defaults to the test resolver.
- Not be reliant upon the globals mode resolver, unless part of the file is actively testing the default global
Resolver. This subset of tests should opt-in to the global resolver. For an example of this see application_test.js:193.
- Not skirt the matter by using the registry for factories. Unless a test is actively testing interaction with the registry, the test resolver is preferred.
The following are useful resources in your journey:
test-resolver.js from internal-test-helpers.
test-cases/ folder in internal-test-helpers.
- #15055 for context and examples of properly migrated files.
- #15060 as simple example of a conversion by @josemarluedke, plus a note on how
autoboot is used in these tests.
- #13127, the Glimmer 2 test issue, for more examples of the class-based tests. You can poke around the codebase as well.
Please see the Google spreadsheet "Ember tests using the globals resolver" to learn what files make good candidates for this work. Add your Github handle and the date there if you are attempting a refactor. Advanced Jedi may find refactoring opportunities not included in that spreadsheet, please feel free to add them and open a PR.
Thank you for your help! If you're attending EmberConf, perhaps I can pick up a ☕️ or 🍻 tab!
(lifted some of this introduction from #15055)
The Ember test suite is very coupled to the default globals-mode resolver. For example:
App.FooControllersetTemplatesto set a template ontoEmber.TEMPLATESApp.Routerto set location or other configurationAll of these ways of passing things to Ember are considered part of the globals-mode resolver API.
At some far future date, we would like to drop the default resolver and its globals API from Ember. Nearly all (but not all) Ember apps are built using Ember-CLI. Those applications (with a few minor tweaks) do not need the default resolver. Already they use the ember-resolver, however this itself is a subclass of the default resolver and retains globals loading as a fallback behavior.
The first step (of many) toward removal of the globals-mode default resolver is to refactor Ember's test suite to not be reliant upon it. To this end #15055 introduced a configurable resolver mock to be used in Ember tests, ideally through the class-based testing abstraction added during the Glimmer2 test porting effort. For example:
Roughly taken from link-to-test.js.
ApplicationTestCasewill default to theModuleBasedTestResolvermock. To break it down:ApplicationTestCaseis a subclass ofAbstractApplicationTestCaseAbstractApplicationTestCasecreates an application. The options default the resolver to theModuleBasedTestResolver.ModuleBasedTestResolveris a subclass ofTestResolver. The module-based resolver will use loading substates (a feature globals mode cannot successfully be integrated with) but besides that there is no difference.Our goal is to migrate all tests in Ember that implicitly rely on the globals resolver to this improved testing style. Note that the aim really is to use the test resolver: Some tests may be avoiding the implicit default resolver by registering factories into the registry. Those tests should also be migrated to the mock resolver.
How to help
Figuring out what tests use the default resolver to pass is a little tricky since it is, well, default. Once you identify a test that uses the default resolver, you still must ascertain if that test is testing the default resolver or if it the dependency is only implicit. Most tests using the default resolver should be candidates for refactoring: They are not testing interaction with the resolver.
Running this
agcall:Spits out a list of tests possibly using the globals resolver. I've narrowed that list to 28 files that look like good candidates for refactoring:
Your mission, should you choose to accept it, is to pick a file from that list and port it from the old style to a test that uses the class-based testing framework and does not use the global resolver.
A successfully converted file will:
ApplicationTestCasethough. In fact, there are already other test cases that might be more appropriate such asRenderTestCaseorAutobootApplicationTestCase. However, all these class-based systems should default to theTestResolverorModuleBasedTestResolver. If you add or modify a test case, be sure it defaults to the test resolver.Resolver. This subset of tests should opt-in to the global resolver. For an example of this seeapplication_test.js:193.The following are useful resources in your journey:
test-resolver.jsfrominternal-test-helpers.test-cases/folder ininternal-test-helpers.autobootis used in these tests.Please see the Google spreadsheet "Ember tests using the globals resolver" to learn what files make good candidates for this work. Add your Github handle and the date there if you are attempting a refactor. Advanced Jedi may find refactoring opportunities not included in that spreadsheet, please feel free to add them and open a PR.
Thank you for your help! If you're attending EmberConf, perhaps I can pick up a ☕️ or 🍻 tab!