@naturalcycles/dev-lib 17.3.0 → 18.0.0
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.
- package/cfg/_cnst.d.ts +7 -0
- package/cfg/_cnst.js +21 -12
- package/cfg/commitlint.config.js +1 -1
- package/cfg/eslint-biome-rules.js +1 -1
- package/cfg/eslint-prettier-rules.js +1 -1
- package/cfg/eslint-rules.js +1 -1
- package/cfg/eslint-vue-rules.js +1 -1
- package/cfg/eslint.config.js +27 -23
- package/cfg/init/commitlint.config.js +4 -2
- package/cfg/init/eslint.config.js +5 -4
- package/cfg/init/lint-staged.config.js +4 -2
- package/cfg/init/prettier.config.js +3 -3
- package/cfg/init/{vitest.config.mts → vitest.config.ts} +1 -1
- package/cfg/lint-staged.config.js +8 -8
- package/cfg/prettier.config.js +1 -1
- package/cfg/stylelint.config.js +1 -1
- package/cfg/{vitest.config.mjs → vitest.config.js} +1 -1
- package/dist/bin/dev-lib.js +41 -48
- package/dist/bin/up.js +4 -6
- package/dist/bin/upnc.js +4 -6
- package/dist/build.util.d.ts +0 -1
- package/dist/build.util.js +12 -70
- package/dist/index.js +1 -2
- package/dist/init-from-dev-lib.command.js +5 -8
- package/dist/lint.util.js +56 -76
- package/dist/paths.js +10 -10
- package/dist/test.util.js +8 -127
- package/dist/testing/index.d.ts +2 -4
- package/dist/testing/index.js +5 -7
- package/dist/testing/mockAllKindsOfThings.js +3 -7
- package/dist/testing/{testOffline.util.js → testOffline.js} +3 -7
- package/dist/testing/testing.util.js +7 -11
- package/dist/testing/time.js +12 -0
- package/dist/yarn.util.js +12 -16
- package/package.json +5 -3
- package/readme.md +9 -24
- package/cfg/eslint-jest-rules.js +0 -14
- package/cfg/jest.alphabetic.sequencer.js +0 -13
- package/cfg/jest.config.js +0 -139
- package/cfg/jest.esbuild.transformer.js +0 -37
- package/cfg/jest.integration-test.config.js +0 -41
- package/cfg/jest.manual-test.config.js +0 -25
- package/dist/testing/time.util.js +0 -18
- /package/cfg/{vitest.config.d.mts → vitest.config.d.ts} +0 -0
- /package/cfg/{vitestAlphabeticSequencer.mjs → vitestAlphabeticSequencer.js} +0 -0
- /package/dist/testing/{testOffline.util.d.ts → testOffline.d.ts} +0 -0
- /package/dist/testing/{time.util.d.ts → time.d.ts} +0 -0
package/dist/lint.util.js
CHANGED
|
@@ -1,26 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
exports.lintStagedCommand = lintStagedCommand;
|
|
8
|
-
exports.runCommitlintCommand = runCommitlintCommand;
|
|
9
|
-
exports.requireActionlintVersion = requireActionlintVersion;
|
|
10
|
-
exports.getActionLintVersion = getActionLintVersion;
|
|
11
|
-
exports.runBiome = runBiome;
|
|
12
|
-
const node_child_process_1 = require("node:child_process");
|
|
13
|
-
const node_fs_1 = require("node:fs");
|
|
14
|
-
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
15
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
16
|
-
const paths_1 = require("./paths");
|
|
17
|
-
const { prettierDirs, prettierExtensionsAll, stylelintExtensions, eslintExtensions, lintExclude, minActionlintVersion, } = require('../cfg/_cnst');
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { _assert, _isTruthy, _since, _truncate, semver2 } from '@naturalcycles/js-lib';
|
|
4
|
+
import { _yargs, boldGrey, dimGrey, exec2, git2 } from '@naturalcycles/nodejs-lib';
|
|
5
|
+
import { eslintExtensions, lintExclude, minActionlintVersion, prettierDirs, prettierExtensionsAll, stylelintExtensions, } from '../cfg/_cnst.js';
|
|
6
|
+
import { cfgDir, scriptsDir } from './paths.js';
|
|
18
7
|
/**
|
|
19
8
|
* Run all linters.
|
|
20
9
|
*/
|
|
21
|
-
async function lintAllCommand() {
|
|
10
|
+
export async function lintAllCommand() {
|
|
22
11
|
const started = Date.now();
|
|
23
|
-
const { commitOnChanges, failOnChanges } =
|
|
12
|
+
const { commitOnChanges, failOnChanges } = _yargs().options({
|
|
24
13
|
commitOnChanges: {
|
|
25
14
|
type: 'boolean',
|
|
26
15
|
default: false,
|
|
@@ -42,23 +31,23 @@ async function lintAllCommand() {
|
|
|
42
31
|
// From this point we start the "slow" linters, with ESLint leading the way
|
|
43
32
|
// We run eslint BEFORE Prettier, because eslint can delete e.g unused imports.
|
|
44
33
|
await eslintAll();
|
|
45
|
-
if (
|
|
46
|
-
|
|
34
|
+
if (existsSync(`node_modules/stylelint`) &&
|
|
35
|
+
existsSync(`node_modules/stylelint-config-standard-scss`)) {
|
|
47
36
|
stylelintAll();
|
|
48
37
|
}
|
|
49
38
|
runPrettier();
|
|
50
39
|
await runKTLint();
|
|
51
|
-
console.log(`${
|
|
40
|
+
console.log(`${boldGrey('lint-all')} ${dimGrey(`took ` + _since(started))}`);
|
|
52
41
|
if (needToTrackChanges) {
|
|
53
42
|
const gitStatusAfter = gitStatus();
|
|
54
43
|
const hasChanges = gitStatusAfter !== gitStatusAtStart;
|
|
55
44
|
if (!hasChanges)
|
|
56
45
|
return;
|
|
57
|
-
const msg = 'style(ci): ' +
|
|
46
|
+
const msg = 'style(ci): ' + _truncate(git2.commitMessageToTitleMessage(git2.getLastGitCommitMsg()), 60);
|
|
58
47
|
// pull, commit, push changes
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
git2.pull();
|
|
49
|
+
git2.commitAll(msg);
|
|
50
|
+
git2.push();
|
|
62
51
|
// fail on changes
|
|
63
52
|
if (failOnChanges) {
|
|
64
53
|
console.log(gitStatusAfter);
|
|
@@ -70,9 +59,9 @@ async function lintAllCommand() {
|
|
|
70
59
|
/**
|
|
71
60
|
* Runs `eslint` command for all predefined paths (e.g /src, /scripts, etc).
|
|
72
61
|
*/
|
|
73
|
-
async function eslintAll(opt) {
|
|
62
|
+
export async function eslintAll(opt) {
|
|
74
63
|
const started = Date.now();
|
|
75
|
-
const { argv } =
|
|
64
|
+
const { argv } = _yargs().options({
|
|
76
65
|
ext: {
|
|
77
66
|
type: 'string',
|
|
78
67
|
default: eslintExtensions,
|
|
@@ -87,20 +76,10 @@ async function eslintAll(opt) {
|
|
|
87
76
|
...opt,
|
|
88
77
|
};
|
|
89
78
|
const extensions = ext.split(',');
|
|
90
|
-
const eslintConfigPathRoot = ['./eslint.config.js'
|
|
91
|
-
const eslintConfigPathScripts = [
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
'./eslint.config.js',
|
|
95
|
-
'./eslint.config.cjs',
|
|
96
|
-
].find(p => (0, node_fs_1.existsSync)(p));
|
|
97
|
-
const eslintConfigPathE2e = [
|
|
98
|
-
'./e2e/eslint.config.js',
|
|
99
|
-
'./e2e/eslint.config.cjs',
|
|
100
|
-
'./eslint.config.js',
|
|
101
|
-
'./eslint.config.cjs',
|
|
102
|
-
].find(p => (0, node_fs_1.existsSync)(p));
|
|
103
|
-
const tsconfigPathScripts = [`./scripts/tsconfig.json`].find(p => (0, node_fs_1.existsSync)(p)) || `${paths_1.scriptsDir}/tsconfig.json`;
|
|
79
|
+
const eslintConfigPathRoot = ['./eslint.config.js'].find(p => existsSync(p));
|
|
80
|
+
const eslintConfigPathScripts = ['./scripts/eslint.config.js', './eslint.config.js'].find(p => existsSync(p));
|
|
81
|
+
const eslintConfigPathE2e = ['./e2e/eslint.config.js', './eslint.config.js'].find(p => existsSync(p));
|
|
82
|
+
const tsconfigPathScripts = [`./scripts/tsconfig.json`].find(p => existsSync(p)) || `${scriptsDir}/tsconfig.json`;
|
|
104
83
|
const tsconfigPathE2e = `./e2e/tsconfig.json`;
|
|
105
84
|
// todo: run on other dirs too, e.g pages, components, layouts
|
|
106
85
|
if (fix) {
|
|
@@ -122,12 +101,12 @@ async function eslintAll(opt) {
|
|
|
122
101
|
// /e2e
|
|
123
102
|
await runESLint(`./e2e`, eslintConfigPathE2e, tsconfigPathE2e, extensions, fix);
|
|
124
103
|
}
|
|
125
|
-
console.log(`${
|
|
104
|
+
console.log(`${boldGrey('eslint-all')} ${dimGrey(`took ` + _since(started))}`);
|
|
126
105
|
}
|
|
127
|
-
async function runESLint(dir, eslintConfigPath, tsconfigPath, extensions = eslintExtensions, fix = true) {
|
|
128
|
-
if (!eslintConfigPath || !
|
|
106
|
+
async function runESLint(dir, eslintConfigPath, tsconfigPath, extensions = eslintExtensions.split(','), fix = true) {
|
|
107
|
+
if (!eslintConfigPath || !existsSync(dir))
|
|
129
108
|
return; // faster to bail-out like this
|
|
130
|
-
await
|
|
109
|
+
await exec2.spawnAsync('eslint', {
|
|
131
110
|
args: [
|
|
132
111
|
`--config`,
|
|
133
112
|
eslintConfigPath,
|
|
@@ -148,12 +127,12 @@ const prettierPaths = [
|
|
|
148
127
|
// Exclude
|
|
149
128
|
...lintExclude.map((s) => `!${s}`),
|
|
150
129
|
];
|
|
151
|
-
function runPrettier() {
|
|
152
|
-
const prettierConfigPath = [`./prettier.config.js
|
|
130
|
+
export function runPrettier() {
|
|
131
|
+
const prettierConfigPath = [`./prettier.config.js`].find(f => existsSync(f));
|
|
153
132
|
if (!prettierConfigPath)
|
|
154
133
|
return;
|
|
155
134
|
// prettier --write 'src/**/*.{js,ts,css,scss,graphql}'
|
|
156
|
-
|
|
135
|
+
exec2.spawn('prettier', {
|
|
157
136
|
args: [`--write`, `--log-level=warn`, `--config`, prettierConfigPath, ...prettierPaths],
|
|
158
137
|
shell: false,
|
|
159
138
|
});
|
|
@@ -164,25 +143,25 @@ const stylelintPaths = [
|
|
|
164
143
|
// Exclude
|
|
165
144
|
...lintExclude.map((s) => `!${s}`),
|
|
166
145
|
];
|
|
167
|
-
function stylelintAll() {
|
|
168
|
-
const { fix } =
|
|
146
|
+
export function stylelintAll() {
|
|
147
|
+
const { fix } = _yargs().options({
|
|
169
148
|
fix: {
|
|
170
149
|
type: 'boolean',
|
|
171
150
|
default: true,
|
|
172
151
|
},
|
|
173
152
|
}).argv;
|
|
174
|
-
const config = [`./stylelint.config.js`].find(f =>
|
|
153
|
+
const config = [`./stylelint.config.js`].find(f => existsSync(f));
|
|
175
154
|
if (!config)
|
|
176
155
|
return;
|
|
177
|
-
|
|
156
|
+
exec2.spawn('stylelint', {
|
|
178
157
|
args: [fix ? `--fix` : '', `--allow-empty-input`, `--config`, config, ...stylelintPaths].filter(Boolean),
|
|
179
158
|
shell: false,
|
|
180
159
|
});
|
|
181
160
|
}
|
|
182
|
-
async function lintStagedCommand() {
|
|
161
|
+
export async function lintStagedCommand() {
|
|
183
162
|
const localConfig = `./lint-staged.config.js`;
|
|
184
|
-
const sharedConfig = `${
|
|
185
|
-
const config =
|
|
163
|
+
const sharedConfig = `${cfgDir}/lint-staged.config.js`;
|
|
164
|
+
const config = existsSync(localConfig) ? localConfig : sharedConfig;
|
|
186
165
|
const { default: lintStaged } = await import('lint-staged');
|
|
187
166
|
const success = await lintStaged({
|
|
188
167
|
configPath: config,
|
|
@@ -190,18 +169,18 @@ async function lintStagedCommand() {
|
|
|
190
169
|
if (!success)
|
|
191
170
|
process.exit(3);
|
|
192
171
|
}
|
|
193
|
-
function runCommitlintCommand() {
|
|
172
|
+
export function runCommitlintCommand() {
|
|
194
173
|
const editMsg = process.argv.at(-1) || '.git/COMMIT_EDITMSG';
|
|
195
174
|
// console.log(editMsg)
|
|
196
175
|
const cwd = process.cwd();
|
|
197
176
|
const localConfig = `${cwd}/commitlint.config.js`;
|
|
198
|
-
const sharedConfig = `${
|
|
199
|
-
const config =
|
|
177
|
+
const sharedConfig = `${cfgDir}/commitlint.config.js`;
|
|
178
|
+
const config = existsSync(localConfig) ? localConfig : sharedConfig;
|
|
200
179
|
const env = {
|
|
201
|
-
GIT_BRANCH:
|
|
180
|
+
GIT_BRANCH: git2.getCurrentBranchName(),
|
|
202
181
|
};
|
|
203
182
|
// await execWithArgs(`commitlint`, [`--edit`, editMsg, `--config`, config], { env })
|
|
204
|
-
|
|
183
|
+
exec2.spawn(`node ./node_modules/.bin/commitlint --edit ${editMsg} --config ${config}`, {
|
|
205
184
|
env,
|
|
206
185
|
passProcessEnv: true, // important to pass it through, to preserve $PATH
|
|
207
186
|
forceColor: false,
|
|
@@ -209,36 +188,37 @@ function runCommitlintCommand() {
|
|
|
209
188
|
});
|
|
210
189
|
}
|
|
211
190
|
async function runKTLint() {
|
|
212
|
-
if (!
|
|
191
|
+
if (!existsSync(`node_modules/@naturalcycles/ktlint`))
|
|
213
192
|
return;
|
|
214
|
-
|
|
193
|
+
// @ts-expect-error ktlint is not installed, but it's ok
|
|
194
|
+
const { default: ktlintLib } = await import('@naturalcycles/ktlint');
|
|
215
195
|
await ktlintLib.ktlintAll();
|
|
216
196
|
}
|
|
217
197
|
function runActionLint() {
|
|
218
198
|
// Only run if there is a folder of `.github/workflows`, otherwise actionlint will fail
|
|
219
|
-
if (!
|
|
199
|
+
if (!existsSync('.github/workflows'))
|
|
220
200
|
return;
|
|
221
201
|
if (canRunBinary('actionlint')) {
|
|
222
202
|
requireActionlintVersion();
|
|
223
|
-
|
|
203
|
+
exec2.spawn(`actionlint`);
|
|
224
204
|
}
|
|
225
205
|
else {
|
|
226
206
|
console.log(`actionlint is not installed and won't be run.\nThis is how to install it: https://github.com/rhysd/actionlint/blob/main/docs/install.md`);
|
|
227
207
|
}
|
|
228
208
|
}
|
|
229
|
-
function requireActionlintVersion() {
|
|
209
|
+
export function requireActionlintVersion() {
|
|
230
210
|
const version = getActionLintVersion();
|
|
231
211
|
if (!version) {
|
|
232
212
|
return;
|
|
233
213
|
}
|
|
234
|
-
|
|
214
|
+
_assert(semver2(version).isSameOrAfter(minActionlintVersion), `actionlint needs to be updated. Min accepted version: ${minActionlintVersion}, local version: ${version}\nThis is how to install/update it: https://github.com/rhysd/actionlint/blob/main/docs/install.md`);
|
|
235
215
|
}
|
|
236
|
-
function getActionLintVersion() {
|
|
216
|
+
export function getActionLintVersion() {
|
|
237
217
|
if (!canRunBinary('actionlint'))
|
|
238
218
|
return;
|
|
239
|
-
return
|
|
219
|
+
return exec2.exec('actionlint --version').split('\n')[0];
|
|
240
220
|
}
|
|
241
|
-
function runBiome(fix = true) {
|
|
221
|
+
export function runBiome(fix = true) {
|
|
242
222
|
// if (!fs.existsSync(`node_modules/@biomejs/biome`)) {
|
|
243
223
|
// if (verbose) {
|
|
244
224
|
// console.log(`biome is not installed (checked in node_modules/@biomejs/biome), skipping`)
|
|
@@ -246,20 +226,20 @@ function runBiome(fix = true) {
|
|
|
246
226
|
// return
|
|
247
227
|
// }
|
|
248
228
|
const configPath = `biome.jsonc`;
|
|
249
|
-
if (!
|
|
229
|
+
if (!existsSync(configPath)) {
|
|
250
230
|
console.log(`biome is skipped, because ./biome.jsonc is not present`);
|
|
251
231
|
return;
|
|
252
232
|
}
|
|
253
|
-
const dirs = [`src`, `scripts`, `e2e`].filter(d =>
|
|
254
|
-
|
|
255
|
-
args: [`lint`, fix && '--write', fix && '--unsafe', '--no-errors-on-unmatched', ...dirs].filter(
|
|
233
|
+
const dirs = [`src`, `scripts`, `e2e`].filter(d => existsSync(d));
|
|
234
|
+
exec2.spawn(`biome`, {
|
|
235
|
+
args: [`lint`, fix && '--write', fix && '--unsafe', '--no-errors-on-unmatched', ...dirs].filter(_isTruthy),
|
|
256
236
|
logFinish: false,
|
|
257
237
|
shell: false,
|
|
258
238
|
});
|
|
259
239
|
}
|
|
260
240
|
function canRunBinary(name) {
|
|
261
241
|
try {
|
|
262
|
-
|
|
242
|
+
execSync(`which ${name}`);
|
|
263
243
|
return true;
|
|
264
244
|
}
|
|
265
245
|
catch {
|
|
@@ -268,7 +248,7 @@ function canRunBinary(name) {
|
|
|
268
248
|
}
|
|
269
249
|
function gitStatus() {
|
|
270
250
|
try {
|
|
271
|
-
return
|
|
251
|
+
return execSync('git status -s', {
|
|
272
252
|
encoding: 'utf8',
|
|
273
253
|
});
|
|
274
254
|
}
|
package/dist/paths.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { dirname, join } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = dirname(__filename);
|
|
5
|
+
export const projectDir = join(__dirname, '..');
|
|
6
|
+
export const srcDir = `${projectDir}/src`;
|
|
7
|
+
export const testDir = `${srcDir}/test`;
|
|
8
|
+
export const cfgDir = `${projectDir}/cfg`;
|
|
9
|
+
export const cfgOverwriteDir = `${projectDir}/cfg/overwrite`;
|
|
10
|
+
export const scriptsDir = `${projectDir}/scripts`;
|
package/dist/test.util.js
CHANGED
|
@@ -1,20 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
7
|
-
const paths_1 = require("./paths");
|
|
8
|
-
function runTest(opt = {}) {
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { _uniq } from '@naturalcycles/js-lib';
|
|
3
|
+
import { dimGrey, exec2 } from '@naturalcycles/nodejs-lib';
|
|
4
|
+
export function runTest(opt = {}) {
|
|
9
5
|
if (nodeModuleExists('vitest')) {
|
|
10
6
|
runVitest(opt);
|
|
11
7
|
return;
|
|
12
8
|
}
|
|
13
|
-
|
|
14
|
-
runJest(opt);
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
console.log((0, nodejs_lib_1.dimGrey)(`vitest/jest not found, skipping tests`));
|
|
9
|
+
console.log(dimGrey(`vitest not found, skipping tests`));
|
|
18
10
|
}
|
|
19
11
|
function runVitest(opt) {
|
|
20
12
|
const { integration, manual } = opt;
|
|
@@ -31,127 +23,16 @@ function runVitest(opt) {
|
|
|
31
23
|
TEST_TYPE: 'manual',
|
|
32
24
|
});
|
|
33
25
|
}
|
|
34
|
-
|
|
35
|
-
args:
|
|
26
|
+
exec2.spawn('vitest', {
|
|
27
|
+
args: _uniq(args),
|
|
36
28
|
logFinish: false,
|
|
37
29
|
shell: false,
|
|
38
30
|
env,
|
|
39
31
|
});
|
|
40
32
|
}
|
|
41
|
-
/**
|
|
42
|
-
* 1. Adds `--silent` if running all tests at once.
|
|
43
|
-
*/
|
|
44
|
-
function runJest(opt) {
|
|
45
|
-
const { CI, CPU_LIMIT, TZ = 'UTC', APP_ENV, JEST_NO_ALPHABETIC, JEST_SHARDS } = process.env;
|
|
46
|
-
const cpuLimit = Number(CPU_LIMIT) || undefined;
|
|
47
|
-
const { integration, manual, leaks } = opt;
|
|
48
|
-
const processArgs = process.argv.slice(3);
|
|
49
|
-
let jestConfig;
|
|
50
|
-
if (manual) {
|
|
51
|
-
jestConfig = getJestManualConfigPath();
|
|
52
|
-
}
|
|
53
|
-
else if (integration) {
|
|
54
|
-
jestConfig = getJestIntegrationConfigPath();
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
jestConfig = getJestConfigPath();
|
|
58
|
-
}
|
|
59
|
-
if (!jestConfig) {
|
|
60
|
-
console.log((0, nodejs_lib_1.dimGrey)(`./jest.config.js not found, skipping jest`));
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
// Allow to override --maxWorkers
|
|
64
|
-
let maxWorkers = processArgs.find(a => a.startsWith('--maxWorkers'));
|
|
65
|
-
const args = [
|
|
66
|
-
`--config=${jestConfig}`,
|
|
67
|
-
'--logHeapUsage',
|
|
68
|
-
'--passWithNoTests',
|
|
69
|
-
...processArgs,
|
|
70
|
-
];
|
|
71
|
-
const env = {
|
|
72
|
-
TZ,
|
|
73
|
-
DEBUG_COLORS: '1',
|
|
74
|
-
};
|
|
75
|
-
if (CI) {
|
|
76
|
-
args.push('--ci');
|
|
77
|
-
// Works with both --coverage=false and --no-coverage syntaxes
|
|
78
|
-
if (!integration && !manual && !processArgs.some(a => a.includes('-coverage'))) {
|
|
79
|
-
// Coverage only makes sense for unit tests, not for integration/manual
|
|
80
|
-
args.push('--coverage');
|
|
81
|
-
}
|
|
82
|
-
if (!maxWorkers && cpuLimit && cpuLimit > 1) {
|
|
83
|
-
maxWorkers = `--maxWorkers=${cpuLimit - 1}`;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// Running all tests - will use `--silent` to suppress console-logs, will also set process.env.JEST_SILENT=1
|
|
87
|
-
if (CI || isRunningAllTests()) {
|
|
88
|
-
args.push('--silent');
|
|
89
|
-
}
|
|
90
|
-
if (leaks) {
|
|
91
|
-
args.push('--detectOpenHandles', '--detectLeaks');
|
|
92
|
-
maxWorkers ||= '--maxWorkers=1';
|
|
93
|
-
}
|
|
94
|
-
if (maxWorkers)
|
|
95
|
-
args.push(maxWorkers);
|
|
96
|
-
if (args.includes('--silent')) {
|
|
97
|
-
Object.assign(env, {
|
|
98
|
-
JEST_SILENT: '1',
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
if (!integration && !manual && !APP_ENV) {
|
|
102
|
-
Object.assign(env, {
|
|
103
|
-
APP_ENV: 'test',
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
if (!JEST_NO_ALPHABETIC) {
|
|
107
|
-
args.push(`--testSequencer=${paths_1.cfgDir}/jest.alphabetic.sequencer.js`);
|
|
108
|
-
}
|
|
109
|
-
if (JEST_SHARDS) {
|
|
110
|
-
const totalShards = Number(JEST_SHARDS);
|
|
111
|
-
const shards = (0, js_lib_1._range)(1, totalShards + 1);
|
|
112
|
-
for (const shard of shards) {
|
|
113
|
-
nodejs_lib_1.exec2.spawn('jest', {
|
|
114
|
-
args: (0, js_lib_1._uniq)([...args, `--shard=${shard}/${totalShards}`]),
|
|
115
|
-
logFinish: false,
|
|
116
|
-
shell: false,
|
|
117
|
-
env,
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
nodejs_lib_1.exec2.spawn('jest', {
|
|
123
|
-
args: (0, js_lib_1._uniq)(args),
|
|
124
|
-
logFinish: false,
|
|
125
|
-
shell: false,
|
|
126
|
-
env,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
33
|
/**
|
|
131
34
|
* Returns true if module with given name exists in _target project's_ node_modules.
|
|
132
35
|
*/
|
|
133
36
|
function nodeModuleExists(moduleName) {
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
function getJestConfigPath() {
|
|
137
|
-
return (0, node_fs_1.existsSync)(`./jest.config.js`) ? './jest.config.js' : undefined;
|
|
138
|
-
}
|
|
139
|
-
function getJestIntegrationConfigPath() {
|
|
140
|
-
return (0, node_fs_1.existsSync)(`./jest.integration-test.config.js`)
|
|
141
|
-
? `./jest.integration-test.config.js`
|
|
142
|
-
: `${paths_1.cfgDir}/jest.integration-test.config.js`;
|
|
143
|
-
}
|
|
144
|
-
function getJestManualConfigPath() {
|
|
145
|
-
return (0, node_fs_1.existsSync)(`./jest.manual-test.config.js`)
|
|
146
|
-
? `./jest.manual-test.config.js`
|
|
147
|
-
: `${paths_1.cfgDir}/jest.manual-test.config.js`;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Detects if jest is run with all tests, or with specific tests.
|
|
151
|
-
*/
|
|
152
|
-
function isRunningAllTests() {
|
|
153
|
-
const args = process.argv.slice(3);
|
|
154
|
-
const positionalArgs = args.filter(a => !a.startsWith('-'));
|
|
155
|
-
// console.log(process.argv, positionalArgs)
|
|
156
|
-
return !positionalArgs.length;
|
|
37
|
+
return existsSync(`./node_modules/${moduleName}`);
|
|
157
38
|
}
|
package/dist/testing/index.d.ts
CHANGED
package/dist/testing/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
tslib_1.__exportStar(require("./testOffline.util"), exports);
|
|
7
|
-
tslib_1.__exportStar(require("./time.util"), exports);
|
|
1
|
+
export * from './mockAllKindsOfThings.js';
|
|
2
|
+
export * from './testing.util.js';
|
|
3
|
+
// Not included in the barrel file, since they import other dependencies
|
|
4
|
+
// export * from './testOffline.util.js'
|
|
5
|
+
// export * from './time.util.js'
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.mockAllKindsOfThings = void 0;
|
|
4
|
-
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
|
-
const mockAllKindsOfThings = () => {
|
|
1
|
+
import { AppError } from '@naturalcycles/js-lib';
|
|
2
|
+
export const mockAllKindsOfThings = () => {
|
|
6
3
|
const errorWithCode = new Error('Error with code');
|
|
7
4
|
Object.assign(errorWithCode, {
|
|
8
5
|
code: `auth/forbidden`,
|
|
@@ -43,11 +40,10 @@ const mockAllKindsOfThings = () => {
|
|
|
43
40
|
new Set(['a', 'b', 'c']),
|
|
44
41
|
new Error('some err msg'),
|
|
45
42
|
errorWithCode,
|
|
46
|
-
new
|
|
43
|
+
new AppError('app error', {
|
|
47
44
|
k1: 'v1',
|
|
48
45
|
}),
|
|
49
46
|
Symbol('a_am_symbol'),
|
|
50
47
|
new Date(1984, 5, 21),
|
|
51
48
|
];
|
|
52
49
|
};
|
|
53
|
-
exports.mockAllKindsOfThings = mockAllKindsOfThings;
|
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.testOffline = testOffline;
|
|
4
|
-
exports.testOnline = testOnline;
|
|
1
|
+
import createMitm from 'mitm';
|
|
5
2
|
const LOCAL_HOSTS = ['localhost', '127.0.0.1'];
|
|
6
3
|
const detectLeaks = process.argv.some(a => a.includes('detectLeaks'));
|
|
7
4
|
let mitm;
|
|
8
5
|
/**
|
|
9
6
|
* Based on: https://github.com/palmerj3/jest-offline/blob/master/index.js
|
|
10
7
|
*/
|
|
11
|
-
function testOffline() {
|
|
8
|
+
export function testOffline() {
|
|
12
9
|
if (detectLeaks) {
|
|
13
10
|
console.log('NOT applying testOffline() when --detectLeaks is on');
|
|
14
11
|
return;
|
|
15
12
|
}
|
|
16
13
|
console.log('test offline mode');
|
|
17
|
-
const createMitm = require('mitm');
|
|
18
14
|
mitm ||= createMitm();
|
|
19
15
|
mitm.on('connect', (socket, opts) => {
|
|
20
16
|
const { host } = opts;
|
|
@@ -27,6 +23,6 @@ function testOffline() {
|
|
|
27
23
|
/**
|
|
28
24
|
* Undo/reset the testOffline() function by allowing network calls again.
|
|
29
25
|
*/
|
|
30
|
-
function testOnline() {
|
|
26
|
+
export function testOnline() {
|
|
31
27
|
mitm?.disable();
|
|
32
28
|
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
exports.silentConsole = silentConsole;
|
|
5
|
-
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
7
|
-
function silentConsole() {
|
|
1
|
+
import { commonLoggerCreate } from '@naturalcycles/js-lib';
|
|
2
|
+
import { _inspect } from '@naturalcycles/nodejs-lib';
|
|
3
|
+
export function silentConsole() {
|
|
8
4
|
console.log = () => { };
|
|
9
5
|
console.debug = () => { };
|
|
10
6
|
console.info = () => { };
|
|
@@ -13,13 +9,13 @@ function silentConsole() {
|
|
|
13
9
|
console.time = () => { };
|
|
14
10
|
console.table = () => { };
|
|
15
11
|
}
|
|
16
|
-
|
|
17
|
-
if (process.env['
|
|
12
|
+
export const testLogger = commonLoggerCreate((_level, args) => {
|
|
13
|
+
if (process.env['TEST_SILENT'])
|
|
18
14
|
return; // no-op
|
|
19
15
|
process.stdout.write(args
|
|
20
|
-
.map(a =>
|
|
16
|
+
.map(a => _inspect(a, {
|
|
21
17
|
includeErrorStack: true,
|
|
22
18
|
}))
|
|
23
19
|
.join(' ') + '\n');
|
|
24
20
|
});
|
|
25
|
-
|
|
21
|
+
export const testLog = testLogger.log.bind(testLogger);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import timekeeper from 'timekeeper';
|
|
2
|
+
export const MOCK_TS_2018_06_21 = 1_529_539_200;
|
|
3
|
+
/**
|
|
4
|
+
* Locks time-related functions to return always same time.
|
|
5
|
+
* For deterministic tests.
|
|
6
|
+
*/
|
|
7
|
+
export function mockTime(ts = MOCK_TS_2018_06_21) {
|
|
8
|
+
timekeeper.freeze(ts * 1000);
|
|
9
|
+
}
|
|
10
|
+
export function resetTime() {
|
|
11
|
+
timekeeper.reset();
|
|
12
|
+
}
|
package/dist/yarn.util.js
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
nodejs_lib_1.exec2.spawn('yarn-deduplicate');
|
|
10
|
-
nodejs_lib_1.exec2.spawn('yarn');
|
|
11
|
-
if ((0, node_fs_1.existsSync)(`node_modules/patch-package`)) {
|
|
12
|
-
nodejs_lib_1.exec2.spawn('patch-package');
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { exec2 } from '@naturalcycles/nodejs-lib';
|
|
3
|
+
export function up() {
|
|
4
|
+
exec2.spawn('yarn upgrade');
|
|
5
|
+
exec2.spawn('yarn-deduplicate');
|
|
6
|
+
exec2.spawn('yarn');
|
|
7
|
+
if (existsSync(`node_modules/patch-package`)) {
|
|
8
|
+
exec2.spawn('patch-package');
|
|
13
9
|
}
|
|
14
10
|
}
|
|
15
|
-
function upnc() {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
export function upnc() {
|
|
12
|
+
exec2.spawn('yarn upgrade --pattern @naturalcycles');
|
|
13
|
+
exec2.spawn('yarn-deduplicate');
|
|
14
|
+
exec2.spawn('yarn');
|
|
19
15
|
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/dev-lib",
|
|
3
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "18.0.0",
|
|
4
5
|
"scripts": {
|
|
5
6
|
"prepare": "husky",
|
|
6
|
-
"
|
|
7
|
+
"tsx-debug": "tsx scripts/testScript.ts",
|
|
7
8
|
"dev-lib": "tsx ./src/bin/dev-lib.ts",
|
|
8
9
|
"bt": "tsx ./src/bin/dev-lib.ts bt && tsx scripts/eslintPrintConfig.script.ts",
|
|
9
10
|
"lbt": "tsx ./src/bin/dev-lib.ts lbt && tsx scripts/eslintPrintConfig.script.ts",
|
|
10
11
|
"build": "tsx ./src/bin/dev-lib.ts build",
|
|
11
|
-
"build-prod-esm-cjs": "tsx ./src/bin/dev-lib.ts build-esm-cjs",
|
|
12
12
|
"test": "tsx ./src/bin/dev-lib.ts test",
|
|
13
13
|
"test-leaks": "tsx ./src/bin/dev-lib.ts test-leaks",
|
|
14
14
|
"test-integration": "tsx ./src/bin/dev-lib.ts test-integration",
|
|
15
15
|
"test-manual": "tsx ./src/bin/dev-lib.ts test-manual",
|
|
16
16
|
"lint": "tsx ./src/bin/dev-lib.ts lint",
|
|
17
|
+
"lint-staged-debug": "tsx ./src/bin/dev-lib.ts lint-staged",
|
|
17
18
|
"up": "tsx ./src/bin/up.ts",
|
|
18
19
|
"upnc": "tsx ./src/bin/upnc.ts"
|
|
19
20
|
},
|
|
@@ -45,6 +46,7 @@
|
|
|
45
46
|
"vue-eslint-parser": "^10"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
49
|
+
"@types/mitm": "^1.3.8",
|
|
48
50
|
"@vitest/coverage-v8": "^3",
|
|
49
51
|
"stylelint": "^16",
|
|
50
52
|
"stylelint-config-standard-scss": "^14",
|