Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(config): add setup-jest.mjs for ESM mode #1463

Merged
merged 1 commit into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions examples/example-app-monorepo/apps/app1/jest-esm.config.mjs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import ngPreset from 'jest-preset-angular/presets/index.js';

/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
const jestConfig = {
...ngPreset.defaultsESM,
displayName: 'app1',
preset: 'jest-preset-angular/presets/defaults-esm',
globals: {
'ts-jest': {
useESM: true,
stringifyContentPathRegex: '\\.(html|svg)$',
...ngPreset.defaultsESM.globals["ts-jest"],
tsconfig: '<rootDir>/tsconfig-esm.spec.json',
},
},
moduleNameMapper: {
tslib: 'tslib/tslib.es6.js',
rxjs: '<rootDir>/../../node_modules/rxjs/dist/bundles/rxjs.umd.js',
},
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
setupFilesAfterEnv: ['<rootDir>/setup-jest-esm.ts'],
}

export default jestConfig;
2 changes: 2 additions & 0 deletions examples/example-app-monorepo/apps/app1/setup-jest-esm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import 'jest-preset-angular/setup-jest.mjs';
import './jest-global-mocks';
10 changes: 1 addition & 9 deletions examples/example-app-monorepo/apps/app1/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
// Can't use standard setup-jest, b/c it uses require()
// import 'jest-preset-angular/setup-jest';

import 'zone.js/fesm2015/zone-testing-bundle.min.js';
import 'jest-preset-angular/setup-jest';
import './jest-global-mocks';

import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
9 changes: 5 additions & 4 deletions examples/example-app-monorepo/libs/user/jest-esm.config.mjs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import ngPreset from 'jest-preset-angular/presets/index.js';

/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
const jestConfig = {
...ngPreset.defaultsESM,
displayName: 'user-lib',
preset: 'jest-preset-angular/presets/defaults-esm',
globals: {
'ts-jest': {
useESM: true,
stringifyContentPathRegex: '\\.(html|svg)$',
...ngPreset.defaultsESM.globals["ts-jest"],
tsconfig: '<rootDir>/tsconfig-esm.spec.json',
},
},
moduleNameMapper: {
tslib: 'tslib/tslib.es6.js',
rxjs: '<rootDir>/../../node_modules/rxjs/dist/bundles/rxjs.umd.js',
},
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
setupFilesAfterEnv: ['<rootDir>/setup-jest-esm.ts'],
}

export default jestConfig;
2 changes: 2 additions & 0 deletions examples/example-app-monorepo/libs/user/setup-jest-esm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import 'jest-preset-angular/setup-jest.mjs';
import './jest-global-mocks';
10 changes: 1 addition & 9 deletions examples/example-app-monorepo/libs/user/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
// Can't use standard setup-jest, b/c it uses require()
// import 'jest-preset-angular/setup-jest';

import 'zone.js/fesm2015/zone-testing-bundle.min.js';
import 'jest-preset-angular/setup-jest';
import './jest-global-mocks';

import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
2 changes: 1 addition & 1 deletion examples/example-app-v11/jest-esm.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const jestConfig = {
},
},
globalSetup: 'jest-preset-angular/global-setup',
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
setupFilesAfterEnv: ['<rootDir>/setup-jest-esm.ts'],
}

export default jestConfig;
2 changes: 2 additions & 0 deletions examples/example-app-v11/setup-jest-esm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import 'jest-preset-angular/setup-jest.mjs';
import './jest-global-mocks';
2 changes: 1 addition & 1 deletion examples/example-app-v12/jest-esm.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const jestConfig = {
},
},
globalSetup: 'jest-preset-angular/global-setup',
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
setupFilesAfterEnv: ['<rootDir>/setup-jest-esm.ts'],
}

export default jestConfig;
2 changes: 2 additions & 0 deletions examples/example-app-v12/setup-jest-esm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import 'jest-preset-angular/setup-jest.mjs';
import './jest-global-mocks';
2 changes: 1 addition & 1 deletion examples/example-app-v13/jest-esm.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const jestConfig = {
tslib: 'tslib/tslib.es6.js',
rxjs: '<rootDir>/node_modules/rxjs/dist/bundles/rxjs.umd.js',
},
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
setupFilesAfterEnv: ['<rootDir>/setup-jest-esm.ts'],
}

export default jestConfig;
2 changes: 2 additions & 0 deletions examples/example-app-v13/setup-jest-esm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import 'jest-preset-angular/setup-jest.mjs';
import './jest-global-mocks';
10 changes: 1 addition & 9 deletions examples/example-app-v13/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
// Can't use standard setup-jest, b/c it uses require()
// import 'jest-preset-angular/setup-jest';

import 'zone.js/fesm2015/zone-testing-bundle.min.js';
import 'jest-preset-angular/setup-jest';
import './jest-global-mocks';

import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const jestConfig = {
tslib: 'tslib/tslib.es6.js',
rxjs: '<rootDir>/../../node_modules/rxjs/dist/bundles/rxjs.umd.js',
},
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
setupFilesAfterEnv: ['<rootDir>/setup-jest-esm.ts'],
}

export default jestConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import 'jest-preset-angular/setup-jest.mjs';
import './jest-global-mocks';
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
// Can't use standard setup-jest, b/c it uses require()
// import 'jest-preset-angular/setup-jest';

import 'zone.js/fesm2015/zone-testing-bundle.min.js';
import 'jest-preset-angular/setup-jest';
import './jest-global-mocks';

import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const jestConfig = {
tslib: 'tslib/tslib.es6.js',
rxjs: '<rootDir>/../../node_modules/rxjs/dist/bundles/rxjs.umd.js',
},
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
setupFilesAfterEnv: ['<rootDir>/setup-jest-esm.ts'],
}

export default jestConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import 'jest-preset-angular/setup-jest.mjs';
import './jest-global-mocks';
10 changes: 1 addition & 9 deletions examples/example-app-yarn-workspace/packages/user/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
// Can't use standard setup-jest, b/c it uses require()
// import 'jest-preset-angular/setup-jest';

import 'zone.js/fesm2015/zone-testing-bundle.min.js';
import 'jest-preset-angular/setup-jest';
import './jest-global-mocks';

import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
12 changes: 7 additions & 5 deletions scripts/test-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ const executeTest = (projectPath) => {
logger.log('installing bundled version of jest-preset-angular');
logger.log();

['build', 'presets', 'global-setup.js', 'jest-preset.js', 'package.json', 'setup-jest.js'].forEach((asset) => {
const assetToReplace = join(projectPath, 'node_modules', 'jest-preset-angular', asset);
const assetToCopy = join(rootDir, asset);
copySync(assetToCopy, assetToReplace, {});
});
['build', 'presets', 'global-setup.js', 'jest-preset.js', 'package.json', 'setup-jest.js', 'setup-jest.mjs'].forEach(
(asset) => {
const assetToReplace = join(projectPath, 'node_modules', 'jest-preset-angular', asset);
const assetToCopy = join(rootDir, asset);
copySync(assetToCopy, assetToReplace, {});
}
);

// then we can run the tests
const cmdLine = ['yarn', 'test'];
Expand Down
10 changes: 9 additions & 1 deletion setup-jest.js
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
module.exports = require('./build/config/setup-jest');
require('zone.js/bundles/zone-testing-bundle.umd');

const { getTestBed } = require('@angular/core/testing');
const {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting,
} = require('@angular/platform-browser-dynamic/testing');

getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
3 changes: 1 addition & 2 deletions src/config/setup-jest.ts → setup-jest.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'zone.js';
import 'zone.js/testing';
import 'zone.js/fesm2015/zone-testing-bundle.min.js';
import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

Expand Down
46 changes: 31 additions & 15 deletions src/config/setup-jest.spec.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
const mockInitTestEnvironment = jest.fn();
const mockZoneJs = jest.fn();
const mockZoneJsTesting = jest.fn();
const mockUmdZoneJs = jest.fn();
const mockEsmZoneJs = jest.fn();
const mockGetTestBed = jest.fn(() => {
return {
initTestEnvironment: mockInitTestEnvironment,
};
});
jest.mock('zone.js', () => {
const mockedResult = mockZoneJs();
jest.mock('zone.js/bundles/zone-testing-bundle.umd', () => {
const mockedResult = mockUmdZoneJs();

return {
mockedResult,
};
});
jest.mock('zone.js/testing', () => {
const mockedResult = mockZoneJsTesting();
jest.mock('zone.js/fesm2015/zone-testing-bundle.min.js', () => {
const mockedResult = mockEsmZoneJs();

return {
mockedResult,
Expand All @@ -36,14 +36,30 @@ jest.mock('@angular/platform-browser-dynamic/testing', () => {
};
});

test('should initialize test environment with getTestBed() and initTestEnvironment()', async () => {
await import('../config/setup-jest');
describe('setup-jest', () => {
const assertOnInitTestEnv = (): void => {
expect(mockGetTestBed).toHaveBeenCalled();
expect(mockInitTestEnvironment).toHaveBeenCalled();
expect(mockInitTestEnvironment.mock.calls[0][0]).toBeInstanceOf(BrowserDynamicTestingModuleStub);
expect(mockPlatformBrowserDynamicTesting).toHaveBeenCalled();
expect(mockPlatformBrowserDynamicTesting.mock.results[0].value).toBeInstanceOf(PlatformRefStub);
};

beforeEach(() => {
jest.clearAllMocks();
});

test('should initialize test environment with getTestBed() and initTestEnvironment() for CJS setup-jest', async () => {
await import('../../setup-jest');

expect(mockUmdZoneJs).toHaveBeenCalled();
assertOnInitTestEnv();
});

test('should initialize test environment with getTestBed() and initTestEnvironment() for ESM setup-jest', async () => {
await import('../../setup-jest.mjs');

expect(mockZoneJs).toHaveBeenCalled();
expect(mockZoneJsTesting).toHaveBeenCalled();
expect(mockGetTestBed).toHaveBeenCalled();
expect(mockInitTestEnvironment).toHaveBeenCalled();
expect(mockInitTestEnvironment.mock.calls[0][0]).toBeInstanceOf(BrowserDynamicTestingModuleStub);
expect(mockPlatformBrowserDynamicTesting).toHaveBeenCalled();
expect(mockPlatformBrowserDynamicTesting.mock.results[0].value).toBeInstanceOf(PlatformRefStub);
expect(mockEsmZoneJs).toHaveBeenCalled();
assertOnInitTestEnv();
});
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"compilerOptions": {
"baseUrl": "./",
"strict": true,
"allowJs": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
Expand Down
17 changes: 2 additions & 15 deletions website/docs/guides/angular-13+.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ title: Angular >=13

**Angular 13** introduces ESM package format for Angular packages. `jest-preset-angular`
currently supports testing with Jest in `CommonJS` mode with **Angular 13** using [default preset](../getting-started/presets.md).
Jest ESM support with **Angular 13** is new and may have issues.

:::important

Expand Down Expand Up @@ -70,25 +69,13 @@ Before upgrading to ng13 and switching to ES Modules, your `setup-jest.ts` file
```ts
// setup-jest.ts
import 'jest-preset-angular/setup-jest';
import './jest-global-mocks';
```

The `jest-preset-angular/setup-jest` file doesn't work with ESM, because it uses `require`. For now you should skip using this file, and replace the contents of your `setup-jest.ts` with:
or for ESM mode

```ts
// setup-jest.ts
import 'zone.js/fesm2015/zone-testing-bundle.min.js';
import './jest-global-mocks';

import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
teardown: {
destroyAfterEach: true, // Angular recommends this, but it may break existing tests
},
});
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
import 'jest-preset-angular/setup-jest.mjs';
```

## Potential issues with Angular 13 ESM package format and workaround
Expand Down
6 changes: 6 additions & 0 deletions website/docs/guides/esm-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ We have [example apps](https://github.com/thymikee/jest-preset-angular/tree/main

:::

Besides, there is `setup-jest.mjs` to add to Jest setup file to ensure that Jest can set up test environment properly.

```ts
import 'jest-preset-angular/setup-jest.mjs';
```

### Examples

#### Manual configuration
Expand Down