Skip to content

Commit

Permalink
fix: support Angular 19 (#503)
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver authored Dec 3, 2024
1 parent 4bd4ab2 commit fdcf5fa
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 87 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
- name: install
run: npm install
run: npm install --force
- name: build
run: npm run build -- --skip-nx-cache
- name: test
Expand Down
46 changes: 23 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,35 @@
"prepare": "git config core.hookspath .githooks"
},
"dependencies": {
"@angular/animations": "18.2.13",
"@angular/cdk": "18.2.14",
"@angular/common": "18.2.13",
"@angular/compiler": "18.2.13",
"@angular/core": "18.2.13",
"@angular/material": "18.2.14",
"@angular/platform-browser": "18.2.13",
"@angular/platform-browser-dynamic": "18.2.13",
"@angular/router": "18.2.13",
"@ngrx/store": "18.0.2",
"@angular/animations": "19.0.1",
"@angular/cdk": "19.0.1",
"@angular/common": "19.0.1",
"@angular/compiler": "19.0.1",
"@angular/core": "19.0.1",
"@angular/material": "19.0.1",
"@angular/platform-browser": "19.0.1",
"@angular/platform-browser-dynamic": "19.0.1",
"@angular/router": "19.0.1",
"@ngrx/store": "19.0.0-beta.0",
"@nx/angular": "20.1.3",
"@testing-library/dom": "^10.0.0",
"@testing-library/dom": "^10.4.0",
"rxjs": "7.8.0",
"tslib": "~2.3.1",
"zone.js": "0.14.10"
"zone.js": "^0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "18.2.9",
"@angular-devkit/core": "18.2.9",
"@angular-devkit/schematics": "18.2.9",
"@angular-devkit/build-angular": "19.0.1",
"@angular-devkit/core": "19.0.1",
"@angular-devkit/schematics": "19.0.1",
"@angular-eslint/builder": "18.3.0",
"@angular-eslint/eslint-plugin": "18.0.1",
"@angular-eslint/eslint-plugin-template": "18.0.1",
"@angular-eslint/schematics": "18.3.0",
"@angular-eslint/template-parser": "18.0.1",
"@angular/cli": "~18.2.0",
"@angular/compiler-cli": "18.2.13",
"@angular/forms": "18.2.13",
"@angular/language-service": "18.2.13",
"@angular/cli": "19.0.1",
"@angular/compiler-cli": "19.0.1",
"@angular/forms": "19.0.1",
"@angular/language-service": "19.0.1",
"@nx/eslint": "20.1.3",
"@nx/eslint-plugin": "20.1.3",
"@nx/jest": "20.1.3",
Expand All @@ -68,7 +68,7 @@
"@testing-library/user-event": "^14.4.3",
"@types/jasmine": "4.3.1",
"@types/jest": "29.5.14",
"@types/node": "18.16.9",
"@types/node": "22.10.1",
"@types/testing-library__jasmine-dom": "^1.3.0",
"@typescript-eslint/eslint-plugin": "7.16.0",
"@typescript-eslint/parser": "7.16.0",
Expand All @@ -86,15 +86,15 @@
"jasmine-spec-reporter": "7.0.0",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"jest-preset-angular": "14.1.0",
"jest-preset-angular": "14.4.1",
"karma": "6.4.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage": "^2.2.1",
"karma-jasmine": "5.1.0",
"karma-jasmine-html-reporter": "2.0.0",
"lint-staged": "^12.1.6",
"ng-mocks": "^14.11.0",
"ng-packagr": "18.2.1",
"ng-packagr": "19.0.1",
"nx": "20.1.3",
"postcss": "^8.4.5",
"postcss-import": "14.1.0",
Expand All @@ -105,6 +105,6 @@
"semantic-release": "^18.0.0",
"ts-jest": "29.1.0",
"ts-node": "10.9.1",
"typescript": "5.5.4"
"typescript": "5.6.2"
}
}
15 changes: 11 additions & 4 deletions projects/testing-library/src/lib/testing-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
RenderComponentOptions,
RenderResult,
RenderTemplateOptions,
Config,
} from './models';

type SubscribedOutput<T> = readonly [key: keyof T, callback: (v: any) => void, subscription: OutputRefSubscription];
Expand Down Expand Up @@ -82,7 +83,9 @@ export async function render<SutType, WrapperType = SutType>(
configureTestBed = () => {
/* noop*/
},
} = { ...globalConfig, ...renderOptions };
} = { ...globalConfig, ...renderOptions } as RenderComponentOptions<SutType> &
RenderTemplateOptions<WrapperType> &
Config;

dtlConfigure({
eventWrapper: (cb) => {
Expand Down Expand Up @@ -228,7 +231,7 @@ export async function render<SutType, WrapperType = SutType>(
return createdFixture;
};

const fixture = await renderFixture(componentProperties, allInputs, componentOutputs, on);
const fixture = await renderFixture(componentProperties, allInputs as any, componentOutputs, on);

if (deferBlockStates) {
if (Array.isArray(deferBlockStates)) {
Expand Down Expand Up @@ -494,12 +497,16 @@ function addAutoDeclarations<SutType>(
wrapper,
}: Pick<RenderTemplateOptions<any>, 'declarations' | 'excludeComponentDeclaration' | 'wrapper'>,
) {
const nonStandaloneDeclarations = declarations?.filter((d) => !isStandalone(d));
if (typeof sut === 'string') {
return [...declarations, wrapper];
if (wrapper && isStandalone(wrapper)) {
return nonStandaloneDeclarations;
}
return [...nonStandaloneDeclarations, wrapper];
}

const components = () => (excludeComponentDeclaration || isStandalone(sut) ? [] : [sut]);
return [...declarations, ...components()];
return [...nonStandaloneDeclarations, ...components()];
}

function addAutoImports<SutType>(
Expand Down
4 changes: 3 additions & 1 deletion projects/testing-library/test-setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'jest-preset-angular/setup-jest';
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
import '@testing-library/jest-dom';
import { TextEncoder, TextDecoder } from 'util';

setupZoneTestEnv();

// eslint-disable-next-line @typescript-eslint/naming-convention
Object.assign(global, { TextDecoder, TextEncoder });
1 change: 1 addition & 0 deletions projects/testing-library/tests/config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { ReactiveFormsModule, FormBuilder } from '@angular/forms';
</div>
</form>
`,
standalone: false,
})
class FormsComponent {
form = this.formBuilder.group({
Expand Down
2 changes: 2 additions & 0 deletions projects/testing-library/tests/find-by.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { Component } from '@angular/core';
import { timer } from 'rxjs';
import { render, screen } from '../src/public_api';
import { mapTo } from 'rxjs/operators';
import { AsyncPipe } from '@angular/common';

@Component({
selector: 'atl-fixture',
template: ` <div>{{ result | async }}</div> `,
imports: [AsyncPipe],
})
class FixtureComponent {
result = timer(30).pipe(mapTo('I am visible'));
Expand Down
38 changes: 21 additions & 17 deletions projects/testing-library/tests/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { of, BehaviorSubject } from 'rxjs';
import { debounceTime, switchMap, map, startWith } from 'rxjs/operators';
import { render, screen, waitFor, waitForElementToBeRemoved, within } from '../src/lib/testing-library';
import userEvent from '@testing-library/user-event';
import { AsyncPipe, NgForOf } from '@angular/common';

const DEBOUNCE_TIME = 1_000;

Expand All @@ -21,6 +22,25 @@ class ModalService {
}
}

@Component({
selector: 'atl-table',
template: `
<table>
<tr *ngFor="let entity of entities">
<td>{{ entity.name }}</td>
<td>
<button (click)="edit.next(entity.name)">Edit</button>
</td>
</tr>
</table>
`,
imports: [NgForOf],
})
class TableComponent {
@Input() entities: any[] = [];
@Output() edit = new EventEmitter<string>();
}

@Component({
template: `
<h1>Entities Title</h1>
Expand All @@ -31,6 +51,7 @@ class ModalService {
</label>
<atl-table [entities]="entities | async" (edit)="editEntityClicked($event)"></atl-table>
`,
imports: [TableComponent, AsyncPipe],
})
class EntitiesComponent {
query = new BehaviorSubject<string>('');
Expand All @@ -55,22 +76,6 @@ class EntitiesComponent {
}
}

@Component({
selector: 'atl-table',
template: `
<table>
<tr *ngFor="let entity of entities">
<td>{{ entity.name }}</td>
<td><button (click)="edit.next(entity.name)">Edit</button></td>
</tr>
</table>
`,
})
class TableComponent {
@Input() entities: any[] = [];
@Output() edit = new EventEmitter<string>();
}

const entities = [
{
id: 1,
Expand All @@ -91,7 +96,6 @@ async function setup() {
const user = userEvent.setup();

await render(EntitiesComponent, {
declarations: [TableComponent],
providers: [
{
provide: EntitiesService,
Expand Down
4 changes: 3 additions & 1 deletion projects/testing-library/tests/issues/issue-230.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Component } from '@angular/core';
import { render, waitFor, screen } from '../../src/public_api';
import { NgClass } from '@angular/common';

@Component({
template: ` <button [ngClass]="classes">Load</button> `,
imports: [NgClass],
})
class LoopComponent {
get classes() {
Expand All @@ -17,7 +19,7 @@ test('wait does not end up in a loop', async () => {

await expect(
waitFor(() => {
expect(true).toEqual(false);
expect(true).toBe(false);
}),
).rejects.toThrow();
});
Expand Down
9 changes: 5 additions & 4 deletions projects/testing-library/tests/issues/issue-280.spec.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { Location } from '@angular/common';
import { Component, NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RouterLink, RouterModule, RouterOutlet, Routes } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import userEvent from '@testing-library/user-event';
import { render, screen } from '../../src/public_api';

@Component({
template: `<div>Navigate</div>
template: ` <div>Navigate</div>
<router-outlet></router-outlet>`,
imports: [RouterOutlet],
})
class MainComponent {}

@Component({
template: `<div>first page</div>
template: ` <div>first page</div>
<a routerLink="/second">go to second</a>`,
imports: [RouterLink],
})
class FirstComponent {}

Expand All @@ -35,7 +37,6 @@ const routes: Routes = [
];

@NgModule({
declarations: [FirstComponent, SecondComponent],
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
Expand Down
18 changes: 9 additions & 9 deletions projects/testing-library/tests/render-template.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class GreetingComponent {

test('the directive renders', async () => {
const view = await render('<div onOff></div>', {
declarations: [OnOffDirective],
imports: [OnOffDirective],
});

// eslint-disable-next-line testing-library/no-container
Expand All @@ -54,7 +54,7 @@ test('the directive renders', async () => {

test('the component renders', async () => {
const view = await render('<greeting name="Angular"></greeting>', {
declarations: [GreetingComponent],
imports: [GreetingComponent],
});

// eslint-disable-next-line testing-library/no-container
Expand All @@ -64,7 +64,7 @@ test('the component renders', async () => {

test('uses the default props', async () => {
await render('<div onOff></div>', {
declarations: [OnOffDirective],
imports: [OnOffDirective],
});

fireEvent.click(screen.getByText('init'));
Expand All @@ -74,7 +74,7 @@ test('uses the default props', async () => {

test('overrides input properties', async () => {
await render('<div onOff on="hello"></div>', {
declarations: [OnOffDirective],
imports: [OnOffDirective],
});

fireEvent.click(screen.getByText('init'));
Expand All @@ -85,7 +85,7 @@ test('overrides input properties', async () => {
test('overrides input properties via a wrapper', async () => {
// `bar` will be set as a property on the wrapper component, the property will be used to pass to the directive
await render('<div onOff [on]="bar"></div>', {
declarations: [OnOffDirective],
imports: [OnOffDirective],
componentProperties: {
bar: 'hello',
},
Expand All @@ -100,7 +100,7 @@ test('overrides output properties', async () => {
const clicked = jest.fn();

await render('<div onOff (clicked)="clicked($event)"></div>', {
declarations: [OnOffDirective],
imports: [OnOffDirective],
componentProperties: {
clicked,
},
Expand All @@ -116,7 +116,7 @@ test('overrides output properties', async () => {
describe('removeAngularAttributes', () => {
it('should remove angular attributes', async () => {
await render('<div onOff (clicked)="clicked($event)"></div>', {
declarations: [OnOffDirective],
imports: [OnOffDirective],
removeAngularAttributes: true,
});

Expand All @@ -126,7 +126,7 @@ describe('removeAngularAttributes', () => {

it('is disabled by default', async () => {
await render('<div onOff (clicked)="clicked($event)"></div>', {
declarations: [OnOffDirective],
imports: [OnOffDirective],
});

expect(document.querySelector('[ng-version]')).not.toBeNull();
Expand All @@ -136,7 +136,7 @@ describe('removeAngularAttributes', () => {

test('updates properties and invokes change detection', async () => {
const view = await render<{ value: string }>('<div [update]="value" ></div>', {
declarations: [UpdateInputDirective],
imports: [UpdateInputDirective],
componentProperties: {
value: 'value1',
},
Expand Down
Loading

0 comments on commit fdcf5fa

Please sign in to comment.