Skip to content

Commit e34264e

Browse files
author
Robert Jackson
committed
Remove supporting code for Ember < 4
1 parent a051a3c commit e34264e

File tree

5 files changed

+66
-214
lines changed

5 files changed

+66
-214
lines changed

addon-test-support/@ember/test-helpers/-internal/get-component-manager.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

addon-test-support/@ember/test-helpers/-internal/is-component.ts

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import Ember from 'ember';
21
import {
32
macroCondition,
43
importSync,
@@ -11,20 +10,12 @@ if (macroCondition(dependencySatisfies('ember-source', '>=4.5.0-beta.1'))) {
1110
//@ts-ignore
1211
renderSettled = importSync('@ember/renderer').renderSettled;
1312
} else if (
14-
macroCondition(dependencySatisfies('ember-source', '>=3.27.0-alpha.1'))
13+
macroCondition(dependencySatisfies('ember-source', '>=4.0.0-alpha.1'))
1514
) {
1615
//@ts-ignore
1716
renderSettled = importSync('@ember/-internals/glimmer').renderSettled;
18-
} else if (
19-
macroCondition(dependencySatisfies('ember-source', '>=3.6.0-alpha.1'))
20-
) {
21-
renderSettled = (Ember as any).__loader.require(
22-
'@ember/-internals/glimmer'
23-
).renderSettled;
2417
} else {
25-
renderSettled = (Ember as any).__loader.require(
26-
'ember-glimmer'
27-
).renderSettled;
18+
throw new Error('Using an unsupported version of Ember (@ember/test-helpers@3.0.0+ requires Ember 4 or higher)');
2819
}
2920

3021
export default renderSettled;

addon-test-support/@ember/test-helpers/setup-application-context.ts

Lines changed: 28 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
TestContext,
77
} from './setup-context';
88
import global from './global';
9-
import hasEmberVersion from './has-ember-version';
109
import settled from './settled';
1110
import getTestMetadata from './test-metadata';
1211
import { runHooks } from './-internal/helper-hooks';
@@ -18,9 +17,7 @@ export interface ApplicationTestContext extends TestContext {
1817
element?: Element | null;
1918
}
2019

21-
const CAN_USE_ROUTER_EVENTS = hasEmberVersion(3, 6);
2220
let routerTransitionsPending: boolean | null = null;
23-
const ROUTER = new WeakMap();
2421
const HAS_SETUP_ROUTER = new WeakMap();
2522

2623
// eslint-disable-next-line require-jsdoc
@@ -37,33 +34,7 @@ export function isApplicationTestContext(
3734
@returns {(boolean|null)} if there are pending transitions
3835
*/
3936
export function hasPendingTransitions(): boolean | null {
40-
if (CAN_USE_ROUTER_EVENTS) {
41-
return routerTransitionsPending;
42-
}
43-
44-
let context = getContext();
45-
46-
// there is no current context, we cannot check
47-
if (context === undefined) {
48-
return null;
49-
}
50-
51-
let router = ROUTER.get(context);
52-
53-
if (router === undefined) {
54-
// if there is no router (e.g. no `visit` calls made yet), we cannot
55-
// check for pending transitions but this is explicitly not an error
56-
// condition
57-
return null;
58-
}
59-
60-
let routerMicrolib = router._routerMicrolib || router.router;
61-
62-
if (routerMicrolib === undefined) {
63-
return null;
64-
}
65-
66-
return !!routerMicrolib.activeTransition;
37+
return routerTransitionsPending;
6738
}
6839

6940
/**
@@ -90,28 +61,20 @@ export function setupRouterSettlednessTracking() {
9061

9162
let { owner } = context;
9263
let router: Router | RouterService;
93-
if (CAN_USE_ROUTER_EVENTS) {
94-
// SAFETY: unfortunately we cannot `assert` here at present because the
95-
// class is not exported, only the type, since it is not designed to be
96-
// sub-classed. The most we can do at present is assert that it at least
97-
// *exists* and assume that if it does exist, it is bound correctly.
98-
let routerService = owner.lookup('service:router');
99-
assert('router service is not set up correctly', !!routerService);
100-
router = routerService as RouterService;
101-
102-
// track pending transitions via the public routeWillChange / routeDidChange APIs
103-
// routeWillChange can fire many times and is only useful to know when we have _started_
104-
// transitioning, we can then use routeDidChange to signal that the transition has settled
105-
router.on('routeWillChange', () => (routerTransitionsPending = true));
106-
router.on('routeDidChange', () => (routerTransitionsPending = false));
107-
} else {
108-
// SAFETY: similarly, this cast cannot be made safer because on the versions
109-
// where we fall into this path, this is *also* not an exported class.
110-
let mainRouter = owner.lookup('router:main');
111-
assert('router:main is not available', !!mainRouter);
112-
router = mainRouter as Router;
113-
ROUTER.set(context, router);
114-
}
64+
65+
// SAFETY: unfortunately we cannot `assert` here at present because the
66+
// class is not exported, only the type, since it is not designed to be
67+
// sub-classed. The most we can do at present is assert that it at least
68+
// *exists* and assume that if it does exist, it is bound correctly.
69+
let routerService = owner.lookup('service:router');
70+
assert('router service is not set up correctly', !!routerService);
71+
router = routerService as RouterService;
72+
73+
// track pending transitions via the public routeWillChange / routeDidChange APIs
74+
// routeWillChange can fire many times and is only useful to know when we have _started_
75+
// transitioning, we can then use routeDidChange to signal that the transition has settled
76+
router.on('routeWillChange', () => (routerTransitionsPending = true));
77+
router.on('routeDidChange', () => (routerTransitionsPending = false));
11578

11679
// hook into teardown to reset local settledness state
11780
let ORIGINAL_WILL_DESTROY = router.willDestroy;
@@ -204,8 +167,6 @@ export function currentRouteName(): string {
204167
return currentRouteName;
205168
}
206169

207-
const HAS_CURRENT_URL_ON_ROUTER = hasEmberVersion(2, 13);
208-
209170
/**
210171
@public
211172
@returns {string} the applications current url
@@ -220,29 +181,22 @@ export function currentURL(): string {
220181

221182
let router = context.owner.lookup('router:main');
222183

223-
if (HAS_CURRENT_URL_ON_ROUTER) {
224-
let routerCurrentURL = get(router, 'currentURL');
184+
let routerCurrentURL = get(router, 'currentURL');
225185

226-
// SAFETY: this path is a lie for the sake of the public-facing types. The
227-
// framework itself sees this path, but users never do. A user who calls the
228-
// API without calling `visit()` will see an `UnrecognizedURLError`, rather
229-
// than getting back `null`.
230-
if (routerCurrentURL === null) {
231-
return routerCurrentURL as never as string;
232-
}
186+
// SAFETY: this path is a lie for the sake of the public-facing types. The
187+
// framework itself sees this path, but users never do. A user who calls the
188+
// API without calling `visit()` will see an `UnrecognizedURLError`, rather
189+
// than getting back `null`.
190+
if (routerCurrentURL === null) {
191+
return routerCurrentURL as never as string;
192+
}
233193

234-
assert(
235-
`currentUrl should be a string, but was ${typeof routerCurrentURL}`,
236-
typeof routerCurrentURL === 'string'
237-
);
194+
assert(
195+
`currentUrl should be a string, but was ${typeof routerCurrentURL}`,
196+
typeof routerCurrentURL === 'string'
197+
);
238198

239-
return routerCurrentURL;
240-
} else {
241-
// SAFETY: this is *positively ancient* and should probably be removed at
242-
// some point; old routers which don't have `currentURL` *should* have a
243-
// `location` with `getURL()` per the docs for 2.12.
244-
return (get(router, 'location') as any).getURL();
245-
}
199+
return routerCurrentURL;
246200
}
247201

248202
/**

addon-test-support/@ember/test-helpers/setup-rendering-context.ts

Lines changed: 36 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@ import { Owner } from './build-owner';
1515
import getTestMetadata from './test-metadata';
1616
import { assert } from '@ember/debug';
1717
import { runHooks } from './-internal/helper-hooks';
18-
import hasEmberVersion from './has-ember-version';
19-
import isComponent from './-internal/is-component';
20-
import { macroCondition, dependencySatisfies } from '@embroider/macros';
2118
import { ComponentRenderMap, SetUsage } from './setup-context';
2219
import { ensureSafeComponent } from '@embroider/util';
23-
import type { ComponentInstance } from '@glimmer/interfaces';
20+
import type { ComponentInstance, InternalComponentManager } from '@glimmer/interfaces';
21+
import { getInternalComponentManager } from '@glimmer/manager';
2422

2523
const OUTLET_TEMPLATE = hbs`{{outlet}}`;
2624
const EMPTY_TEMPLATE = hbs``;
@@ -33,6 +31,19 @@ export interface RenderingTestContext extends TestContext {
3331
[hasCalledSetupRenderingContext]?: true;
3432
}
3533

34+
/**
35+
* We should ultimately get a new API from @glimmer/runtime that provides this functionality
36+
* (see https://github.com/emberjs/rfcs/pull/785 for more info).
37+
* @private
38+
* @param {Object} maybeComponent The thing you think might be a component
39+
* @returns {boolean} True if it's a component, false if not
40+
*/
41+
function isComponent(maybeComponent: object): boolean {
42+
let manager = getInternalComponentManager(maybeComponent, true);
43+
44+
return !!manager;
45+
}
46+
3647
// Isolates the notion of transforming a TextContext into a RenderingTestContext.
3748
// eslint-disable-next-line require-jsdoc
3849
function prepare(context: TestContext): RenderingTestContext {
@@ -131,60 +142,38 @@ export function render(
131142
let OutletTemplate = lookupOutletTemplate(owner);
132143
let ownerToRenderFrom = options?.owner || owner;
133144

134-
if (macroCondition(dependencySatisfies('ember-source', '<3.24.0'))) {
135-
// Pre 3.24, we just don't support rendering components at all, so we error
136-
// if we find anything that isn't a template.
137-
const isTemplate =
138-
('__id' in templateOrComponent && '__meta' in templateOrComponent) ||
139-
('id' in templateOrComponent && 'meta' in templateOrComponent);
145+
if (isComponent(templateOrComponent)) {
146+
// We use this to track when `render` is used with a component so that we can throw an
147+
// assertion if `this.{set,setProperty} is used in the same test
148+
ComponentRenderMap.set(context, true);
149+
150+
const setCalls = SetUsage.get(context);
140151

141-
if (!isTemplate) {
142-
throw new Error(
143-
`Using \`render\` with something other than a pre-compiled template is not supported until Ember 3.24 (you are on ${Ember.VERSION}).`
152+
if (setCalls !== undefined) {
153+
assert(
154+
`You cannot call \`this.set\` or \`this.setProperties\` when passing a component to \`render\`, but they were called for the following properties:\n${setCalls
155+
.map((key) => ` - ${key}`)
156+
.join('\n')}`
144157
);
145158
}
146159

160+
let ProvidedComponent = ensureSafeComponent(
161+
templateOrComponent,
162+
context
163+
);
164+
165+
context = {
166+
ProvidedComponent,
167+
};
168+
templateOrComponent = INVOKE_PROVIDED_COMPONENT;
169+
} else {
147170
templateId += 1;
148171
let templateFullName = `template:-undertest-${templateId}` as const;
149172
ownerToRenderFrom.register(templateFullName, templateOrComponent);
150173
templateOrComponent = lookupTemplate(
151174
ownerToRenderFrom,
152175
templateFullName
153176
);
154-
} else {
155-
if (isComponent(templateOrComponent, owner)) {
156-
// We use this to track when `render` is used with a component so that we can throw an
157-
// assertion if `this.{set,setProperty} is used in the same test
158-
ComponentRenderMap.set(context, true);
159-
160-
const setCalls = SetUsage.get(context);
161-
162-
if (setCalls !== undefined) {
163-
assert(
164-
`You cannot call \`this.set\` or \`this.setProperties\` when passing a component to \`render\`, but they were called for the following properties:\n${setCalls
165-
.map((key) => ` - ${key}`)
166-
.join('\n')}`
167-
);
168-
}
169-
170-
let ProvidedComponent = ensureSafeComponent(
171-
templateOrComponent,
172-
context
173-
);
174-
175-
context = {
176-
ProvidedComponent,
177-
};
178-
templateOrComponent = INVOKE_PROVIDED_COMPONENT;
179-
} else {
180-
templateId += 1;
181-
let templateFullName = `template:-undertest-${templateId}` as const;
182-
ownerToRenderFrom.register(templateFullName, templateOrComponent);
183-
templateOrComponent = lookupTemplate(
184-
ownerToRenderFrom,
185-
templateFullName
186-
);
187-
}
188177
}
189178

190179
let outletState = {
@@ -216,20 +205,6 @@ export function render(
216205
};
217206
toplevelView.setOutletState(outletState);
218207

219-
// Ember's rendering engine is integration with the run loop so that when a run
220-
// loop starts, the rendering is scheduled to be done.
221-
//
222-
// Ember should be ensuring an instance on its own here (the act of
223-
// setting outletState should ensureInstance, since we know we need to
224-
// render), but on Ember < 3.23 that is not guaranteed.
225-
if (!hasEmberVersion(3, 23)) {
226-
// SAFETY: this was correct and type checked on the Ember v3 types, but
227-
// since the `run` namespace does not exist in Ember v4, this no longer
228-
// can be type checked. When (eventually) dropping support for Ember v3,
229-
// and therefore for versions before 3.23, this can be removed entirely.
230-
(run as any).backburner.ensureInstance();
231-
}
232-
233208
// returning settled here because the actual rendering does not happen until
234209
// the renderer detects it is dirty (which happens on backburner's end
235210
// hook), see the following implementation details:

0 commit comments

Comments
 (0)