Skip to content

Commit

Permalink
Merge pull request #1302 from emberjs/backport-fix
Browse files Browse the repository at this point in the history
[backport] Remove the index signature from `TestContext`
  • Loading branch information
chriskrycho authored Dec 21, 2022
2 parents b487c05 + a34c29b commit 6675e10
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 18 deletions.
36 changes: 20 additions & 16 deletions addon-test-support/@ember/test-helpers/setup-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,34 +60,33 @@ registerWarnHandler((message, options, next) => {
next.apply(null, [message, options]);
});

export interface BaseContext {
[key: string]: unknown;
}
export type BaseContext = object;

/**
* The public API for the test context, which test authors can depend on being
* available.
*
* Note: this is *not* user-constructible; it becomes available by calling
* `setupContext()` with a `BaseContext`.
* `setupContext()` with a base context object.
*/
export interface TestContext extends BaseContext {
owner: Owner;

set<T>(key: string, value: T): T;
setProperties<T extends Record<string, unknown>>(hash: T): T;
get(key: string): unknown;
getProperties(...args: string[]): Pick<BaseContext, string>;
getProperties(...args: string[]): Record<string, unknown>;

pauseTest(): Promise<void>;
resumeTest(): void;
}

// eslint-disable-next-line require-jsdoc
export function isTestContext(context: BaseContext): context is TestContext {
let maybeContext = context as Record<string, unknown>;
return (
typeof context['pauseTest'] === 'function' &&
typeof context['resumeTest'] === 'function'
typeof maybeContext['pauseTest'] === 'function' &&
typeof maybeContext['resumeTest'] === 'function'
);
}

Expand Down Expand Up @@ -367,15 +366,17 @@ export const SetUsage = new WeakMap<BaseContext, Array<string>>();
- setting up `pauseTest` (also available as `this.pauseTest()`) and `resumeTest` helpers
@public
@param {Object} context the context to setup
@param {Object} base the context to setup
@param {Object} [options] options used to override defaults
@param {Resolver} [options.resolver] a resolver to use for customizing normal resolution
@returns {Promise<Object>} resolves with the context that was setup
*/
export default function setupContext(
context: BaseContext,
export default function setupContext<T extends object>(
base: T,
options: { resolver?: Resolver } = {}
): Promise<TestContext> {
): Promise<T & TestContext> {
let context = base as T & TestContext;

// SAFETY: this is intimate API *designed* for us to override.
(Ember as any).testing = true;
setContext(context);
Expand Down Expand Up @@ -426,7 +427,8 @@ export default function setupContext(
Object.defineProperty(context, 'set', {
configurable: true,
enumerable: true,
value(key: string, value: unknown): unknown {
// SAFETY: in all of these `defineProperty` calls, we can't actually guarantee any safety w.r.t. the corresponding field's type in `TestContext`
value(key: any, value: any): unknown {
let ret = run(function () {
if (ComponentRenderMap.has(context)) {
assert(
Expand Down Expand Up @@ -454,7 +456,8 @@ export default function setupContext(
Object.defineProperty(context, 'setProperties', {
configurable: true,
enumerable: true,
value(hash: { [key: string]: any }): { [key: string]: any } {
// SAFETY: in all of these `defineProperty` calls, we can't actually guarantee any safety w.r.t. the corresponding field's type in `TestContext`
value(hash: any): unknown {
let ret = run(function () {
if (ComponentRenderMap.has(context)) {
assert(
Expand Down Expand Up @@ -490,13 +493,14 @@ export default function setupContext(
Object.defineProperty(context, 'getProperties', {
configurable: true,
enumerable: true,
value(...args: string[]): Pick<BaseContext, string> {
// SAFETY: in all of these `defineProperty` calls, we can't actually guarantee any safety w.r.t. the corresponding field's type in `TestContext`
value(...args: any[]): Record<string, unknown> {
return getProperties(context, args);
},
writable: false,
});

let resume: ((value?: unknown) => void) | undefined;
let resume: ((value?: void | PromiseLike<void>) => void) | undefined;
context['resumeTest'] = function resumeTest() {
assert(
'Testing has not been paused. There is nothing to resume.',
Expand All @@ -517,6 +521,6 @@ export default function setupContext(

_setupAJAXHooks();

return context as TestContext;
return context;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ export interface RenderingTestContext extends TestContext {
export function isRenderingTestContext(
context: BaseContext
): context is RenderingTestContext {
let maybeContext = context as Partial<RenderingTestContext>;
return (
isTestContext(context) &&
typeof context['render'] === 'function' &&
typeof context['clearRender'] === 'function'
typeof maybeContext['render'] === 'function' &&
typeof maybeContext['clearRender'] === 'function'
);
}

Expand Down

0 comments on commit 6675e10

Please sign in to comment.