Skip to content

Commit cfeffeb

Browse files
committed
refactor: enable strict mode
1 parent 4e766d1 commit cfeffeb

File tree

4 files changed

+50
-35
lines changed

4 files changed

+50
-35
lines changed

projects/testing-library/.eslintrc.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22
"extends": "../../.eslintrc.json",
33
"ignorePatterns": ["!**/*"],
44
"overrides": [
5+
{
6+
"files": ["*.ts"],
7+
"rules": {
8+
"@typescript-eslint/ban-ts-comment": "off"
9+
}
10+
},
511
{
612
"files": ["*.ts"],
713
"extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
814
"parserOptions": {
915
"project": ["projects/testing-library/tsconfig.*?.json"]
1016
},
1117
"rules": {
18+
"@typescript-eslint/ban-ts-comment": "off",
1219
"@angular-eslint/directive-selector": [
1320
"error",
1421
{

projects/testing-library/src/lib/models.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,8 @@ export interface RenderTemplateOptions<WrapperType, Properties extends object =
268268
* `WrapperComponent`, an empty component that strips the `ng-version` attribute
269269
*
270270
* @example
271-
* const component = await render(SpoilerDirective, {
272-
* template: `<div spoiler message='SPOILER'></div>`
271+
* const component = await render(`<div spoiler message='SPOILER'></div>`, {
272+
* declarations: [SpoilerDirective]
273273
* wrapper: CustomWrapperComponent
274274
* })
275275
*/

projects/testing-library/src/lib/testing-library.ts

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ export async function render<SutType, WrapperType = SutType>(
5353
providers = [],
5454
schemas = [],
5555
queries,
56-
template = undefined,
57-
wrapper = WrapperComponent,
56+
wrapper = WrapperComponent as Type<WrapperType>,
5857
componentProperties = {},
5958
componentProviders = [],
6059
excludeComponentDeclaration = false,
@@ -89,13 +88,13 @@ export async function render<SutType, WrapperType = SutType>(
8988
await TestBed.compileComponents();
9089

9190
componentProviders
92-
.reduce((acc, provider) => acc.concat(provider), [])
93-
.forEach((p) => {
91+
.reduce((acc, provider) => acc.concat(provider), [] as any[])
92+
.forEach((p: any) => {
9493
const { provide, ...provider } = p;
9594
TestBed.overrideProvider(provide, provider);
9695
});
9796

98-
const componentContainer = createComponentFixture(sut, { wrapper });
97+
const componentContainer = createComponentFixture(sut, wrapper);
9998

10099
let fixture: ComponentFixture<SutType>;
101100
let detectChanges: () => void;
@@ -120,7 +119,7 @@ export async function render<SutType, WrapperType = SutType>(
120119

121120
let router = routes ? inject(Router) : null;
122121
const zone = inject(NgZone);
123-
const navigate = async (elementOrPath: Element | string, basePath = '') => {
122+
const navigate = async (elementOrPath: Element | string, basePath = ''): Promise<boolean> => {
124123
if (!router) {
125124
router = inject(Router);
126125
}
@@ -139,16 +138,18 @@ export async function render<SutType, WrapperType = SutType>(
139138
qp[key] = [currentValue, value];
140139
}
141140
return qp;
142-
}, {})
141+
}, {} as Record<string, string | string[]>)
143142
: undefined;
144143

145-
const navigateOptions: NavigationExtras = queryParams
144+
const navigateOptions: NavigationExtras | undefined = queryParams
146145
? {
147146
queryParams,
148147
}
149148
: undefined;
150149

151-
const doNavigate = () => (navigateOptions ? router.navigate([path], navigateOptions) : router.navigate([path]));
150+
const doNavigate = () => {
151+
return navigateOptions ? router?.navigate([path], navigateOptions) : router?.navigate([path]);
152+
};
152153

153154
let result;
154155

@@ -159,21 +160,25 @@ export async function render<SutType, WrapperType = SutType>(
159160
}
160161

161162
detectChanges();
162-
return result;
163+
return result ?? false;
163164
};
164165

165166
return {
167+
// @ts-ignore: fixture assigned
166168
fixture,
167169
detectChanges: () => detectChanges(),
168170
navigate,
169171
rerender,
170172
change,
173+
// @ts-ignore: fixture assigned
171174
debugElement: typeof sut === 'string' ? fixture.debugElement : fixture.debugElement.query(By.directive(sut)),
175+
// @ts-ignore: fixture assigned
172176
container: fixture.nativeElement,
173177
debug: (element = fixture.nativeElement, maxLength, options) =>
174178
Array.isArray(element)
175179
? element.forEach((e) => console.log(dtlPrettyDOM(e, maxLength, options)))
176180
: console.log(dtlPrettyDOM(element, maxLength, options)),
181+
// @ts-ignore: fixture assigned
177182
...replaceFindWithFindAndDetectChanges(dtlGetQueriesForElement(fixture.nativeElement, queries)),
178183
};
179184

@@ -220,9 +225,9 @@ async function createComponent<SutType>(component: Type<SutType>): Promise<Compo
220225
return TestBed.createComponent(component);
221226
}
222227

223-
function createComponentFixture<SutType>(
228+
function createComponentFixture<SutType, WrapperType>(
224229
sut: Type<SutType> | string,
225-
{ wrapper }: Pick<RenderTemplateOptions<SutType>, 'wrapper'>,
230+
wrapper: Type<WrapperType>,
226231
): Type<any> {
227232
if (typeof sut === 'string') {
228233
TestBed.overrideTemplate(wrapper, sut);
@@ -236,13 +241,13 @@ function setComponentProperties<SutType>(
236241
{ componentProperties = {} }: Pick<RenderTemplateOptions<SutType, any>, 'componentProperties'>,
237242
) {
238243
for (const key of Object.keys(componentProperties)) {
239-
const descriptor: PropertyDescriptor = Object.getOwnPropertyDescriptor(
240-
fixture.componentInstance.constructor.prototype,
244+
const descriptor = Object.getOwnPropertyDescriptor(
245+
(fixture.componentInstance as any).constructor.prototype,
241246
key,
242247
);
243248
let _value = componentProperties[key];
244249
const defaultGetter = () => _value;
245-
const extendedSetter = (value) => {
250+
const extendedSetter = (value:any) => {
246251
_value = value;
247252
descriptor?.set?.call(fixture.componentInstance, _value);
248253
fixture.detectChanges();
@@ -268,21 +273,21 @@ function hasOnChangesHook<SutType>(componentInstance: SutType): componentInstanc
268273
);
269274
}
270275

271-
function getChangesObj<SutType>(oldProps: Partial<SutType> | null, newProps: Partial<SutType>) {
276+
function getChangesObj<SutType extends Record<string, any>>(oldProps: Partial<SutType> | null, newProps: Partial<SutType>) {
272277
const isFirstChange = oldProps === null;
273278
return Object.keys(newProps).reduce<SimpleChanges>(
274279
(changes, key) => ({
275280
...changes,
276281
[key]: new SimpleChange(isFirstChange ? null : oldProps[key], newProps[key], isFirstChange),
277282
}),
278-
{},
283+
{} as SutType,
279284
);
280285
}
281286

282287
function addAutoDeclarations<SutType>(
283288
sut: Type<SutType> | string,
284289
{
285-
declarations,
290+
declarations = [],
286291
excludeComponentDeclaration,
287292
wrapper,
288293
}: Pick<RenderTemplateOptions<any>, 'declarations' | 'excludeComponentDeclaration' | 'wrapper'>,
@@ -295,7 +300,7 @@ function addAutoDeclarations<SutType>(
295300
return [...declarations, ...components()];
296301
}
297302

298-
function addAutoImports({ imports, routes }: Pick<RenderComponentOptions<any>, 'imports' | 'routes'>) {
303+
function addAutoImports({ imports = [], routes }: Pick<RenderComponentOptions<any>, 'imports' | 'routes'>) {
299304
const animations = () => {
300305
const animationIsDefined =
301306
imports.indexOf(NoopAnimationsModule) > -1 || imports.indexOf(BrowserAnimationsModule) > -1;
@@ -341,19 +346,19 @@ async function waitForElementToBeRemovedWrapper<T>(
341346
callback: (() => T) | T,
342347
options?: dtlWaitForOptions,
343348
): Promise<void> {
344-
let cb;
349+
let cb: (() => T)
345350
if (typeof callback !== 'function') {
346351
const elements = (Array.isArray(callback) ? callback : [callback]) as Element[];
347352
const getRemainingElements = elements.map((element) => {
348-
let parent = element.parentElement;
353+
let parent = element.parentElement as Element
349354
while (parent.parentElement) {
350355
parent = parent.parentElement;
351356
}
352357
return () => (parent.contains(element) ? element : null);
353358
});
354-
cb = () => getRemainingElements.map((c) => c()).filter(Boolean);
359+
cb = () => getRemainingElements.map((c) => c()).find(Boolean) as unknown as T;
355360
} else {
356-
cb = callback;
361+
cb = callback as (() => T);
357362
}
358363

359364
return await dtlWaitForElementToBeRemoved(() => {
@@ -367,7 +372,7 @@ function cleanup() {
367372
mountedFixtures.forEach(cleanupAtFixture);
368373
}
369374

370-
function cleanupAtFixture(fixture) {
375+
function cleanupAtFixture(fixture: ComponentFixture<any>) {
371376
fixture.destroy();
372377

373378
if (!fixture.nativeElement.getAttribute('ng-version') && fixture.nativeElement.parentNode === document.body) {
@@ -394,25 +399,25 @@ class WrapperComponent {}
394399
/**
395400
* Wrap findBy queries to poke the Angular change detection cycle
396401
*/
397-
function replaceFindWithFindAndDetectChanges<T>(originalQueriesForContainer: T): T {
402+
function replaceFindWithFindAndDetectChanges<T extends Record<string,any>>(originalQueriesForContainer: T): T {
398403
return Object.keys(originalQueriesForContainer).reduce((newQueries, key) => {
399404
const getByQuery = originalQueriesForContainer[key.replace('find', 'get')];
400405
if (key.startsWith('find') && getByQuery) {
401-
newQueries[key] = async (text, options, waitOptions) => {
406+
newQueries[key ] = async (...queryOptions: any[]) => {
407+
const waitOptions = queryOptions.pop()
402408
// original implementation at https://github.com/testing-library/dom-testing-library/blob/main/src/query-helpers.js
403-
const result = await waitForWrapper(
409+
return await waitForWrapper(
404410
detectChangesForMountedFixtures,
405-
() => getByQuery(text, options),
411+
() => getByQuery(...queryOptions),
406412
waitOptions,
407413
);
408-
return result;
409414
};
410415
} else {
411416
newQueries[key] = originalQueriesForContainer[key];
412417
}
413418

414419
return newQueries;
415-
}, {} as T);
420+
}, {} as Record<string,any>) as T;
416421
}
417422

418423
/**
@@ -422,7 +427,7 @@ function detectChangesForMountedFixtures() {
422427
mountedFixtures.forEach((fixture) => {
423428
try {
424429
fixture.detectChanges();
425-
} catch (err) {
430+
} catch (err: any) {
426431
if (!err.message.startsWith('ViewDestroyedError')) {
427432
throw err;
428433
}

tsconfig.base.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
"sourceMap": true,
1414
"target": "es2015",
1515
"typeRoots": ["node_modules/@types"],
16-
"forceConsistentCasingInFileNames": true,
17-
"noImplicitReturns": true,
16+
"strict": true,
1817
"noFallthroughCasesInSwitch": true,
18+
"noImplicitReturns": true,
19+
"noUnusedLocals": true,
20+
"noUnusedParameters": true,
21+
"forceConsistentCasingInFileNames": true,
1922
"paths": {
2023
"@testing-library/angular": ["projects/testing-library"],
2124
"@testing-library/angular/jest-utils": ["projects/jest-utils"]

0 commit comments

Comments
 (0)