Skip to content

Commit ac283b7

Browse files
authored
chore: 🤖 migrate to esm (#177)
BREAKING CHANGE: 🧨 The lib is now ESM
1 parent dd47f5f commit ac283b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+9789
-7718
lines changed

‎__tests__/buildTranslationFiles.spec.ts‎

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
import fs from 'fs-extra';
2-
import {jest} from '@jest/globals';
2+
import { jest } from '@jest/globals';
33

4-
import { buildTranslationFiles } from '../src/keys-builder';
5-
import { getCurrentTranslation } from '../src/keys-builder/utils/get-current-translation';
64
import { resetScopes } from '../src/keys-builder/utils/scope.utils';
75
import { messages } from '../src/messages';
86
import { Config, FileFormats, Translation } from '../src/types';
9-
import { resolveProjectBasePath } from '../src/utils/resolve-project-base-path';
10-
11-
jest.mock('../src/utils/resolve-project-base-path');
7+
import {
8+
spyOnConsole,
9+
spyOnProcess,
10+
mockResolveProjectBasePath,
11+
} from './utils';
1212

1313
const sourceRoot = '__tests__';
14+
mockResolveProjectBasePath(sourceRoot);
15+
16+
/**
17+
* With ESM modules, you need to mock the modules beforehand (with jest.unstable_mockModule) and import them ashynchronously afterwards.
18+
* This thing is still in WIP at Jest, so keep an eye on it.
19+
* @see https://jestjs.io/docs/ecmascript-modules#module-mocking-in-esm
20+
*/
21+
const { buildTranslationFiles } = await import('../src/keys-builder');
22+
const { getCurrentTranslation } = await import(
23+
'../src/keys-builder/utils/get-current-translation'
24+
);
1425

1526
const defaultValue = 'missing';
1627

@@ -30,10 +41,7 @@ function generateKeys({
3041
return keys;
3142
}
3243

33-
function gConfig(
34-
type: TranslationCategory,
35-
config: Partial<Config> = {}
36-
) {
44+
function gConfig(type: TranslationCategory, config: Partial<Config> = {}) {
3745
return {
3846
input: [`${type}`],
3947
output: `${type}/i18n`,
@@ -86,8 +94,8 @@ function assertPartialTranslation({
8694

8795
function loadTranslationFile(
8896
type: TranslationCategory,
89-
path: string,
90-
fileFormat: FileFormats
97+
path: string | undefined,
98+
fileFormat: FileFormats,
9199
) {
92100
return getCurrentTranslation({
93101
path: `./${sourceRoot}/${type}/i18n/${path || ''}en.${fileFormat}`,
@@ -107,9 +115,8 @@ describe.each(formats)('buildTranslationFiles in %s', (fileFormat) => {
107115
}
108116

109117
beforeAll(() => {
110-
(resolveProjectBasePath as any).mockImplementation(() => {
111-
return { projectBasePath: sourceRoot };
112-
});
118+
spyOnConsole('warn');
119+
spyOnProcess('exit');
113120
});
114121

115122
// Reset to ensure the scopes are not being shared among the tests.
@@ -157,7 +164,7 @@ describe.each(formats)('buildTranslationFiles in %s', (fileFormat) => {
157164
['Processing archive...', 'Restore Options'].forEach(
158165
(nonNumericKey) => {
159166
expected[nonNumericKey] = defaultValue;
160-
}
167+
},
161168
);
162169
createTranslations(config);
163170
assertTranslation({ type, expected, fileFormat });
@@ -370,7 +377,7 @@ describe.each(formats)('buildTranslationFiles in %s', (fileFormat) => {
370377
['Processing archive...', 'Restore Options'].forEach(
371378
(nonNumericKey) => {
372379
expected[nonNumericKey] = defaultValue;
373-
}
380+
},
374381
);
375382
createTranslations(config);
376383
assertTranslation({ type, expected, fileFormat });
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
export const v = {
2-
provide: TRANSLOCO_SCOPE,
3-
useValue: ['nested/scope', 'todos-page'],
4-
};
1+
export const v = { provide: TRANSLOCO_SCOPE, useValue: 'todos-page' };

‎__tests__/resolveConfig.spec.ts‎

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
11
import chalk from 'chalk';
22
import path from 'node:path';
3-
import {jest} from '@jest/globals';
4-
import type { SpyInstance } from "jest-mock";
3+
import { jest } from '@jest/globals';
4+
import type { SpyInstance } from 'jest-mock';
55

66
import { defaultConfig as _defaultConfig } from '../src/config';
77
import { messages } from '../src/messages';
88

9-
import { noop, spyOnLog } from './utils';
9+
import {
10+
spyOnConsole,
11+
spyOnProcess,
12+
mockResolveProjectBasePath,
13+
} from './utils';
1014

1115
const sourceRoot = '__tests__';
1216
let mockedGloblConfig;
13-
jest.mock('../src/utils/resolve-project-base-path', () => {
14-
return {
15-
resolveProjectBasePath: () => {
16-
return { projectBasePath: sourceRoot };
17-
}
18-
}
19-
});
20-
jest.mock('@ngneat/transloco-utils', () => {
21-
return {
22-
getGlobalConfig: () => mockedGloblConfig
23-
};
24-
});
2517

18+
mockResolveProjectBasePath(sourceRoot);
19+
20+
jest.unstable_mockModule('@ngneat/transloco-utils', () => ({
21+
getGlobalConfig: () => mockedGloblConfig,
22+
}));
23+
24+
/**
25+
* With ESM modules, you need to mock the modules beforehand (with jest.unstable_mockModule) and import them ashynchronously afterwards.
26+
* This thing is still in WIP at Jest, so keep an eye on it.
27+
* @see https://jestjs.io/docs/ecmascript-modules#module-mocking-in-esm
28+
*/
2629
const { resolveConfig } = await import('../src/utils/resolve-config');
2730

2831
describe('resolveConfig', () => {
@@ -38,10 +41,8 @@ describe('resolveConfig', () => {
3841

3942
beforeAll(() => {
4043
mockedGloblConfig = {};
41-
processExitSpy = jest
42-
.spyOn(process, 'exit')
43-
.mockImplementation(noop as any);
44-
consoleLogSpy = spyOnLog();
44+
processExitSpy = spyOnProcess('exit');
45+
consoleLogSpy = spyOnConsole('log');
4546
spies = [processExitSpy, consoleLogSpy];
4647
});
4748

@@ -107,7 +108,7 @@ describe('resolveConfig', () => {
107108
});
108109

109110
afterAll(() => {
110-
mockedGloblConfig = {}
111+
mockedGloblConfig = {};
111112
});
112113

113114
it('should merge the default and the transloco config', () => {
@@ -140,14 +141,14 @@ describe('resolveConfig', () => {
140141
function shouldFail(prop: string, msg: 'pathDoesntExist' | 'pathIsNotDir') {
141142
expect(processExitSpy).toHaveBeenCalled();
142143
expect(consoleLogSpy).toHaveBeenCalledWith(
143-
chalk.bgRed.black(`${prop} ${messages[msg]}`)
144+
chalk.bgRed.black(`${prop} ${messages[msg]}`),
144145
);
145146
clearSpies();
146147
}
147148

148149
function shouldPass() {
149150
[processExitSpy, consoleLogSpy].forEach((s) =>
150-
expect(s).not.toHaveBeenCalled()
151+
expect(s).not.toHaveBeenCalled(),
151152
);
152153
clearSpies();
153154
}
@@ -195,11 +196,11 @@ describe('resolveConfig', () => {
195196
const config = resolveConfig({ input: ['comments'] });
196197
const assertPath = (p) =>
197198
expect(p.startsWith(path.resolve(process.cwd(), sourceRoot))).toBe(
198-
true
199+
true,
199200
);
200201
config.input.forEach(assertPath);
201202
['output', 'translationsPath'].forEach((prop) =>
202-
assertPath(config[prop])
203+
assertPath(config[prop]),
203204
);
204205
});
205206
});

‎__tests__/resolveProjectBasePath.spec.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from 'path';
33

44
import { resolveProjectBasePath } from '../src/utils/resolve-project-base-path';
55

6-
import { spyOnLog } from './utils';
6+
import { spyOnConsole } from './utils';
77

88
const supportedConfigs = ['angular', 'workspace', 'project'] as const;
99
const myProjectConfig = { projectType: 'library', sourceRoot: 'myRoot' };
@@ -17,7 +17,7 @@ const defaultConfig = {
1717

1818
describe('resolveProjectBasePath', () => {
1919
it('should return the default "src"', () => {
20-
const spy = spyOnLog();
20+
const spy = spyOnConsole('log');
2121
expect(resolveProjectBasePath().projectBasePath).toBe('src');
2222
spy.mockRestore();
2323
});
@@ -134,7 +134,7 @@ function addProjectConfig({
134134
fs.mkdirsSync(resolvePath(path));
135135
fs.writeFileSync(
136136
jsonFile('project', path),
137-
'// comment\n' + JSON.stringify(config)
137+
'// comment\n' + JSON.stringify(config),
138138
);
139139
}
140140

@@ -154,7 +154,7 @@ function addRootConfig({
154154
}) {
155155
fs.writeFileSync(
156156
jsonFile(configType, path),
157-
'// comment\n' + JSON.stringify(config)
157+
'// comment\n' + JSON.stringify(config),
158158
);
159159
}
160160

‎__tests__/utils.ts‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
1-
import {jest} from '@jest/globals';
1+
import { jest } from '@jest/globals';
2+
import type { SpyInstance } from 'jest-mock';
23

34
export function noop() {}
45

5-
export function spyOnLog() {
6-
return jest.spyOn(console, 'log').mockImplementation(noop);
6+
export function spyOnConsole(method: 'log' | 'warn'): SpyInstance {
7+
return jest.spyOn(console, method).mockImplementation(noop);
8+
}
9+
10+
export function spyOnProcess(method: 'exit'): SpyInstance {
11+
return jest
12+
.spyOn(process, method)
13+
.mockImplementation(noop as any) as SpyInstance;
14+
}
15+
16+
export function mockResolveProjectBasePath(projectBasePath: string) {
17+
jest.unstable_mockModule('../src/utils/resolve-project-base-path.ts', () => ({
18+
resolveProjectBasePath: jest.fn().mockReturnValue({ projectBasePath }),
19+
}));
720
}

‎jest.config.mjs‎ renamed to ‎jest.config.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import type { Config } from 'jest';
12
import ngPreset from 'jest-preset-angular/presets/index.js';
23

3-
/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */
4-
const config = {
4+
const jestConfig: Config = {
55
...ngPreset.defaultsESM,
66
testMatch: ['**/__tests__/**/*.spec.ts'],
77
moduleNameMapper: {
@@ -21,4 +21,4 @@ const config = {
2121
},
2222
};
2323

24-
export default config;
24+
export default jestConfig;

0 commit comments

Comments
 (0)