diff --git a/apps/example-app-karma/eslint.config.mjs b/apps/example-app-karma/eslint.config.mjs index 8f627dbf..bd9b42bf 100644 --- a/apps/example-app-karma/eslint.config.mjs +++ b/apps/example-app-karma/eslint.config.mjs @@ -1,8 +1,6 @@ // @ts-check -import tseslint from "typescript-eslint"; -import rootConfig from "../../eslint.config.mjs"; +import tseslint from 'typescript-eslint'; +import rootConfig from '../../eslint.config.mjs'; -export default tseslint.config( - ...rootConfig, -); +export default tseslint.config(...rootConfig); diff --git a/apps/example-app-karma/src/app/examples/login-form.spec.ts b/apps/example-app-karma/src/app/examples/login-form.spec.ts index a0282341..d019e069 100644 --- a/apps/example-app-karma/src/app/examples/login-form.spec.ts +++ b/apps/example-app-karma/src/app/examples/login-form.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; import userEvent from '@testing-library/user-event'; import { render, screen } from '@testing-library/angular'; @@ -45,13 +45,13 @@ it('should display invalid message and submit button must be disabled', async () `, }) class LoginComponent { + private fb = inject(FormBuilder); + form: FormGroup = this.fb.group({ email: ['', [Validators.required, Validators.email]], password: ['', [Validators.required, Validators.minLength(8)]], }); - constructor(private fb: FormBuilder) {} - get email(): FormControl { return this.form.get('email') as FormControl; } diff --git a/apps/example-app-karma/src/app/issues/issue-491.spec.ts b/apps/example-app-karma/src/app/issues/issue-491.spec.ts index 9320251e..9c967710 100644 --- a/apps/example-app-karma/src/app/issues/issue-491.spec.ts +++ b/apps/example-app-karma/src/app/issues/issue-491.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { Router } from '@angular/router'; import { render, screen } from '@testing-library/angular'; import userEvent from '@testing-library/user-event'; @@ -43,7 +43,7 @@ it('test click event with router.navigate', async () => { `, }) class LoginComponent { - constructor(private router: Router) {} + private readonly router = inject(Router); onSubmit(): void { this.router.navigate(['logged-in']); } diff --git a/apps/example-app/eslint.config.mjs b/apps/example-app/eslint.config.mjs index 01625848..bd9b42bf 100644 --- a/apps/example-app/eslint.config.mjs +++ b/apps/example-app/eslint.config.mjs @@ -1,8 +1,6 @@ // @ts-check -import tseslint from "typescript-eslint"; -import rootConfig from "../../eslint.config.mjs"; +import tseslint from 'typescript-eslint'; +import rootConfig from '../../eslint.config.mjs'; -export default tseslint.config( - ...rootConfig, -); \ No newline at end of file +export default tseslint.config(...rootConfig); diff --git a/apps/example-app/src/app/examples/03-forms.ts b/apps/example-app/src/app/examples/03-forms.ts index a62d8650..c1e48c23 100644 --- a/apps/example-app/src/app/examples/03-forms.ts +++ b/apps/example-app/src/app/examples/03-forms.ts @@ -1,5 +1,5 @@ import { NgForOf, NgIf } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; @Component({ @@ -33,6 +33,8 @@ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; `, }) export class FormsComponent { + private formBuilder = inject(FormBuilder); + colors = [ { id: 'R', value: 'Red' }, { id: 'B', value: 'Blue' }, @@ -45,8 +47,6 @@ export class FormsComponent { color: [null as string | null, Validators.required], }); - constructor(private formBuilder: FormBuilder) {} - get formErrors() { return Object.keys(this.form.controls) .map((formKey) => { diff --git a/apps/example-app/src/app/examples/04-forms-with-material.ts b/apps/example-app/src/app/examples/04-forms-with-material.ts index cf117a51..2376c725 100644 --- a/apps/example-app/src/app/examples/04-forms-with-material.ts +++ b/apps/example-app/src/app/examples/04-forms-with-material.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; import { NgForOf, NgIf } from '@angular/common'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -84,6 +84,8 @@ import { MatNativeDateModule } from '@angular/material/core'; ], }) export class MaterialFormsComponent { + private formBuilder = inject(FormBuilder); + colors = [ { id: 'R', value: 'Red' }, { id: 'B', value: 'Blue' }, @@ -97,8 +99,6 @@ export class MaterialFormsComponent { agree: [false, Validators.requiredTrue], }); - constructor(private formBuilder: FormBuilder) {} - get colorControlDisplayValue(): string | undefined { const selectedId = this.form.get('color')?.value; return this.colors.filter((color) => color.id === selectedId)[0]?.value; diff --git a/apps/example-app/src/app/examples/05-component-provider.ts b/apps/example-app/src/app/examples/05-component-provider.ts index 2d66b070..c6162e0b 100644 --- a/apps/example-app/src/app/examples/05-component-provider.ts +++ b/apps/example-app/src/app/examples/05-component-provider.ts @@ -1,4 +1,4 @@ -import { Component, Injectable } from '@angular/core'; +import { Component, inject, Injectable } from '@angular/core'; @Injectable({ providedIn: 'root', @@ -30,5 +30,5 @@ export class CounterService { providers: [CounterService], }) export class ComponentWithProviderComponent { - constructor(public counter: CounterService) {} + protected counter = inject(CounterService); } diff --git a/apps/example-app/src/app/examples/06-with-ngrx-store.ts b/apps/example-app/src/app/examples/06-with-ngrx-store.ts index 8702843c..f478e528 100644 --- a/apps/example-app/src/app/examples/06-with-ngrx-store.ts +++ b/apps/example-app/src/app/examples/06-with-ngrx-store.ts @@ -1,5 +1,5 @@ import { AsyncPipe } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { createSelector, Store, createAction, createReducer, on, select } from '@ngrx/store'; const increment = createAction('increment'); @@ -26,8 +26,9 @@ const selectValue = createSelector( `, }) export class WithNgRxStoreComponent { + private store = inject(Store); + value = this.store.pipe(select(selectValue)); - constructor(private store: Store) {} increment() { this.store.dispatch(increment()); diff --git a/apps/example-app/src/app/examples/07-with-ngrx-mock-store.ts b/apps/example-app/src/app/examples/07-with-ngrx-mock-store.ts index 915a88d8..0bd5d864 100644 --- a/apps/example-app/src/app/examples/07-with-ngrx-mock-store.ts +++ b/apps/example-app/src/app/examples/07-with-ngrx-mock-store.ts @@ -1,5 +1,5 @@ import { AsyncPipe, NgForOf } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { createSelector, Store, select } from '@ngrx/store'; export const selectItems = createSelector( @@ -20,8 +20,9 @@ export const selectItems = createSelector( `, }) export class WithNgRxMockStoreComponent { + private store = inject(Store); + items = this.store.pipe(select(selectItems)); - constructor(private store: Store) {} send(item: string) { this.store.dispatch({ type: '[Item List] send', item }); diff --git a/apps/example-app/src/app/examples/08-directive.ts b/apps/example-app/src/app/examples/08-directive.ts index 63efe415..d6cd631c 100644 --- a/apps/example-app/src/app/examples/08-directive.ts +++ b/apps/example-app/src/app/examples/08-directive.ts @@ -1,15 +1,15 @@ -import { Directive, HostListener, ElementRef, Input, OnInit } from '@angular/core'; +import { Directive, HostListener, ElementRef, Input, OnInit, inject } from '@angular/core'; @Directive({ standalone: true, selector: '[atlSpoiler]', }) export class SpoilerDirective implements OnInit { + private el = inject(ElementRef); + @Input() hidden = 'SPOILER'; @Input() visible = 'I am visible now...'; - constructor(private el: ElementRef) {} - ngOnInit() { this.el.nativeElement.textContent = this.hidden; } diff --git a/apps/example-app/src/app/examples/09-router.ts b/apps/example-app/src/app/examples/09-router.ts index e46773be..f29a4efe 100644 --- a/apps/example-app/src/app/examples/09-router.ts +++ b/apps/example-app/src/app/examples/09-router.ts @@ -1,5 +1,5 @@ import { AsyncPipe } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { ActivatedRoute, RouterLink, RouterOutlet } from '@angular/router'; import { map } from 'rxjs/operators'; @@ -32,10 +32,10 @@ export class RootComponent {} `, }) export class DetailComponent { + private route = inject(ActivatedRoute); id = this.route.paramMap.pipe(map((params) => params.get('id'))); text = this.route.queryParams.pipe(map((params) => params['text'])); subtext = this.route.queryParams.pipe(map((params) => params['subtext'])); - constructor(private route: ActivatedRoute) {} } @Component({ diff --git a/apps/example-app/src/app/examples/10-inject-token-dependency.ts b/apps/example-app/src/app/examples/10-inject-token-dependency.ts index f7b2f661..5cd60498 100644 --- a/apps/example-app/src/app/examples/10-inject-token-dependency.ts +++ b/apps/example-app/src/app/examples/10-inject-token-dependency.ts @@ -1,4 +1,4 @@ -import { Component, InjectionToken, Inject } from '@angular/core'; +import { Component, InjectionToken, inject } from '@angular/core'; export const DATA = new InjectionToken<{ text: string }>('Components Data'); @@ -8,5 +8,5 @@ export const DATA = new InjectionToken<{ text: string }>('Components Data'); template: ' {{ data.text }} ', }) export class DataInjectedComponent { - constructor(@Inject(DATA) public data: { text: string }) {} + protected data = inject(DATA); } diff --git a/apps/example-app/src/app/examples/12-service-component.ts b/apps/example-app/src/app/examples/12-service-component.ts index 1746eb2c..f1b848ba 100644 --- a/apps/example-app/src/app/examples/12-service-component.ts +++ b/apps/example-app/src/app/examples/12-service-component.ts @@ -1,5 +1,5 @@ import { AsyncPipe, NgForOf } from '@angular/common'; -import { Component, Injectable } from '@angular/core'; +import { Component, inject, Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; export class Customer { @@ -29,6 +29,6 @@ export class CustomersService { `, }) export class CustomersComponent { + private service = inject(CustomersService); customers$ = this.service.load(); - constructor(private service: CustomersService) {} } diff --git a/apps/example-app/src/app/examples/15-dialog.component.spec.ts b/apps/example-app/src/app/examples/15-dialog.component.spec.ts index df172be8..51f8fb04 100644 --- a/apps/example-app/src/app/examples/15-dialog.component.spec.ts +++ b/apps/example-app/src/app/examples/15-dialog.component.spec.ts @@ -1,5 +1,5 @@ import { MatDialogRef } from '@angular/material/dialog'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { provideNoopAnimations } from '@angular/platform-browser/animations'; import { render, screen } from '@testing-library/angular'; import userEvent from '@testing-library/user-event'; @@ -10,8 +10,8 @@ test('dialog closes', async () => { const closeFn = jest.fn(); await render(DialogContentComponent, { - imports: [NoopAnimationsModule], providers: [ + provideNoopAnimations(), { provide: MatDialogRef, useValue: { @@ -31,7 +31,7 @@ test('closes the dialog via the backdrop', async () => { const user = userEvent.setup(); await render(DialogComponent, { - imports: [NoopAnimationsModule], + providers: [provideNoopAnimations()], }); const openDialogButton = await screen.findByRole('button', { name: /open dialog/i }); @@ -55,7 +55,7 @@ test('opens and closes the dialog with buttons', async () => { const user = userEvent.setup(); await render(DialogComponent, { - imports: [NoopAnimationsModule], + providers: [provideNoopAnimations()], }); const openDialogButton = await screen.findByRole('button', { name: /open dialog/i }); diff --git a/apps/example-app/src/app/examples/15-dialog.component.ts b/apps/example-app/src/app/examples/15-dialog.component.ts index 029ee64e..ce951f23 100644 --- a/apps/example-app/src/app/examples/15-dialog.component.ts +++ b/apps/example-app/src/app/examples/15-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; @Component({ @@ -8,7 +8,7 @@ import { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dial template: '', }) export class DialogComponent { - constructor(public dialog: MatDialog) {} + private dialog = inject(MatDialog); openDialog(): void { this.dialog.open(DialogContentComponent); @@ -29,7 +29,7 @@ export class DialogComponent { `, }) export class DialogContentComponent { - constructor(public dialogRef: MatDialogRef) {} + private dialogRef = inject>(MatDialogRef); cancel(): void { this.dialogRef.close(); diff --git a/apps/example-app/src/app/examples/16-input-getter-setter.ts b/apps/example-app/src/app/examples/16-input-getter-setter.ts index 4c189000..9d0654d3 100644 --- a/apps/example-app/src/app/examples/16-input-getter-setter.ts +++ b/apps/example-app/src/app/examples/16-input-getter-setter.ts @@ -8,7 +8,6 @@ import { Component, Input } from '@angular/core'; {{ value }} `, }) -// eslint-disable-next-line @angular-eslint/component-class-suffix export class InputGetterSetter { @Input() set value(value: string) { this.originalValue = value; diff --git a/apps/example-app/src/app/examples/20-test-harness.ts b/apps/example-app/src/app/examples/20-test-harness.ts index 8e5e4071..0ecb7b35 100644 --- a/apps/example-app/src/app/examples/20-test-harness.ts +++ b/apps/example-app/src/app/examples/20-test-harness.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; @@ -11,7 +11,7 @@ import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; `, }) export class HarnessComponent { - constructor(private snackBar: MatSnackBar) {} + private snackBar = inject(MatSnackBar); openSnackBar() { return this.snackBar.open('Pizza Party!!!'); diff --git a/apps/example-app/src/app/examples/23-host-directive.ts b/apps/example-app/src/app/examples/23-host-directive.ts index 3e201c75..3d27f788 100644 --- a/apps/example-app/src/app/examples/23-host-directive.ts +++ b/apps/example-app/src/app/examples/23-host-directive.ts @@ -1,13 +1,12 @@ -import { Component, Directive, ElementRef, input, OnInit } from '@angular/core'; +import { Component, Directive, ElementRef, inject, input, OnInit } from '@angular/core'; @Directive({ selector: '[atlText]', }) export class TextDirective implements OnInit { + private el = inject(ElementRef); atlText = input(''); - constructor(private el: ElementRef) {} - ngOnInit() { this.el.nativeElement.textContent = this.atlText(); } diff --git a/eslint.config.mjs b/eslint.config.mjs index 95e031ac..f61ad778 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,14 +1,14 @@ // @ts-check -import eslint from "@eslint/js"; -import tseslint from "typescript-eslint"; -import angular from "angular-eslint"; +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import angular from 'angular-eslint'; import jestDom from 'eslint-plugin-jest-dom'; import testingLibrary from 'eslint-plugin-testing-library'; export default tseslint.config( { - files: ["**/*.ts"], + files: ['**/*.ts'], extends: [ eslint.configs.recommended, ...tseslint.configs.recommended, @@ -17,50 +17,44 @@ export default tseslint.config( ], processor: angular.processInlineTemplates, rules: { - "@angular-eslint/directive-selector": [ - "error", + '@angular-eslint/directive-selector': [ + 'error', { - type: "attribute", - prefix: "atl", - style: "camelCase", + type: 'attribute', + prefix: 'atl', + style: 'camelCase', }, ], - "@angular-eslint/component-selector": [ - "error", + '@angular-eslint/component-selector': [ + 'error', { - type: "element", - prefix: "atl", - style: "kebab-case", + type: 'element', + prefix: 'atl', + style: 'kebab-case', }, ], - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-unused-vars": [ - "error", + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', { - "argsIgnorePattern": "^_", - "varsIgnorePattern": "^_", - "caughtErrorsIgnorePattern": "^_" - } + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, ], // These are needed for test cases - "@angular-eslint/prefer-standalone": "off", - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-input-rename": "off", + '@angular-eslint/prefer-standalone': 'off', + '@angular-eslint/no-input-rename': 'off', + '@angular-eslint/no-input-rename': 'off', }, }, { - files: ["**/*.spec.ts"], - extends: [ - jestDom.configs["flat/recommended"], - testingLibrary.configs["flat/angular"], - ], - }, + files: ['**/*.spec.ts'], + extends: [jestDom.configs['flat/recommended'], testingLibrary.configs['flat/angular']], + }, { - files: ["**/*.html"], - extends: [ - ...angular.configs.templateRecommended, - ...angular.configs.templateAccessibility, - ], + files: ['**/*.html'], + extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility], rules: {}, - } + }, ); diff --git a/package.json b/package.json index 38883955..341eb0f5 100644 --- a/package.json +++ b/package.json @@ -27,53 +27,53 @@ "prepare": "git config core.hookspath .githooks" }, "dependencies": { - "@angular/animations": "20.0.0", - "@angular/cdk": "20.0.0", - "@angular/common": "20.0.0", - "@angular/compiler": "20.0.0", - "@angular/core": "20.0.0", - "@angular/material": "20.0.0", - "@angular/platform-browser": "20.0.0", - "@angular/platform-browser-dynamic": "20.0.0", - "@angular/router": "20.0.0", - "@ngrx/store": "19.0.0", - "@nx/angular": "21.1.2", + "@angular/animations": "20.1.7", + "@angular/cdk": "20.1.6", + "@angular/common": "20.1.7", + "@angular/compiler": "20.1.7", + "@angular/core": "20.1.7", + "@angular/material": "20.1.6", + "@angular/platform-browser": "20.1.7", + "@angular/platform-browser-dynamic": "20.1.7", + "@angular/router": "20.1.7", + "@ngrx/store": "20.0.0", + "@nx/angular": "21.3.11", "@testing-library/dom": "^10.4.0", "rxjs": "7.8.0", "tslib": "~2.8.1", "zone.js": "^0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "20.0.0", - "@angular-devkit/core": "20.0.0", - "@angular-devkit/schematics": "20.0.0", - "@angular-eslint/builder": "19.2.0", - "@angular-eslint/eslint-plugin": "19.2.0", - "@angular-eslint/eslint-plugin-template": "19.2.0", - "@angular-eslint/schematics": "19.2.0", - "@angular-eslint/template-parser": "19.2.0", + "@angular-devkit/build-angular": "20.1.6", + "@angular-devkit/core": "20.1.6", + "@angular-devkit/schematics": "20.1.6", + "@angular-eslint/builder": "20.0.0", + "@angular-eslint/eslint-plugin": "20.0.0", + "@angular-eslint/eslint-plugin-template": "20.0.0", + "@angular-eslint/schematics": "20.0.0", + "@angular-eslint/template-parser": "20.0.0", "@angular/cli": "~20.0.0", - "@angular/compiler-cli": "20.0.0", - "@angular/forms": "20.0.0", - "@angular/language-service": "20.0.0", + "@angular/compiler-cli": "20.1.7", + "@angular/forms": "20.1.7", + "@angular/language-service": "20.1.7", "@eslint/eslintrc": "^2.1.1", - "@nx/eslint": "21.1.2", - "@nx/eslint-plugin": "21.1.2", - "@nx/jest": "21.1.2", - "@nx/node": "21.1.2", - "@nx/plugin": "21.1.2", - "@nx/workspace": "21.1.2", - "@schematics/angular": "20.0.0", + "@nx/eslint": "21.3.11", + "@nx/eslint-plugin": "21.3.11", + "@nx/jest": "21.3.11", + "@nx/node": "21.3.11", + "@nx/plugin": "21.3.11", + "@nx/workspace": "21.3.11", + "@schematics/angular": "20.1.6", "@testing-library/jasmine-dom": "^1.3.3", "@testing-library/jest-dom": "^6.6.3", "@testing-library/user-event": "^14.5.2", "@types/jasmine": "4.3.1", - "@types/jest": "29.5.14", + "@types/jest": "30.0.0", "@types/node": "22.10.1", "@types/testing-library__jasmine-dom": "^1.3.4", "@typescript-eslint/types": "^8.19.0", "@typescript-eslint/utils": "^8.19.0", - "angular-eslint": "19.2.0", + "angular-eslint": "20.0.0", "autoprefixer": "^10.4.20", "cpy-cli": "^5.0.0", "eslint": "^9.8.0", @@ -81,9 +81,9 @@ "eslint-plugin-testing-library": "~7.1.1", "jasmine-core": "4.2.0", "jasmine-spec-reporter": "7.0.0", - "jest": "29.7.0", - "jest-environment-jsdom": "29.7.0", - "jest-preset-angular": "14.4.2", + "jest": "30.0.5", + "jest-environment-jsdom": "30.0.5", + "jest-preset-angular": "15.0.0", "karma": "6.4.0", "karma-chrome-launcher": "^3.2.0", "karma-coverage": "^2.2.1", @@ -91,8 +91,8 @@ "karma-jasmine-html-reporter": "2.0.0", "lint-staged": "^15.3.0", "ng-mocks": "^14.13.1", - "ng-packagr": "20.0.0", - "nx": "21.1.2", + "ng-packagr": "20.1.0", + "nx": "21.3.11", "postcss": "^8.4.49", "postcss-import": "14.1.0", "postcss-preset-env": "7.5.0", @@ -100,9 +100,10 @@ "prettier": "2.6.2", "rimraf": "^5.0.10", "semantic-release": "^24.2.1", - "ts-jest": "29.1.0", + "ts-jest": "29.4.1", "ts-node": "10.9.1", "typescript": "5.8.2", - "typescript-eslint": "^8.19.0" + "typescript-eslint": "^8.19.0", + "jest-util": "30.0.5" } } diff --git a/projects/testing-library/eslint.config.mjs b/projects/testing-library/eslint.config.mjs index 8f627dbf..bd9b42bf 100644 --- a/projects/testing-library/eslint.config.mjs +++ b/projects/testing-library/eslint.config.mjs @@ -1,8 +1,6 @@ // @ts-check -import tseslint from "typescript-eslint"; -import rootConfig from "../../eslint.config.mjs"; +import tseslint from 'typescript-eslint'; +import rootConfig from '../../eslint.config.mjs'; -export default tseslint.config( - ...rootConfig, -); +export default tseslint.config(...rootConfig); diff --git a/projects/testing-library/jest-utils/tests/create-mock.spec.ts b/projects/testing-library/jest-utils/tests/create-mock.spec.ts index 2393fe30..60917b35 100644 --- a/projects/testing-library/jest-utils/tests/create-mock.spec.ts +++ b/projects/testing-library/jest-utils/tests/create-mock.spec.ts @@ -21,7 +21,7 @@ class FixtureService { template: ` `, }) class FixtureComponent { - constructor(private service: FixtureService) {} + private service = inject(FixtureService); print() { this.service.print(); diff --git a/projects/testing-library/tests/config.spec.ts b/projects/testing-library/tests/config.spec.ts index 041d991a..e2d07cb8 100644 --- a/projects/testing-library/tests/config.spec.ts +++ b/projects/testing-library/tests/config.spec.ts @@ -16,11 +16,10 @@ import { ReactiveFormsModule, FormBuilder } from '@angular/forms'; standalone: false, }) class FormsComponent { + private formBuilder = inject(FormBuilder); form = this.formBuilder.group({ name: [''], }); - - constructor(private formBuilder: FormBuilder) {} } let originalConfig: Config; diff --git a/projects/testing-library/tests/integration.spec.ts b/projects/testing-library/tests/integration.spec.ts index 02ca2902..70d0169c 100644 --- a/projects/testing-library/tests/integration.spec.ts +++ b/projects/testing-library/tests/integration.spec.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Injectable, Input, Output } from '@angular/core'; +import { Component, EventEmitter, inject, Injectable, Input, Output } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { of, BehaviorSubject } from 'rxjs'; import { debounceTime, switchMap, map, startWith } from 'rxjs/operators'; @@ -54,6 +54,8 @@ class TableComponent { imports: [TableComponent, AsyncPipe], }) class EntitiesComponent { + private entitiesService = inject(EntitiesService); + private modalService = inject(ModalService); query = new BehaviorSubject(''); readonly entities = this.query.pipe( debounceTime(DEBOUNCE_TIME), @@ -63,8 +65,6 @@ class EntitiesComponent { startWith(entities), ); - constructor(private entitiesService: EntitiesService, private modalService: ModalService) {} - newEntityClicked() { this.modalService.open('new entity'); } diff --git a/projects/testing-library/tests/issues/issue-280.spec.ts b/projects/testing-library/tests/issues/issue-280.spec.ts index 711cbec3..ea230e78 100644 --- a/projects/testing-library/tests/issues/issue-280.spec.ts +++ b/projects/testing-library/tests/issues/issue-280.spec.ts @@ -1,5 +1,5 @@ import { Location } from '@angular/common'; -import { Component, NgModule } from '@angular/core'; +import { Component, inject, NgModule } from '@angular/core'; import { RouterLink, RouterModule, RouterOutlet, Routes } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import userEvent from '@testing-library/user-event'; @@ -24,7 +24,7 @@ class FirstComponent {} `, }) class SecondComponent { - constructor(private location: Location) {} + private location = inject(Location); goBack() { this.location.back(); } diff --git a/projects/testing-library/tests/issues/issue-318.spec.ts b/projects/testing-library/tests/issues/issue-318.spec.ts index 3f1430e8..1cfe5b85 100644 --- a/projects/testing-library/tests/issues/issue-318.spec.ts +++ b/projects/testing-library/tests/issues/issue-318.spec.ts @@ -1,21 +1,20 @@ -import {Component, OnDestroy, OnInit} from '@angular/core'; -import {Router} from '@angular/router'; -import {RouterTestingModule} from '@angular/router/testing'; -import {Subject, takeUntil} from 'rxjs'; -import {render} from "@testing-library/angular"; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; +import { Subject, takeUntil } from 'rxjs'; +import { render } from '@testing-library/angular'; @Component({ selector: 'atl-app-fixture', template: '', }) class FixtureComponent implements OnInit, OnDestroy { + private readonly router = inject(Router); unsubscribe$ = new Subject(); - constructor(private router: Router) {} - ngOnInit(): void { this.router.events.pipe(takeUntil(this.unsubscribe$)).subscribe((evt) => { - this.eventReceived(evt) + this.eventReceived(evt); }); } @@ -29,15 +28,13 @@ class FixtureComponent implements OnInit, OnDestroy { } } - test('it does not invoke router events on init', async () => { const eventReceived = jest.fn(); await render(FixtureComponent, { imports: [RouterTestingModule], componentProperties: { - eventReceived - } + eventReceived, + }, }); expect(eventReceived).not.toHaveBeenCalled(); }); - diff --git a/projects/testing-library/tests/issues/issue-397-directive-overrides-component-input.spec.ts b/projects/testing-library/tests/issues/issue-397-directive-overrides-component-input.spec.ts index c2a02a8c..c34e1304 100644 --- a/projects/testing-library/tests/issues/issue-397-directive-overrides-component-input.spec.ts +++ b/projects/testing-library/tests/issues/issue-397-directive-overrides-component-input.spec.ts @@ -1,4 +1,4 @@ -import { Component, Directive, Input, OnInit } from '@angular/core'; +import { Component, Directive, inject, Input, OnInit } from '@angular/core'; import { render, screen } from '../../src/public_api'; test('the value set in the directive constructor is overriden by the input binding', async () => { @@ -48,7 +48,8 @@ class FixtureComponent { standalone: true, }) class InputOverrideViaConstructorDirective { - constructor(private fixture: FixtureComponent) { + private readonly fixture = inject(FixtureComponent); + constructor() { this.fixture.input = 'set by directive constructor'; } } @@ -59,7 +60,7 @@ class InputOverrideViaConstructorDirective { standalone: true, }) class InputOverrideViaOnInitDirective implements OnInit { - constructor(private fixture: FixtureComponent) {} + private readonly fixture = inject(FixtureComponent); ngOnInit(): void { this.fixture.input = 'set by directive ngOnInit'; diff --git a/projects/testing-library/tests/issues/issue-422-view-already-destroyed.spec.ts b/projects/testing-library/tests/issues/issue-422-view-already-destroyed.spec.ts index c4fa7a37..d75d1d23 100644 --- a/projects/testing-library/tests/issues/issue-422-view-already-destroyed.spec.ts +++ b/projects/testing-library/tests/issues/issue-422-view-already-destroyed.spec.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef } from '@angular/core'; +import { Component, ElementRef, inject } from '@angular/core'; import { NgIf } from '@angular/common'; import { render } from '../../src/public_api'; @@ -9,8 +9,7 @@ test('declaration specific dependencies should be available for components', asy template: `
Test
`, }) class TestComponent { - // eslint-disable-next-line @typescript-eslint/no-empty-function - constructor(_elementRef: ElementRef) {} + private _el = inject(ElementRef); } await expect(async () => await render(TestComponent)).not.toThrow(); diff --git a/projects/testing-library/tests/issues/issue-435.spec.ts b/projects/testing-library/tests/issues/issue-435.spec.ts index e1e420f9..2982319b 100644 --- a/projects/testing-library/tests/issues/issue-435.spec.ts +++ b/projects/testing-library/tests/issues/issue-435.spec.ts @@ -1,6 +1,6 @@ import { CommonModule } from '@angular/common'; import { BehaviorSubject } from 'rxjs'; -import { Component, Inject, Injectable } from '@angular/core'; +import { Component, inject, Injectable } from '@angular/core'; import { screen, render } from '../../src/public_api'; // Service @@ -23,7 +23,7 @@ class DemoService { `, }) class DemoComponent { - constructor(@Inject(DemoService) public demoService: DemoService) {} + protected readonly demoService = inject(DemoService); } test('issue #435', async () => { diff --git a/projects/testing-library/tests/issues/issue-493.spec.ts b/projects/testing-library/tests/issues/issue-493.spec.ts index 5d0e1237..11210088 100644 --- a/projects/testing-library/tests/issues/issue-493.spec.ts +++ b/projects/testing-library/tests/issues/issue-493.spec.ts @@ -1,6 +1,6 @@ import { HttpClient, provideHttpClient } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, input } from '@angular/core'; +import { Component, inject, input } from '@angular/core'; import { render, screen } from '../../src/public_api'; test('succeeds', async () => { @@ -21,7 +21,6 @@ test('succeeds', async () => { template: '

{{ value() }}

', }) class DummyComponent { + private _http = inject(HttpClient); value = input.required(); - // @ts-expect-error http is unused but needed for the test - constructor(private http: HttpClient) {} } diff --git a/projects/testing-library/tests/providers/component-provider.spec.ts b/projects/testing-library/tests/providers/component-provider.spec.ts index 9290d5bd..b774064e 100644 --- a/projects/testing-library/tests/providers/component-provider.spec.ts +++ b/projects/testing-library/tests/providers/component-provider.spec.ts @@ -1,4 +1,4 @@ -import { Injectable, Provider } from '@angular/core'; +import { inject, Injectable, Provider } from '@angular/core'; import { Component } from '@angular/core'; import { render, screen } from '../../src/public_api'; @@ -73,5 +73,5 @@ class Service { providers: [Service], }) class FixtureComponent { - constructor(public service: Service) {} + protected readonly service = inject(Service); } diff --git a/projects/testing-library/tests/providers/module-provider.spec.ts b/projects/testing-library/tests/providers/module-provider.spec.ts index bd39b81b..80710291 100644 --- a/projects/testing-library/tests/providers/module-provider.spec.ts +++ b/projects/testing-library/tests/providers/module-provider.spec.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Component } from '@angular/core'; import { render, screen } from '../../src/public_api'; @@ -64,5 +64,5 @@ class Service { template: '{{service.foo()}}', }) class FixtureComponent { - constructor(public service: Service) {} + protected readonly service = inject(Service); } diff --git a/projects/testing-library/tests/render-template.spec.ts b/projects/testing-library/tests/render-template.spec.ts index e185f702..cddc28a1 100644 --- a/projects/testing-library/tests/render-template.spec.ts +++ b/projects/testing-library/tests/render-template.spec.ts @@ -1,4 +1,4 @@ -import { Directive, HostListener, ElementRef, Input, Output, EventEmitter, Component } from '@angular/core'; +import { Directive, HostListener, ElementRef, Input, Output, EventEmitter, Component, inject } from '@angular/core'; import { render, fireEvent, screen } from '../src/public_api'; @@ -7,11 +7,12 @@ import { render, fireEvent, screen } from '../src/public_api'; selector: '[onOff]', }) class OnOffDirective { + private el = inject(ElementRef); @Input() on = 'on'; @Input() off = 'off'; @Output() clicked = new EventEmitter(); - constructor(private el: ElementRef) { + constructor() { this.el.nativeElement.textContent = 'init'; } @@ -26,12 +27,11 @@ class OnOffDirective { selector: '[update]', }) class UpdateInputDirective { + private readonly el = inject(ElementRef); @Input() set update(value: any) { this.el.nativeElement.textContent = value; } - - constructor(private el: ElementRef) {} } @Component({ diff --git a/projects/testing-library/tests/render.spec.ts b/projects/testing-library/tests/render.spec.ts index a93da906..243a5e81 100644 --- a/projects/testing-library/tests/render.spec.ts +++ b/projects/testing-library/tests/render.spec.ts @@ -116,7 +116,7 @@ describe('childComponentOverrides', () => { providers: [MySimpleService], }) class NestedChildFixtureComponent { - public constructor(public simpleService: MySimpleService) {} + protected simpleService = inject(MySimpleService); } @Component({ @@ -490,7 +490,7 @@ describe('initialRoute', () => { imports: [NgIf, AsyncPipe], }) class QueryParamFixtureComponent { - constructor(public route: ActivatedRoute) {} + private readonly route = inject(ActivatedRoute); paramPresent$ = this.route.queryParams.pipe(map((queryParams) => (queryParams?.param ? 'present' : 'missing'))); }