@analogjs/vitest-angular 3.0.0-alpha.9 → 3.0.0-alpha.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +304 -0
  2. package/_virtual/_@oxc-project_runtime@0.124.0/helpers/decorate.js +9 -0
  3. package/package.json +24 -8
  4. package/setup-serializers.d.ts +1 -0
  5. package/setup-serializers.js +13 -0
  6. package/setup-serializers.js.map +1 -0
  7. package/setup-snapshots.d.ts +1 -26
  8. package/setup-snapshots.js +4 -73
  9. package/setup-snapshots.js.map +1 -1
  10. package/setup-testbed.d.ts +14 -12
  11. package/setup-testbed.js +11 -7
  12. package/setup-testbed.js.map +1 -1
  13. package/setup-zone.d.ts +6 -5
  14. package/setup-zone.js +84 -83
  15. package/setup-zone.js.map +1 -1
  16. package/src/index.d.ts +2 -2
  17. package/src/lib/builders/build/devkit.d.ts +2 -2
  18. package/src/lib/builders/build/devkit.js +4 -3
  19. package/src/lib/builders/build/devkit.js.map +1 -1
  20. package/src/lib/builders/build/plugins/angular-memory-plugin.d.ts +13 -20
  21. package/src/lib/builders/build/plugins/angular-memory-plugin.js.map +1 -1
  22. package/src/lib/builders/build/plugins/downlevel-plugin.d.ts +6 -6
  23. package/src/lib/builders/build/plugins/downlevel-plugin.js.map +1 -1
  24. package/src/lib/builders/build/schema.js.map +1 -1
  25. package/src/lib/builders/build/schema.json +47 -0
  26. package/src/lib/builders/build/utils.d.ts +3 -3
  27. package/src/lib/builders/build/vitest.impl.d.ts +5 -5
  28. package/src/lib/builders/build/vitest.impl.js +3 -2
  29. package/src/lib/builders/build/vitest.impl.js.map +1 -1
  30. package/src/lib/builders/test/schema.js.map +1 -1
  31. package/src/lib/builders/test/schema.json +47 -0
  32. package/src/lib/builders/test/vitest.impl.d.ts +1 -1
  33. package/src/lib/builders/test/vitest.impl.js +3 -3
  34. package/src/lib/builders/test/vitest.impl.js.map +1 -1
  35. package/src/lib/snapshot-serializers/angular-fixture.d.ts +2 -0
  36. package/src/lib/snapshot-serializers/angular-fixture.js +71 -0
  37. package/src/lib/snapshot-serializers/angular-fixture.js.map +1 -0
  38. package/src/lib/snapshot-serializers/html-comment.d.ts +2 -0
  39. package/src/lib/snapshot-serializers/html-comment.js +11 -0
  40. package/src/lib/snapshot-serializers/html-comment.js.map +1 -0
  41. package/src/lib/snapshot-serializers/index.d.ts +3 -0
  42. package/src/lib/snapshot-serializers/no-ng-attributes.d.ts +4 -0
  43. package/src/lib/snapshot-serializers/no-ng-attributes.js +63 -0
  44. package/src/lib/snapshot-serializers/no-ng-attributes.js.map +1 -0
  45. package/src/lib/tools/collection.json +2 -2
  46. package/src/lib/tools/index.d.ts +1 -0
  47. package/src/lib/tools/package.json +1 -3
  48. package/src/lib/tools/{src/schematics → schematics}/setup/files/src/test-setup.ts.template +1 -0
  49. package/src/lib/tools/{src/schematics → schematics}/setup/files/vite.config.mts.template +2 -7
  50. package/src/lib/tools/schematics/setup/index.d.ts +3 -0
  51. package/src/lib/tools/schematics/setup/index.js.map +1 -0
  52. package/src/lib/tools/schematics/utils/angular.d.ts +3 -0
  53. package/src/lib/tools/schematics/utils/angular.js.map +1 -0
  54. package/src/lib/tools/schematics/utils/dependencies.d.ts +6 -0
  55. package/src/lib/tools/schematics/utils/dependencies.js.map +1 -0
  56. package/src/lib/tools/schematics/utils/index.d.ts +4 -0
  57. package/src/lib/tools/schematics/utils/versions.d.ts +7 -0
  58. package/src/lib/tools/{src/schematics → schematics}/utils/versions.js +1 -1
  59. package/src/lib/tools/schematics/utils/versions.js.map +1 -0
  60. package/src/lib/tools/schematics/utils/workspace.d.ts +15 -0
  61. package/src/lib/tools/schematics/utils/workspace.js.map +1 -0
  62. package/src/lib/tools/src/index.d.ts +1 -1
  63. package/src/lib/tools/src/schematics/setup/index.d.ts +2 -2
  64. package/src/lib/tools/src/schematics/utils/angular.d.ts +1 -1
  65. package/src/lib/tools/src/schematics/utils/dependencies.d.ts +2 -2
  66. package/src/lib/tools/src/schematics/utils/index.d.ts +4 -4
  67. package/src/lib/tools/src/schematics/utils/versions.d.ts +1 -1
  68. package/src/lib/tools/src/schematics/utils/workspace.d.ts +8 -8
  69. package/src/test-setup.d.ts +3 -0
  70. package/_virtual/_rolldown/runtime.js +0 -7
  71. package/src/lib/tools/src/schematics/setup/index.js.map +0 -1
  72. package/src/lib/tools/src/schematics/utils/angular.js.map +0 -1
  73. package/src/lib/tools/src/schematics/utils/dependencies.js.map +0 -1
  74. package/src/lib/tools/src/schematics/utils/versions.js.map +0 -1
  75. package/src/lib/tools/src/schematics/utils/workspace.js.map +0 -1
  76. /package/src/lib/tools/{src/index.js → index.js} +0 -0
  77. /package/src/lib/tools/{src/schematics → schematics}/jsonc-parser.d.ts +0 -0
  78. /package/src/lib/tools/{src/schematics → schematics}/semver.d.ts +0 -0
  79. /package/src/lib/tools/{src/schematics → schematics}/setup/index.js +0 -0
  80. /package/src/lib/tools/{src/schematics → schematics}/setup/schema.d.ts +0 -0
  81. /package/src/lib/tools/{src/schematics → schematics}/setup/schema.json +0 -0
  82. /package/src/lib/tools/{src/schematics → schematics}/utils/angular.js +0 -0
  83. /package/src/lib/tools/{src/schematics → schematics}/utils/dependencies.js +0 -0
  84. /package/src/lib/tools/{src/schematics → schematics}/utils/index.js +0 -0
  85. /package/src/lib/tools/{src/schematics → schematics}/utils/workspace.js +0 -0
package/README.md ADDED
@@ -0,0 +1,304 @@
1
+ # @analogjs/vitest-angular
2
+
3
+ A standalone builder for running tests with Vitest and Angular.
4
+
5
+ ## Supporting Analog
6
+
7
+ - Star the [GitHub Repo](https://github.com/analogjs/analog)
8
+ - Join the [Discord](https://chat.analogjs.org)
9
+ - Follow us on [Twitter](https://twitter.com/analogjs)
10
+ - Become a [Sponsor](https://analogjs.org/docs/sponsoring)
11
+
12
+ ## Installation
13
+
14
+ Use your package manager of choice to install the necessary packages.
15
+
16
+ With ng add:
17
+
18
+ ```sh
19
+ ng add @analogjs/vitest-angular
20
+ ```
21
+
22
+ With npm:
23
+
24
+ ```sh
25
+ npm install @analogjs/vitest-angular vitest --save-dev
26
+ ```
27
+
28
+ With pnpm:
29
+
30
+ ```sh
31
+ pnpm install -w @analogjs/vitest-angular vitest --dev
32
+ ```
33
+
34
+ With Yarn:
35
+
36
+ ```sh
37
+ yarn install @analogjs/vitest-angular vitest --dev
38
+ ```
39
+
40
+ ## Automated Setup Using a Schematic
41
+
42
+ A schematic can be used to setup Vitest in an existing Angular project:
43
+
44
+ Run the schematic to set up the Vite config, test configuration files, and update the test configuration.
45
+
46
+ ```sh
47
+ npx ng generate @analogjs/vitest-angular:setup --project [your-project-name]
48
+ ```
49
+
50
+ ### Schematic Options
51
+
52
+ | Option | Type | Default | Description |
53
+ | ------------- | ------- | ------- | ----------------------------------------------------------- |
54
+ | `project` | string | - | The name of the project to configure (required) |
55
+ | `browserMode` | boolean | `false` | Configure Vitest to run tests in a browser using Playwright |
56
+
57
+ To enable browser mode during setup:
58
+
59
+ ```shell
60
+ ng g @analogjs/vitest-angular:setup --project [your-project-name] --browserMode
61
+ ```
62
+
63
+ This automatically installs Playwright dependencies and configures Vitest for browser testing. See [Setup for Running Tests in the Browser](#setup-for-running-tests-in-the-browser) for more details.
64
+
65
+ If using browser mode, run `npx playwright install` after the schematic to ensure playwright is installed and configured.
66
+
67
+ ## Manual Setup
68
+
69
+ Vitest can be setup manually also using the steps below.
70
+
71
+ ### Setup for Running Tests in Node
72
+
73
+ To setup Vitest, create a `vite.config.mts` at the root of your project:
74
+
75
+ ```ts
76
+ /// <reference types="vitest" />
77
+ import { defineConfig } from 'vite';
78
+
79
+ import angular from '@analogjs/vite-plugin-angular';
80
+
81
+ export default defineConfig(({ mode }) => ({
82
+ plugins: [angular()],
83
+ test: {
84
+ globals: true,
85
+ setupFiles: ['src/test-setup.ts'],
86
+ environment: 'jsdom',
87
+ include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
88
+ reporters: ['default'],
89
+ },
90
+ }));
91
+ ```
92
+
93
+ Next, define a `src/test-setup.ts` file to setup the `TestBed`:
94
+
95
+ ### Zoneless setup
96
+
97
+ As of Angular v21, `Zoneless` change detection is the default for new projects.
98
+
99
+ Use the following setup:
100
+
101
+ ```ts
102
+ // src/test-setup.ts
103
+ import '@angular/compiler';
104
+ import '@analogjs/vitest-angular/setup-snapshots';
105
+ import '@analogjs/vitest-angular/setup-serializers';
106
+
107
+ import { setupTestBed } from '@analogjs/vitest-angular/setup-testbed';
108
+
109
+ setupTestBed();
110
+ ```
111
+
112
+ ### Zone.js setup
113
+
114
+ If you are using `Zone.js` for change detection, import the `setup-zone` script before setting up the `TestBed`. This script patches the test environment for `Zone.js` helpers such as `fakeAsync`, and automatically includes support for setting up snapshot tests.
115
+
116
+ ```ts
117
+ // src/test-setup.ts
118
+ import '@angular/compiler';
119
+ import '@analogjs/vitest-angular/setup-zone';
120
+
121
+ import { setupTestBed } from '@analogjs/vitest-angular/setup-testbed';
122
+
123
+ setupTestBed({
124
+ zoneless: false,
125
+ });
126
+ ```
127
+
128
+ The side effect imports must come first. If your formatter sorts side effect imports below named imports, keep them in a separate import group with a blank line, or exclude `src/test-setup.ts` from import sorting.
129
+
130
+ > **Note:** With `Zone.js`, use Vitest's global test functions, with `globals: true` set in the `vite.config.mts`, and `vitest/globals` added to the `types` array in the `tsconfig.spec.json`. Importing `describe`, `it`, `beforeEach`, and other functions from `vitest` directly bypasses the `Zone.js` patching, and `fakeAsync` fails with the error `Expected to be running in 'ProxyZone', but it was not found`. Zoneless tests have no such restriction — when migrating to zoneless change detection, you can switch back to importing the functions from `vitest`.
131
+
132
+ ### Configuration Options
133
+
134
+ The `setupTestBed()` function accepts an optional configuration object with the following properties:
135
+
136
+ - `zoneless` (boolean): Whether to use zoneless change detection (default: `true`)
137
+ - `providers` (`Type<any>[]`): Additional providers to include in the test environment (default: `[]`)
138
+ - `teardown.destroyAfterEach` (boolean): Whether to destroy the test environment after each test. Set to `false` to keep the component rendered, allowing you to inspect its final state. (default: `true`)
139
+ - `errorOnUnknownElements` (boolean): Whether to throw when unknown elements are present in a component's template. Set to `false` (default) to log the error instead of throwing.
140
+ - `errorOnUnknownProperties` (boolean): Whether to throw when unknown properties are present in a component's template. Set to `false` (default) to log the error instead of throwing.
141
+
142
+ **Example with options:**
143
+
144
+ ```ts
145
+ setupTestBed({
146
+ zoneless: true,
147
+ providers: [],
148
+ teardown: { destroyAfterEach: false },
149
+ errorOnUnknownElements: true,
150
+ errorOnUnknownProperties: true,
151
+ });
152
+ ```
153
+
154
+ Next, update the `test` target in the `angular.json` to use the `@analogjs/vitest-angular:test` builder:
155
+
156
+ ```json
157
+ {
158
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
159
+ "version": 1,
160
+ "newProjectRoot": "projects",
161
+ "projects": {
162
+ "your-project": {
163
+ "projectType": "application",
164
+ "architect": {
165
+ "test": {
166
+ "builder": "@analogjs/vitest-angular:test"
167
+ }
168
+ }
169
+ }
170
+ }
171
+ }
172
+ ```
173
+
174
+ Lastly, add the `src/test-setup.ts` to `files` array in the `tsconfig.spec.json` in the root of your project, set the `target` to `es2022`, and update the `types`.
175
+
176
+ ```json
177
+ {
178
+ "extends": "./tsconfig.json",
179
+ "compilerOptions": {
180
+ "outDir": "./out-tsc/spec",
181
+ "target": "es2022",
182
+ "types": ["vitest/globals", "node"]
183
+ },
184
+ "files": ["src/test-setup.ts"],
185
+ "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
186
+ }
187
+ ```
188
+
189
+ ## Running Tests
190
+
191
+ To run unit tests, use the `test` command:
192
+
193
+ ```shell
194
+ npm run test
195
+ ```
196
+
197
+ ```shell
198
+ yarn test
199
+ ```
200
+
201
+ ```shell
202
+ pnpm test
203
+ ```
204
+
205
+ > The `npx vitest` command can also be used directly.
206
+
207
+ ## Snapshot Testing
208
+
209
+ For snapshot testing you can use `toMatchSnapshot` from `expect` API.
210
+ The provided snapshot setup also removes Angular-specific `_ng*` attributes and `<!--container-->` comments from DOM snapshots, which keeps diffs focused on the actual template output.
211
+
212
+ The import of `setup-snapshots` and `setup-serializers` are complementary:
213
+
214
+ - Use `setup-snapshots` to serialize Angular fixtures and component refs so Vitest snapshots print component markup instead of Angular testing internals.
215
+ - Use `setup-serializers` to clean DOM snapshots by removing Angular runtime noise such as `_ngcontent-*`, `_nghost-*`, `ng-reflect-*`, generated ids and classes, and removes comments from DOM snapshots (e.g. `<!--container-->`).
216
+
217
+ Below is a small example of how to write a snapshot test:
218
+
219
+ ```ts
220
+ // card.component.spec.ts
221
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
222
+
223
+ import { CardComponent } from './card.component';
224
+
225
+ describe('CardComponent', () => {
226
+ let fixture: ComponentFixture<CardComponent>;
227
+ let component: CardComponent;
228
+
229
+ beforeEach(() =>
230
+ TestBed.configureTestingModule({
231
+ imports: [CardComponent],
232
+ }),
233
+ );
234
+
235
+ beforeEach(() => {
236
+ fixture = TestBed.createComponent(CardComponent);
237
+ component = fixture.componentInstance;
238
+ fixture.detectChanges();
239
+ });
240
+
241
+ it('should create the app', () => {
242
+ expect(fixture).toMatchSnapshot();
243
+ });
244
+ });
245
+ ```
246
+
247
+ After you run the test, a `card.component.spec.ts.snap` file is created in the`__snapshots__` folder with the below content:
248
+
249
+ ```ts
250
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
251
+
252
+ exports[`CardComponent > should create the app 1`] = `
253
+ <component-code>
254
+ `;
255
+ ```
256
+
257
+ The snapshots generated should be reviewed and added to version control.
258
+
259
+ ## Using TypeScript Config Path Aliases
260
+
261
+ If you are using `paths` in your `tsconfig.json`, support for those aliases can be added to the `vite.config.ts`.
262
+
263
+ First, install the `vite-tsconfig-paths` package.
264
+
265
+ With npm:
266
+
267
+ ```shell
268
+ npm install vite-tsconfig-paths --save-dev
269
+ ```
270
+
271
+ With pnpm:
272
+
273
+ ```shell
274
+ pnpm install -w vite-tsconfig-paths --dev
275
+ ```
276
+
277
+ With Yarn:
278
+
279
+ ```shell
280
+ yarn add vite-tsconfig-paths --dev
281
+ ```
282
+
283
+ Next, add the plugin to the `plugins` array in the `vite.config.ts`.
284
+
285
+ ```ts
286
+ /// <reference types="vitest" />
287
+ import { defineConfig } from 'vite';
288
+
289
+ import angular from '@analogjs/vite-plugin-angular';
290
+ import viteTsConfigPaths from 'vite-tsconfig-paths';
291
+
292
+ export default defineConfig(({ mode }) => ({
293
+ // ...other config
294
+ plugins: [angular(), viteTsConfigPaths()],
295
+ }));
296
+ ```
297
+
298
+ ### With Nx
299
+
300
+ Nx workspaces use the same `vite-tsconfig-paths` plugin. The `nxViteTsPaths` plugin from `@nx/vite` is deprecated and is removed in Nx 24, so replace it with `viteTsConfigPaths()`.
301
+
302
+ ## IDE Support
303
+
304
+ Tests can also be run directly from your IDE using the Vitest [IDE integrations](https://vitest.dev/guide/ide) for VS Code or JetBrains IDEs.
@@ -0,0 +1,9 @@
1
+ //#region \0@oxc-project+runtime@0.124.0/helpers/decorate.js
2
+ function __decorate(decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ }
8
+ //#endregion
9
+ export { __decorate };
package/package.json CHANGED
@@ -1,14 +1,30 @@
1
1
  {
2
2
  "name": "@analogjs/vitest-angular",
3
- "version": "3.0.0-alpha.9",
3
+ "version": "3.0.0-alpha.90",
4
4
  "description": "Vitest Builder for Angular",
5
5
  "type": "module",
6
6
  "author": "Brandon Roberts <robertsbt@gmail.com>",
7
7
  "exports": {
8
- ".": "./src/index.js",
9
- "./setup-zone": "./setup-zone.js",
10
- "./setup-snapshots": "./setup-snapshots.js",
11
- "./setup-testbed": "./setup-testbed.js",
8
+ ".": {
9
+ "types": "./src/index.d.ts",
10
+ "default": "./src/index.js"
11
+ },
12
+ "./setup-zone": {
13
+ "types": "./setup-zone.d.ts",
14
+ "default": "./setup-zone.js"
15
+ },
16
+ "./setup-snapshots": {
17
+ "types": "./setup-snapshots.d.ts",
18
+ "default": "./setup-snapshots.js"
19
+ },
20
+ "./setup-serializers": {
21
+ "types": "./setup-serializers.d.ts",
22
+ "default": "./setup-serializers.js"
23
+ },
24
+ "./setup-testbed": {
25
+ "types": "./setup-testbed.d.ts",
26
+ "default": "./setup-testbed.js"
27
+ },
12
28
  "./package.json": "./package.json"
13
29
  },
14
30
  "keywords": [
@@ -36,13 +52,13 @@
36
52
  "save": "devDependencies"
37
53
  },
38
54
  "dependencies": {
39
- "oxc-transform": "^0.119.0"
55
+ "oxc-transform": "^0.124.0"
40
56
  },
41
57
  "peerDependencies": {
42
58
  "@analogjs/vite-plugin-angular": "*",
43
- "@angular-devkit/architect": ">=0.1500.0 < 0.2200.0",
59
+ "@angular-devkit/architect": ">=0.1500.0 < 0.2300.0",
44
60
  "@angular-devkit/schematics": ">=17.0.0",
45
- "vitest": "^1.3.1 || ^2.0.0 || ^3.0.0 || ^4.0.0",
61
+ "vitest": "^1.3.1 || ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0",
46
62
  "zone.js": ">=0.14.0"
47
63
  },
48
64
  "peerDependenciesMeta": {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { createHtmlCommentSnapshotSerializer } from "./src/lib/snapshot-serializers/html-comment.js";
2
+ import { createNoNgAttributesSnapshotSerializer } from "./src/lib/snapshot-serializers/no-ng-attributes.js";
3
+ //#region packages/vitest-angular/setup-serializers.ts
4
+ var env = globalThis;
5
+ ["expect"].forEach((methodName) => {
6
+ const originalVitestFn = env[methodName];
7
+ if (!originalVitestFn) return;
8
+ originalVitestFn.addSnapshotSerializer(createHtmlCommentSnapshotSerializer());
9
+ originalVitestFn.addSnapshotSerializer(createNoNgAttributesSnapshotSerializer());
10
+ });
11
+ //#endregion
12
+
13
+ //# sourceMappingURL=setup-serializers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-serializers.js","names":[],"sources":["../setup-serializers.ts"],"sourcesContent":["import {\n createHtmlCommentSnapshotSerializer,\n createNoNgAttributesSnapshotSerializer,\n} from './snapshot-serializers.js';\n\nconst env = globalThis as any;\n\n['expect'].forEach((methodName) => {\n const originalVitestFn = env[methodName];\n if (!originalVitestFn) {\n return;\n }\n originalVitestFn.addSnapshotSerializer(createHtmlCommentSnapshotSerializer());\n originalVitestFn.addSnapshotSerializer(\n createNoNgAttributesSnapshotSerializer(),\n );\n});\n"],"mappings":";;;AAKA,IAAM,MAAM;AAEZ,CAAC,SAAS,CAAC,SAAS,eAAe;CACjC,MAAM,mBAAmB,IAAI;AAC7B,KAAI,CAAC,iBACH;AAEF,kBAAiB,sBAAsB,qCAAqC,CAAC;AAC7E,kBAAiB,sBACf,wCAAwC,CACzC;EACD"}
@@ -1,26 +1 @@
1
- declare const env: any;
2
- /**
3
- * Allows Vitest to handle Angular test fixtures
4
- *
5
- * Vitest Snapshot guide ==> https://vitest.dev/guide/snapshot.html
6
- *
7
- * @returns customSnapshotSerializer for Angular Fixture Component
8
- */
9
- declare const customSnapshotSerializer: () => {
10
- serialize: (...args: any[]) => string;
11
- test: (val: any) => boolean;
12
- };
13
- /**
14
- * Check if is an Angular fixture
15
- *
16
- * @param val Angular fixture
17
- * @returns boolean who check if is an angular fixture
18
- */
19
- declare function isAngularFixture(val: any): boolean;
20
- /**
21
- * Serialize Angular fixture for Vitest
22
- *
23
- * @param fixture Angular Fixture Component
24
- * @returns HTML Child Node
25
- */
26
- declare function fixtureVitestSerializer(fixture: any): ChildNode;
1
+ export {};
@@ -1,79 +1,10 @@
1
+ import { createAngularFixtureSnapshotSerializer } from "./src/lib/snapshot-serializers/angular-fixture.js";
1
2
  //#region packages/vitest-angular/setup-snapshots.ts
2
3
  var env = globalThis;
3
- /**
4
- * Allows Vitest to handle Angular test fixtures
5
- *
6
- * Vitest Snapshot guide ==> https://vitest.dev/guide/snapshot.html
7
- *
8
- * @returns customSnapshotSerializer for Angular Fixture Component
9
- */
10
- var customSnapshotSerializer = () => {
11
- function serialize(val, config, indentation, depth, refs, printer) {
12
- return `${printer(fixtureVitestSerializer(val), config, indentation, depth, refs)}`;
13
- }
14
- function test(val) {
15
- return val && isAngularFixture(val);
16
- }
17
- return {
18
- serialize,
19
- test
20
- };
21
- };
22
- /**
23
- * Check if is an Angular fixture
24
- *
25
- * @param val Angular fixture
26
- * @returns boolean who check if is an angular fixture
27
- */
28
- function isAngularFixture(val) {
29
- if (typeof val !== "object") return false;
30
- if (val["componentRef"] || val["componentInstance"]) return true;
31
- if (val["componentType"]) return true;
32
- return JSON.stringify(Object.keys(val)) === JSON.stringify([
33
- "componentRef",
34
- "ngZone",
35
- "effectRunner",
36
- "_autoDetect",
37
- "_isStable",
38
- "_isDestroyed",
39
- "_resolve",
40
- "_promise",
41
- "_onUnstableSubscription",
42
- "_onStableSubscription",
43
- "_onMicrotaskEmptySubscription",
44
- "_onErrorSubscription",
45
- "changeDetectorRef",
46
- "elementRef",
47
- "debugElement",
48
- "componentInstance",
49
- "nativeElement"
50
- ]) || JSON.stringify(Object.keys(val)) === JSON.stringify([
51
- "location",
52
- "_rootLView",
53
- "_tNode",
54
- "previousInputValues",
55
- "instance",
56
- "changeDetectorRef",
57
- "hostView",
58
- "componentType"
59
- ]);
60
- }
61
- /**
62
- * Serialize Angular fixture for Vitest
63
- *
64
- * @param fixture Angular Fixture Component
65
- * @returns HTML Child Node
66
- */
67
- function fixtureVitestSerializer(fixture) {
68
- const componentType = fixture && fixture.componentType ? fixture.componentType : fixture.componentRef.componentType;
69
- let inputsData = "";
70
- const selector = Reflect.getOwnPropertyDescriptor(componentType, "__annotations__")?.value[0].selector;
71
- if (componentType && componentType.propDecorators) inputsData = Object.entries(componentType.propDecorators).map(([key, value]) => `${key}="${value}"`).join("");
72
- const divElement = fixture && fixture.nativeElement ? fixture.nativeElement : fixture.location.nativeElement;
73
- return new DOMParser().parseFromString(`<${selector} ${inputsData}>${divElement.innerHTML}</${selector}>`, "text/html").body.childNodes[0];
74
- }
75
4
  ["expect"].forEach((methodName) => {
76
- return env[methodName].addSnapshotSerializer(customSnapshotSerializer());
5
+ const originalVitestFn = env[methodName];
6
+ if (!originalVitestFn) return;
7
+ originalVitestFn.addSnapshotSerializer(createAngularFixtureSnapshotSerializer());
77
8
  });
78
9
  //#endregion
79
10
 
@@ -1 +1 @@
1
- {"version":3,"file":"setup-snapshots.js","names":[],"sources":["../../../packages/vitest-angular/setup-snapshots.ts"],"sourcesContent":["const env = globalThis as any;\n\n/**\n * Allows Vitest to handle Angular test fixtures\n *\n * Vitest Snapshot guide ==> https://vitest.dev/guide/snapshot.html\n *\n * @returns customSnapshotSerializer for Angular Fixture Component\n */\nconst customSnapshotSerializer = (): {\n serialize: (...args: any[]) => string;\n test: (val: any) => boolean;\n} => {\n function serialize(\n val: any,\n config: any,\n indentation: any,\n depth: any,\n refs: any,\n printer: any,\n ): string {\n // `printer` is a function that serializes a value using existing plugins.\n return `${printer(\n fixtureVitestSerializer(val),\n config,\n indentation,\n depth,\n refs,\n )}`;\n }\n function test(val: any): boolean {\n // * If it's a ComponentFixture we apply the transformation rules\n return val && isAngularFixture(val);\n }\n return {\n serialize: serialize,\n test: test,\n };\n};\n\n/**\n * Check if is an Angular fixture\n *\n * @param val Angular fixture\n * @returns boolean who check if is an angular fixture\n */\nfunction isAngularFixture(val: any): boolean {\n if (typeof val !== 'object') {\n return false;\n }\n\n if (val['componentRef'] || val['componentInstance']) {\n return true;\n }\n\n if (val['componentType']) {\n return true;\n }\n\n // * Angular fixture keys in Fixture component Object\n const fixtureKeys = [\n 'componentRef',\n 'ngZone',\n 'effectRunner',\n '_autoDetect',\n '_isStable',\n '_isDestroyed',\n '_resolve',\n '_promise',\n '_onUnstableSubscription',\n '_onStableSubscription',\n '_onMicrotaskEmptySubscription',\n '_onErrorSubscription',\n 'changeDetectorRef',\n 'elementRef',\n 'debugElement',\n 'componentInstance',\n 'nativeElement',\n ];\n\n // * Angular fixture keys in Fixture componentRef Object\n const fixtureComponentRefKeys = [\n 'location',\n '_rootLView',\n '_tNode',\n 'previousInputValues',\n 'instance',\n 'changeDetectorRef',\n 'hostView',\n 'componentType',\n ];\n\n return (\n JSON.stringify(Object.keys(val)) === JSON.stringify(fixtureKeys) ||\n JSON.stringify(Object.keys(val)) === JSON.stringify(fixtureComponentRefKeys)\n );\n}\n\n/**\n * Serialize Angular fixture for Vitest\n *\n * @param fixture Angular Fixture Component\n * @returns HTML Child Node\n */\nfunction fixtureVitestSerializer(fixture: any): ChildNode {\n // * Get Component meta data\n const componentType = (\n fixture && fixture.componentType\n ? fixture.componentType\n : fixture.componentRef.componentType\n ) as any;\n\n let inputsData = '';\n\n const selector = Reflect.getOwnPropertyDescriptor(\n componentType,\n '__annotations__',\n )?.value[0].selector;\n\n if (componentType && componentType.propDecorators) {\n inputsData = Object.entries(componentType.propDecorators)\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join('');\n }\n\n // * Get DOM Elements\n const divElement =\n fixture && fixture.nativeElement\n ? fixture.nativeElement\n : fixture.location.nativeElement;\n\n // * Convert string data to HTML data\n const doc = new DOMParser().parseFromString(\n `<${selector} ${inputsData}>${divElement.innerHTML}</${selector}>`,\n 'text/html',\n );\n\n return doc.body.childNodes[0];\n}\n\n['expect'].forEach((methodName) => {\n const originalvitestFn = env[methodName];\n return originalvitestFn.addSnapshotSerializer(customSnapshotSerializer());\n});\n"],"mappings":";AAAA,IAAM,MAAM;;;;;;;;AASZ,IAAM,iCAGD;CACH,SAAS,UACP,KACA,QACA,aACA,OACA,MACA,SACQ;AAER,SAAO,GAAG,QACR,wBAAwB,IAAI,EAC5B,QACA,aACA,OACA,KACD;;CAEH,SAAS,KAAK,KAAmB;AAE/B,SAAO,OAAO,iBAAiB,IAAI;;AAErC,QAAO;EACM;EACL;EACP;;;;;;;;AASH,SAAS,iBAAiB,KAAmB;AAC3C,KAAI,OAAO,QAAQ,SACjB,QAAO;AAGT,KAAI,IAAI,mBAAmB,IAAI,qBAC7B,QAAO;AAGT,KAAI,IAAI,iBACN,QAAO;AAoCT,QACE,KAAK,UAAU,OAAO,KAAK,IAAI,CAAC,KAAK,KAAK,UAjCxB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAeiE,IAChE,KAAK,UAAU,OAAO,KAAK,IAAI,CAAC,KAAK,KAAK,UAbZ;EAC9B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAI6E;;;;;;;;AAUhF,SAAS,wBAAwB,SAAyB;CAExD,MAAM,gBACJ,WAAW,QAAQ,gBACf,QAAQ,gBACR,QAAQ,aAAa;CAG3B,IAAI,aAAa;CAEjB,MAAM,WAAW,QAAQ,yBACvB,eACA,kBACD,EAAE,MAAM,GAAG;AAEZ,KAAI,iBAAiB,cAAc,eACjC,cAAa,OAAO,QAAQ,cAAc,eAAe,CACtD,KAAK,CAAC,KAAK,WAAW,GAAG,IAAI,IAAI,MAAM,GAAG,CAC1C,KAAK,GAAG;CAIb,MAAM,aACJ,WAAW,QAAQ,gBACf,QAAQ,gBACR,QAAQ,SAAS;AAQvB,QALY,IAAI,WAAW,CAAC,gBAC1B,IAAI,SAAS,GAAG,WAAW,GAAG,WAAW,UAAU,IAAI,SAAS,IAChE,YACD,CAEU,KAAK,WAAW;;AAG7B,CAAC,SAAS,CAAC,SAAS,eAAe;AAEjC,QADyB,IAAI,YACL,sBAAsB,0BAA0B,CAAC;EACzE"}
1
+ {"version":3,"file":"setup-snapshots.js","names":[],"sources":["../setup-snapshots.ts"],"sourcesContent":["import { createAngularFixtureSnapshotSerializer } from './snapshot-serializers.js';\n\nconst env = globalThis as any;\n\n['expect'].forEach((methodName) => {\n const originalVitestFn = env[methodName];\n if (!originalVitestFn) {\n return;\n }\n originalVitestFn.addSnapshotSerializer(\n createAngularFixtureSnapshotSerializer(),\n );\n});\n"],"mappings":";;AAEA,IAAM,MAAM;AAEZ,CAAC,SAAS,CAAC,SAAS,eAAe;CACjC,MAAM,mBAAmB,IAAI;AAC7B,KAAI,CAAC,iBACH;AAEF,kBAAiB,sBACf,wCAAwC,CACzC;EACD"}
@@ -1,15 +1,17 @@
1
- import { EnvironmentProviders, Provider } from '@angular/core';
1
+ import { EnvironmentProviders, Provider } from "@angular/core";
2
2
  type TestBedSetupOptions = {
3
- zoneless?: boolean;
4
- providers?: (Provider | EnvironmentProviders)[];
5
- /**
6
- * @deprecated Use `teardown.destroyAfterEach` instead.
7
- * @sunset 3.0.0
8
- */
9
- browserMode?: boolean;
10
- teardown?: {
11
- destroyAfterEach: boolean;
12
- };
3
+ zoneless?: boolean;
4
+ providers?: (Provider | EnvironmentProviders)[];
5
+ /**
6
+ * @deprecated Use `teardown.destroyAfterEach` instead.
7
+ * @sunset 3.0.0
8
+ */
9
+ browserMode?: boolean;
10
+ teardown?: {
11
+ destroyAfterEach: boolean;
12
+ };
13
+ errorOnUnknownElements?: boolean;
14
+ errorOnUnknownProperties?: boolean;
13
15
  };
14
- export declare function setupTestBed({ zoneless, providers, browserMode, teardown, }?: TestBedSetupOptions): void;
16
+ export declare function setupTestBed({ zoneless, providers, browserMode, teardown, errorOnUnknownElements, errorOnUnknownProperties }?: TestBedSetupOptions): void;
15
17
  export {};
package/setup-testbed.js CHANGED
@@ -1,21 +1,25 @@
1
+ import { __decorate } from "./_virtual/_@oxc-project_runtime@0.124.0/helpers/decorate.js";
1
2
  import { NgModule, provideZonelessChangeDetection } from "@angular/core";
2
3
  import { getTestBed, ɵgetCleanupHook } from "@angular/core/testing";
3
4
  import { BrowserTestingModule, platformBrowserTesting } from "@angular/platform-browser/testing";
4
5
  import { afterEach, beforeEach } from "vitest";
5
- import _decorate from "@oxc-project/runtime/helpers/decorate";
6
6
  //#region packages/vitest-angular/setup-testbed.ts
7
7
  var ANGULAR_TESTBED_SETUP = Symbol.for("testbed-setup");
8
- function setupTestBed({ zoneless = true, providers = [], browserMode = false, teardown } = {}) {
8
+ function setupTestBed({ zoneless = true, providers = [], browserMode = false, teardown, errorOnUnknownElements, errorOnUnknownProperties } = {}) {
9
9
  beforeEach(ɵgetCleanupHook(false));
10
10
  afterEach(ɵgetCleanupHook(true));
11
11
  if (!globalThis[ANGULAR_TESTBED_SETUP]) {
12
12
  globalThis[ANGULAR_TESTBED_SETUP] = true;
13
13
  let TestModule = class TestModule {};
14
- TestModule = _decorate([NgModule({ providers: [...zoneless ? [provideZonelessChangeDetection()] : [], ...providers] })], TestModule);
15
- getTestBed().initTestEnvironment([BrowserTestingModule, TestModule], platformBrowserTesting(), { teardown: {
16
- destroyAfterEach: !browserMode,
17
- ...teardown
18
- } });
14
+ TestModule = __decorate([NgModule({ providers: [...zoneless ? [provideZonelessChangeDetection()] : [], ...providers] })], TestModule);
15
+ getTestBed().initTestEnvironment([BrowserTestingModule, TestModule], platformBrowserTesting(), {
16
+ teardown: {
17
+ destroyAfterEach: !browserMode,
18
+ ...teardown
19
+ },
20
+ errorOnUnknownElements,
21
+ errorOnUnknownProperties
22
+ });
19
23
  }
20
24
  }
21
25
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"setup-testbed.js","names":[],"sources":["../../../packages/vitest-angular/setup-testbed.ts"],"sourcesContent":["import {\n EnvironmentProviders,\n NgModule,\n Provider,\n provideZonelessChangeDetection,\n} from '@angular/core';\nimport {\n ɵgetCleanupHook as getCleanupHook,\n getTestBed,\n} from '@angular/core/testing';\nimport {\n BrowserTestingModule,\n platformBrowserTesting,\n} from '@angular/platform-browser/testing';\nimport { afterEach, beforeEach } from 'vitest';\n\nconst ANGULAR_TESTBED_SETUP = Symbol.for('testbed-setup');\n\ntype TestBedSetupOptions = {\n zoneless?: boolean;\n providers?: (Provider | EnvironmentProviders)[];\n /**\n * @deprecated Use `teardown.destroyAfterEach` instead.\n * @sunset 3.0.0\n */\n browserMode?: boolean;\n teardown?: {\n destroyAfterEach: boolean;\n };\n};\n\nexport function setupTestBed({\n zoneless = true,\n providers = [],\n browserMode = false,\n teardown,\n}: TestBedSetupOptions = {}): void {\n beforeEach(getCleanupHook(false));\n afterEach(getCleanupHook(true));\n\n if (!(globalThis as any)[ANGULAR_TESTBED_SETUP]) {\n (globalThis as any)[ANGULAR_TESTBED_SETUP] = true;\n\n @NgModule({\n providers: [\n ...(zoneless ? [provideZonelessChangeDetection()] : []),\n ...providers,\n ],\n })\n class TestModule {}\n\n getTestBed().initTestEnvironment(\n [BrowserTestingModule, TestModule],\n platformBrowserTesting(),\n {\n teardown: {\n ...{ destroyAfterEach: !browserMode },\n ...teardown,\n },\n },\n );\n }\n}\n"],"mappings":";;;;;;AAgBA,IAAM,wBAAwB,OAAO,IAAI,gBAAgB;AAezD,SAAgB,aAAa,EAC3B,WAAW,MACX,YAAY,EAAE,EACd,cAAc,OACd,aACuB,EAAE,EAAQ;AACjC,YAAW,gBAAe,MAAM,CAAC;AACjC,WAAU,gBAAe,KAAK,CAAC;AAE/B,KAAI,CAAE,WAAmB,wBAAwB;AAC9C,aAAmB,yBAAyB;EAE7C,IAAA,aAAA,MAMM,WAAW;0BANhB,SAAS,EACR,WAAW,CACT,GAAI,WAAW,CAAC,gCAAgC,CAAC,GAAG,EAAE,EACtD,GAAG,UACJ,EACF,CAAC,CAAA,EAAA,WAAA;AAGF,cAAY,CAAC,oBACX,CAAC,sBAAsB,WAAW,EAClC,wBAAwB,EACxB,EACE,UAAU;GACH,kBAAkB,CAAC;GACxB,GAAG;GACJ,EACF,CACF"}
1
+ {"version":3,"file":"setup-testbed.js","names":[],"sources":["../setup-testbed.ts"],"sourcesContent":["import {\n EnvironmentProviders,\n NgModule,\n Provider,\n provideZonelessChangeDetection,\n} from '@angular/core';\nimport {\n ɵgetCleanupHook as getCleanupHook,\n getTestBed,\n} from '@angular/core/testing';\nimport {\n BrowserTestingModule,\n platformBrowserTesting,\n} from '@angular/platform-browser/testing';\nimport { afterEach, beforeEach } from 'vitest';\n\nconst ANGULAR_TESTBED_SETUP = Symbol.for('testbed-setup');\n\ntype TestBedSetupOptions = {\n zoneless?: boolean;\n providers?: (Provider | EnvironmentProviders)[];\n /**\n * @deprecated Use `teardown.destroyAfterEach` instead.\n * @sunset 3.0.0\n */\n browserMode?: boolean;\n teardown?: {\n destroyAfterEach: boolean;\n };\n errorOnUnknownElements?: boolean;\n errorOnUnknownProperties?: boolean;\n};\n\nexport function setupTestBed({\n zoneless = true,\n providers = [],\n browserMode = false,\n teardown,\n errorOnUnknownElements,\n errorOnUnknownProperties,\n}: TestBedSetupOptions = {}): void {\n beforeEach(getCleanupHook(false));\n afterEach(getCleanupHook(true));\n\n if (!(globalThis as any)[ANGULAR_TESTBED_SETUP]) {\n (globalThis as any)[ANGULAR_TESTBED_SETUP] = true;\n\n @NgModule({\n providers: [\n ...(zoneless ? [provideZonelessChangeDetection()] : []),\n ...providers,\n ],\n })\n class TestModule {}\n\n getTestBed().initTestEnvironment(\n [BrowserTestingModule, TestModule],\n platformBrowserTesting(),\n {\n teardown: {\n ...{ destroyAfterEach: !browserMode },\n ...teardown,\n },\n errorOnUnknownElements,\n errorOnUnknownProperties,\n },\n );\n }\n}\n"],"mappings":";;;;;;AAgBA,IAAM,wBAAwB,OAAO,IAAI,gBAAgB;AAiBzD,SAAgB,aAAa,EAC3B,WAAW,MACX,YAAY,EAAE,EACd,cAAc,OACd,UACA,wBACA,6BACuB,EAAE,EAAQ;AACjC,YAAW,gBAAe,MAAM,CAAC;AACjC,WAAU,gBAAe,KAAK,CAAC;AAE/B,KAAI,CAAE,WAAmB,wBAAwB;AAC9C,aAAmB,yBAAyB;EAE7C,IAAA,aAAA,MAMM,WAAW;2BANhB,SAAS,EACR,WAAW,CACT,GAAI,WAAW,CAAC,gCAAgC,CAAC,GAAG,EAAE,EACtD,GAAG,UACJ,EACF,CAAC,CAAA,EAAA,WAAA;AAGF,cAAY,CAAC,oBACX,CAAC,sBAAsB,WAAW,EAClC,wBAAwB,EACxB;GACE,UAAU;IACH,kBAAkB,CAAC;IACxB,GAAG;IACJ;GACD;GACA;GACD,CACF"}
package/setup-zone.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import 'zone.js';
2
- import 'zone.js/plugins/sync-test';
3
- import 'zone.js/plugins/proxy';
4
- import 'zone.js/testing';
5
- import './setup-snapshots.js';
1
+ import "zone.js";
2
+ import "zone.js/plugins/sync-test";
3
+ import "zone.js/plugins/proxy";
4
+ import "zone.js/testing";
5
+ import "./setup-snapshots.js";
6
+ export {};