poku 4.3.3-canary.894a7c91 → 4.4.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.
@@ -1,6 +1,6 @@
1
1
  import { stat } from "node:fs/promises";
2
2
  import { exit, argv } from "node:process";
3
- import { hr, log$1 as log, format, GLOBAL, getArg, reporter, hasArg } from "../modules/_shared.js";
3
+ import { hr, log$1 as log, format, GLOBAL, getArg, reporter, getPrefix, hasArg } from "../modules/_shared.js";
4
4
  import "node:path";
5
5
  import "node:os";
6
6
  import "node:child_process";
@@ -14,10 +14,10 @@ const errors = [], pathExists = async (arg, path) => {
14
14
  errors.push(`--${arg}: ./${path} doesn't exists.`);
15
15
  }
16
16
  }, checkUselessValue = (arg) => {
17
- const prefix = arg.length === 1 ? "-" : "--";
17
+ const prefix = getPrefix(arg);
18
18
  typeof getArg(arg, prefix) < "u" && errors.push(`${prefix}${arg}: this flag shouldn't receive a value.`);
19
19
  }, checkRequiredValue = (arg) => {
20
- const prefix = arg.length === 1 ? "-" : "--";
20
+ const prefix = getPrefix(arg);
21
21
  hasArg(arg, prefix) && typeof getArg(arg, prefix) > "u" && errors.push(`${prefix}${arg}: this flag require a value.`);
22
22
  }, checkFlags = () => {
23
23
  const allowedFlags = /* @__PURE__ */ new Set([
@@ -108,12 +108,9 @@ const errors = [], pathExists = async (arg, path) => {
108
108
  "exclude",
109
109
  "failFast",
110
110
  "envFile",
111
- "exclude",
112
- "failFast",
113
111
  "concurrency",
114
112
  "quiet",
115
113
  "timeout",
116
- "envFile",
117
114
  "kill",
118
115
  "isolation",
119
116
  "platform",
package/lib/bin/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { env, exit } from "node:process";
3
- import { GLOBAL, log$1 as log, format, isWindows, hasArg, VERSION, getArg, getPaths, argToArray, states, hr, escapeRegExp, kill, envFile, poku } from "../modules/_shared.js";
3
+ import { GLOBAL, log$1 as log, format, isWindows, hasArg, VERSION, getArg, getPaths, argToArray, numericArg, states, hr, toRegExp, kill, envFile, poku } from "../modules/_shared.js";
4
4
  import { existsSync } from "node:fs";
5
5
  import { readFile } from "node:fs/promises";
6
6
  import { join } from "node:path";
@@ -45,13 +45,7 @@ const getConfigs = async (customPath) => {
45
45
  }
46
46
  const enforce = hasArg("enforce") || hasArg("x", "-"), configFile = getArg("config") || getArg("c", "-");
47
47
  GLOBAL.configsFromFile = await getConfigs(configFile);
48
- const { configsFromFile } = GLOBAL, dirs = getPaths("-") ?? (configsFromFile?.include ? Array.prototype.concat(configsFromFile?.include) : ["."]), filter = getArg("filter") ?? configsFromFile?.filter, exclude = getArg("exclude") ?? configsFromFile?.exclude, killPort = getArg("killPort"), killRange = getArg("killRange"), killPID = getArg("killPid"), reporter = getArg("reporter") ?? getArg("r", "-") ?? GLOBAL.configsFromFile.reporter ?? "poku", denoAllow = argToArray("denoAllow") ?? configsFromFile?.deno?.allow, denoDeny = argToArray("denoDeny") ?? configsFromFile?.deno?.deny, quiet = hasArg("quiet") || hasArg("q", "-") || configsFromFile?.quiet, debug = hasArg("debug") || hasArg("d", "-") || configsFromFile?.debug, failFast = hasArg("failFast") || configsFromFile?.failFast, watchMode = hasArg("watch") || hasArg("w", "-"), hasEnvFile = hasArg("envFile"), concurrency = (() => {
49
- const value = Number(getArg("concurrency"));
50
- return Number.isNaN(value) ? configsFromFile?.concurrency : value;
51
- })(), timeout = (() => {
52
- const value = Number(getArg("timeout"));
53
- return Number.isNaN(value) ? configsFromFile?.timeout : value;
54
- })(), sequential = hasArg("sequential") || configsFromFile?.sequential, isolation = getArg("isolation") || configsFromFile?.isolation, testNamePattern = getArg("testNamePattern") ?? getArg("t", "-") ?? configsFromFile?.testNamePattern, testSkipPattern = getArg("testSkipPattern") ?? configsFromFile?.testSkipPattern;
48
+ const { configsFromFile } = GLOBAL, dirs = getPaths("-") ?? (configsFromFile?.include ? Array.prototype.concat(configsFromFile?.include) : ["."]), filter = getArg("filter") ?? configsFromFile?.filter, exclude = getArg("exclude") ?? configsFromFile?.exclude, killPort = getArg("killPort"), killRange = getArg("killRange"), killPID = getArg("killPid"), reporter = getArg("reporter") ?? getArg("r", "-") ?? GLOBAL.configsFromFile.reporter ?? "poku", denoAllow = argToArray("denoAllow") ?? configsFromFile?.deno?.allow, denoDeny = argToArray("denoDeny") ?? configsFromFile?.deno?.deny, quiet = hasArg("quiet") || hasArg("q", "-") || configsFromFile?.quiet, debug = hasArg("debug") || hasArg("d", "-") || configsFromFile?.debug, failFast = hasArg("failFast") || configsFromFile?.failFast, watchMode = hasArg("watch") || hasArg("w", "-"), hasEnvFile = hasArg("envFile"), concurrency = numericArg("concurrency", configsFromFile?.concurrency), timeout = numericArg("timeout", configsFromFile?.timeout), sequential = hasArg("sequential") || configsFromFile?.sequential, isolation = getArg("isolation") || configsFromFile?.isolation, testNamePattern = getArg("testNamePattern") ?? getArg("t", "-") ?? configsFromFile?.testNamePattern, testSkipPattern = getArg("testSkipPattern") ?? configsFromFile?.testSkipPattern;
55
49
  if (dirs.length === 1 && (states.isSinglePath = !0), hasArg("listFiles")) {
56
50
  const { listFiles } = await import("../modules/_shared.js").then(function(n) {
57
51
  return n.listFiles$1;
@@ -60,8 +54,8 @@ const getConfigs = async (customPath) => {
60
54
  for (const dir of dirs)
61
55
  files.push(
62
56
  ...await listFiles(dir, {
63
- filter: typeof filter == "string" ? new RegExp(escapeRegExp(filter)) : filter,
64
- exclude: typeof exclude == "string" ? new RegExp(escapeRegExp(exclude)) : exclude
57
+ filter: toRegExp(filter),
58
+ exclude: toRegExp(exclude)
65
59
  })
66
60
  );
67
61
  log(
@@ -71,8 +65,8 @@ const getConfigs = async (customPath) => {
71
65
  return;
72
66
  }
73
67
  if (GLOBAL.configFile = configFile, env.POKU_RUNTIME = GLOBAL.runtime, env.POKU_REPORTER = typeof reporter == "string" ? reporter : "poku", GLOBAL.configs = {
74
- filter: typeof filter == "string" ? new RegExp(escapeRegExp(filter)) : filter,
75
- exclude: typeof exclude == "string" ? new RegExp(escapeRegExp(exclude)) : exclude,
68
+ filter: toRegExp(filter),
69
+ exclude: toRegExp(exclude),
76
70
  concurrency,
77
71
  timeout,
78
72
  sequential,
@@ -86,8 +80,8 @@ const getConfigs = async (customPath) => {
86
80
  },
87
81
  noExit: watchMode,
88
82
  reporter,
89
- testNamePattern: typeof testNamePattern == "string" ? new RegExp(escapeRegExp(testNamePattern)) : testNamePattern,
90
- testSkipPattern: typeof testSkipPattern == "string" ? new RegExp(escapeRegExp(testSkipPattern)) : testSkipPattern,
83
+ testNamePattern: toRegExp(testNamePattern),
84
+ testSkipPattern: toRegExp(testSkipPattern),
91
85
  beforeEach: "beforeEach" in configsFromFile ? configsFromFile.beforeEach : void 0,
92
86
  afterEach: "afterEach" in configsFromFile ? configsFromFile.afterEach : void 0,
93
87
  plugins: "plugins" in configsFromFile ? configsFromFile.plugins : void 0
package/lib/bin/watch.js CHANGED
@@ -107,9 +107,9 @@ class Watcher {
107
107
  );
108
108
  this.fileWatchers.set(filePath, watcher);
109
109
  }
110
- unwatchFiles() {
111
- for (const [filePath, watcher] of this.fileWatchers)
112
- watcher.close(), this.fileWatchers.delete(filePath);
110
+ unwatchMap(watchers) {
111
+ for (const [path, watcher] of watchers)
112
+ watcher.close(), watchers.delete(path);
113
113
  }
114
114
  syncFileWatchers(filePaths) {
115
115
  const next = new Set(filePaths);
@@ -145,11 +145,7 @@ class Watcher {
145
145
  this.watchFile(this.rootDir);
146
146
  }
147
147
  stop() {
148
- this.unwatchFiles(), this.unwatchDirectories();
149
- }
150
- unwatchDirectories() {
151
- for (const [dirPath, watcher] of this.dirWatchers)
152
- watcher.close(), this.dirWatchers.delete(dirPath);
148
+ this.unwatchMap(this.fileWatchers), this.unwatchMap(this.dirWatchers);
153
149
  }
154
150
  }
155
151
  const watch = async (path, callback) => {
@@ -157,8 +153,10 @@ const watch = async (path, callback) => {
157
153
  return await watcher.start(), watcher;
158
154
  }, startWatch = async (dirs) => {
159
155
  let isRunning = !1;
160
- const { configs } = GLOBAL, watchers = /* @__PURE__ */ new Set(), executing = /* @__PURE__ */ new Set(), interval = Number(getArg("watchInterval")) || 1500, setIsRunning = (value) => {
161
- isRunning = value;
156
+ const { configs } = GLOBAL, watchers = /* @__PURE__ */ new Set(), executing = /* @__PURE__ */ new Set(), interval = Number(getArg("watchInterval")) || 1500, addWatcher = (pending) => {
157
+ pending.then((watcher) => {
158
+ watchers.add(watcher);
159
+ });
162
160
  }, resultsClear = () => {
163
161
  errors.length = 0, results.passed = 0, results.failed = 0, results.skipped = 0, results.todo = 0;
164
162
  }, listenStdin = async (input) => {
@@ -174,37 +172,37 @@ const watch = async (path, callback) => {
174
172
  configs.filter,
175
173
  configs.exclude
176
174
  );
177
- for (const mappedTest of Array.from(mappedTests.keys()))
178
- watch(mappedTest, async (file, event) => {
175
+ for (const mappedTest of Array.from(mappedTests.keys())) {
176
+ const currentWatcher = watch(mappedTest, async (file, event) => {
179
177
  if (event === "change") {
180
178
  const filePath = normalizePath(file);
181
179
  if (executing.has(filePath) || isRunning || executing.size > 0) return;
182
- setIsRunning(!0), executing.add(filePath), resultsClear();
180
+ isRunning = !0, executing.add(filePath), resultsClear();
183
181
  const tests = mappedTests.get(filePath);
184
182
  if (!tests) return;
185
183
  await poku(Array.from(tests), {
186
184
  ...configs,
187
185
  concurrency: configs.concurrency ?? Math.max(Math.floor(availableParallelism() / 2), 1)
188
186
  }), setTimeout(() => {
189
- executing.delete(filePath), setIsRunning(!1);
187
+ executing.delete(filePath), isRunning = !1;
190
188
  }, interval);
191
189
  }
192
- }).then((watcher) => {
193
- watchers.add(watcher);
194
190
  });
195
- for (const dir of dirs)
196
- watch(dir, (file, event) => {
191
+ addWatcher(currentWatcher);
192
+ }
193
+ for (const dir of dirs) {
194
+ const currentWatcher = watch(dir, (file, event) => {
197
195
  if (event === "change") {
198
196
  if (executing.has(file) || isRunning || executing.size > 0) return;
199
- setIsRunning(!0), executing.add(file), resultsClear(), poku(file).then(
197
+ isRunning = !0, executing.add(file), resultsClear(), poku(file).then(
200
198
  () => setTimeout(() => {
201
- executing.delete(file), setIsRunning(!1);
199
+ executing.delete(file), isRunning = !1;
202
200
  }, interval)
203
201
  );
204
202
  }
205
- }).then((watcher) => {
206
- watchers.add(watcher);
207
203
  });
204
+ addWatcher(currentWatcher);
205
+ }
208
206
  hr(), log(`${format("Watching:").bold()} ${format(dirs.join(", ")).underline()}`), process.on("SIGTERM", () => {
209
207
  for (const watcher of watchers) watcher.stop();
210
208
  process.exit(0);
@@ -83,7 +83,13 @@ class Formatter {
83
83
  return `${this.parts}${this.text}\x1B[0m`;
84
84
  }
85
85
  }
86
- const format = (text) => new Formatter(text), SKIP_MARKER = "\x1B[94m\x1B[1m\u25EF", TODO_MARKER = "\x1B[96m\x1B[1m\u25CF", ANSI_RESET = "\x1B[0m", timeoutMessage = (ms) => `${format(`\u25CF Timeout: test file exceeded ${ms}ms limit`).fail().bold()}`, serialize = (value) => typeof value > "u" || typeof value == "function" || typeof value == "bigint" || typeof value == "symbol" || value instanceof RegExp ? String(value) : Array.isArray(value) ? value.map(serialize) : value instanceof Set ? Array.from(value).map(serialize) : value instanceof Map ? serialize(Object.fromEntries(value)) : value !== null && typeof value == "object" ? Object.fromEntries(
86
+ const format = (text) => new Formatter(text), ANSI_RESET = "\x1B[0m", SKIP_MARKER = String(format("\u25EF").info().bold()).slice(
87
+ 0,
88
+ -ANSI_RESET.length
89
+ ), TODO_MARKER = String(format("\u25CF").cyan().bold()).slice(
90
+ 0,
91
+ -ANSI_RESET.length
92
+ ), timeoutMessage = (ms) => `${format(`\u25CF Timeout: test file exceeded ${ms}ms limit`).fail().bold()}`, serialize = (value) => typeof value > "u" || typeof value == "function" || typeof value == "bigint" || typeof value == "symbol" || value instanceof RegExp ? String(value) : Array.isArray(value) ? value.map(serialize) : value instanceof Set ? Array.from(value).map(serialize) : value instanceof Map ? serialize(Object.fromEntries(value)) : value !== null && typeof value == "object" ? Object.fromEntries(
87
93
  Object.entries(value).map(([key, val]) => [key, serialize(val)])
88
94
  ) : value, parserOutput = (options) => {
89
95
  const { output, result, debug } = options, pad2 = " ", isDebugOrFailed = debug || !result, outputs = [];
@@ -153,14 +159,25 @@ const format = (text) => new Formatter(text), SKIP_MARKER = "\x1B[94m\x1B[1m\u25
153
159
  }, pad = (num) => String(num).padStart(2, "0"), parseTime = (date) => {
154
160
  const hours = pad(date.getHours()), minutes = pad(date.getMinutes()), seconds = pad(date.getSeconds());
155
161
  return `${hours}:${minutes}:${seconds}`;
156
- }, parseTimeToSecs = (milliseconds) => (milliseconds / 1e3).toFixed(2), columns = Math.max((process$1.stdout.columns || 50) - 10, 40), hrLine = `
162
+ }, parseTimeToSecs = (milliseconds) => (milliseconds / 1e3).toFixed(2), hrtimeToMs = (end) => end[0] * 1e3 + end[1] / 1e6, columns = Math.max((process$1.stdout.columns || 50) - 10, 40), hrLine = `
157
163
  \x1B[2m\x1B[90m${"\u2500".repeat(columns)}\x1B[0m
158
164
  `, log$1 = (data) => {
159
165
  process$1.stdout.write(`${data}
160
166
  `);
161
167
  }, hr = () => {
162
168
  log$1(hrLine);
163
- }, ARROW_PASS = "\x1B[32m\x1B[1m\u203A\x1B[0m", ARROW_FAIL = "\x1B[91m\x1B[1m\u203A\x1B[0m", getIndent = () => indentation.test.repeat(indentation.describeDepth + indentation.itDepth), errors = getSharedState(
169
+ }, ARROW_PASS = "\x1B[32m\x1B[1m\u203A\x1B[0m", ARROW_FAIL = "\x1B[91m\x1B[1m\u203A\x1B[0m", getIndent = () => indentation.test.repeat(indentation.describeDepth + indentation.itDepth), logEndResult = ({
170
+ title,
171
+ duration,
172
+ success = !0
173
+ }) => {
174
+ const status = success ? "success" : "fail", indent = getIndent();
175
+ log$1(
176
+ `${indent}${format(`\u25CF ${title}`)[status]().bold()} ${format(
177
+ `\u203A ${duration.toFixed(6)}ms`
178
+ )[status]().dim()}`
179
+ );
180
+ }, errors = getSharedState(
164
181
  "errors",
165
182
  []
166
183
  ), poku$1 = {
@@ -181,26 +198,16 @@ const format = (text) => new Formatter(text), SKIP_MARKER = "\x1B[94m\x1B[1m\u25
181
198
  const indent = getIndent();
182
199
  log$1(`${indent}${format(`\u25CC ${title}`).bold().dim()}`);
183
200
  },
184
- onDescribeEnd({ title, duration, success = !0 }) {
185
- const status = success ? "success" : "fail", indent = getIndent();
186
- log$1(
187
- `${indent}${format(`\u25CF ${title}`)[status]().bold()} ${format(
188
- `\u203A ${duration.toFixed(6)}ms`
189
- )[status]().dim()}`
190
- );
201
+ onDescribeEnd(options) {
202
+ logEndResult(options);
191
203
  },
192
204
  onItStart({ title }) {
193
205
  if (!title) return;
194
206
  const indent = getIndent();
195
207
  log$1(`${indent}${format(`\u25CC ${title}`).dim()}`);
196
208
  },
197
- onItEnd({ title, duration, success = !0 }) {
198
- const status = success ? "success" : "fail", indent = getIndent();
199
- log$1(
200
- `${indent}${format(`\u25CF ${title}`)[status]().bold()} ${format(
201
- `\u203A ${duration.toFixed(6)}ms`
202
- )[status]().dim()}`
203
- );
209
+ onItEnd(options) {
210
+ logEndResult(options);
204
211
  },
205
212
  onAssertionSuccess({ message }) {
206
213
  const output = `${getIndent()}${format(`\u2714 ${message}`).success().bold()}`;
@@ -244,16 +251,12 @@ ${preIdentation} ${format(`${options?.expected ?? "Expected"}:`).dim()}`
244
251
  log$1(`${indent}${format(`\u25CF ${message}`).cyan().bold()}`);
245
252
  },
246
253
  onRetryStart({ attempt, total }) {
247
- const indent = indentation.test.repeat(
248
- indentation.describeDepth + indentation.itDepth
249
- );
254
+ const indent = getIndent();
250
255
  log$1(`${indent}${format(`\u21BB Retry ${attempt}/${total}`).dim()}`);
251
256
  },
252
257
  onRetryEnd({ attempt, success }) {
253
258
  if (success && attempt > 1) {
254
- const indent = indentation.test.repeat(
255
- indentation.describeDepth + indentation.itDepth
256
- );
259
+ const indent = getIndent();
257
260
  log$1(`${indent}${format("\u2714 Retry succeeded").success().dim()}`);
258
261
  }
259
262
  },
@@ -278,14 +281,12 @@ ${preIdentation} ${format(`${options?.expected ?? "Expected"}:`).dim()}`
278
281
  `${format(String(errors.length)).fail().bold()} ${format("test file(s) failed:").bold()}
279
282
  `
280
283
  );
281
- for (const i in errors) {
282
- const { file, output } = errors[i], index = +i;
284
+ for (const [index, { file, output }] of errors.entries())
283
285
  index > 0 && process$1.stdout.write(`
284
286
  `), log$1(
285
287
  `${format(`${index + 1})`).dim().bold()} ${format(file).underline()}`
286
288
  ), output && log$1(`
287
289
  ${output}`);
288
- }
289
290
  }
290
291
  },
291
292
  onExit({ results: results2, timespan: timespan2 }) {
@@ -310,7 +311,7 @@ ${message}
310
311
  }, createReporter = (events) => () => ({
311
312
  ...poku$1,
312
313
  ...events
313
- }), classic = () => {
314
+ }), formatFile = (icon, status, file, time) => `${indentation.test}${format(icon)[status]()} ${format(`${file} ${format(`\u203A ${time.toFixed(6)}ms`)[status]()}`).dim()}`, classic = () => {
314
315
  const files = {
315
316
  passed: /* @__PURE__ */ new Map(),
316
317
  failed: /* @__PURE__ */ new Map()
@@ -328,17 +329,13 @@ ${message}
328
329
  onRunResult() {
329
330
  if (hr(), files.passed.size > 0 && files.failed.size === 0) {
330
331
  log$1(
331
- Array.from(files.passed).map(
332
- ([file, time]) => `${indentation.test}${format("\u2714").success()} ${format(`${file} ${format(`\u203A ${time.toFixed(6)}ms`).success()}`).dim()}`
333
- ).join(`
332
+ Array.from(files.passed).map(([file, time]) => formatFile("\u2714", "success", file, time)).join(`
334
333
  `)
335
334
  );
336
335
  return;
337
336
  }
338
337
  files.failed.size > 0 && log$1(
339
- Array.from(files.failed).map(
340
- ([file, time]) => `${indentation.test}${format("\u2718").fail()} ${format(`${file} ${format(`\u203A ${time.toFixed(6)}ms`).fail()}`).dim()}`
341
- ).join(`
338
+ Array.from(files.failed).map(([file, time]) => formatFile("\u2718", "fail", file, time)).join(`
342
339
  `)
343
340
  );
344
341
  },
@@ -450,7 +447,7 @@ const states = getSharedState("states", {
450
447
  }), errorHoist = getSharedState("errorHoist", {
451
448
  depth: 0,
452
449
  failed: !1
453
- }), VERSION = "4.3.3-canary.894a7c91", deepOptions = getSharedState("deepOptions", []), GLOBAL = getSharedState("GLOBAL", {
450
+ }), VERSION = "4.4.0", deepOptions = getSharedState("deepOptions", []), GLOBAL = getSharedState("GLOBAL", {
454
451
  cwd: cwd$1,
455
452
  configs: {
456
453
  filter: void 0,
@@ -480,7 +477,7 @@ const states = getSharedState("states", {
480
477
  const { configs, runtime } = GLOBAL;
481
478
  if (runtime === "bun") return ["bun"];
482
479
  if (runtime === "deno") {
483
- const denoAllow = configs.deno?.allow ? configs.deno.allow.map((allow) => allow ? `--allow-${allow}` : "").filter((allow) => allow) : ["--allow-read", "--allow-env", "--allow-run", "--allow-net"], denoDeny = configs.deno?.deny ? configs.deno.deny.map((deny) => deny ? `--deny-${deny}` : "").filter((deny) => deny) : [];
480
+ const denoAllow = configs.deno?.allow ? configs.deno.allow.map((allow) => allow ? `--allow-${allow}` : "").filter(Boolean) : ["--allow-read", "--allow-env", "--allow-run", "--allow-net"], denoDeny = configs.deno?.deny ? configs.deno.deny.map((deny) => deny ? `--deny-${deny}` : "").filter(Boolean) : [];
484
481
  return ["deno", "run", ...denoAllow, ...denoDeny];
485
482
  }
486
483
  const ext = node_path.extname(filename);
@@ -558,7 +555,7 @@ const states = getSharedState("states", {
558
555
  result,
559
556
  debug: GLOBAL.configs.debug
560
557
  })?.join(`
561
- `), total = end[0] * 1e3 + end[1] / 1e6;
558
+ `), total = hrtimeToMs(end);
562
559
  reporter2.onFileResult({
563
560
  status: result,
564
561
  path: {
@@ -576,7 +573,7 @@ const states = getSharedState("states", {
576
573
  resolve(result);
577
574
  }), child.on("error", (err) => {
578
575
  killTimer && clearTimeout(killTimer), end = process$1.hrtime(start);
579
- const total = end[0] * 1e3 + end[1] / 1e6;
576
+ const total = hrtimeToMs(end);
580
577
  showLogs && console.error(`Failed to start test: ${path}`, err), reporter2.onFileResult({
581
578
  status: !1,
582
579
  path: {
@@ -699,7 +696,7 @@ const poku = (async (targetPaths, configs) => {
699
696
  paths.map((dir) => listFiles(node_path.join(cwd2, dir), GLOBAL.configs))
700
697
  )).flat(1);
701
698
  showLogs && GLOBAL.reporter.onRunStart();
702
- const code = await runTests(testFiles) ? 0 : 1, end = process$1.hrtime(start), total = end[0] * 1e3 + end[1] / 1e6;
699
+ const code = await runTests(testFiles) ? 0 : 1, end = process$1.hrtime(start), total = hrtimeToMs(end);
703
700
  if (timespan.duration = total, timespan.finished = /* @__PURE__ */ new Date(), showLogs && GLOBAL.reporter.onRunResult({ code, timespan, results }), GLOBAL.configs.noExit || exit(code, GLOBAL.configs.quiet), plugins?.length && pluginContext)
704
701
  for (const plugin2 of plugins)
705
702
  plugin2.teardown && await plugin2.teardown(pluginContext);
@@ -726,7 +723,7 @@ const poku = (async (targetPaths, configs) => {
726
723
  handleError(error, options);
727
724
  }
728
725
  } };
729
- }, { processAssert, processAsyncAssert } = assertProcessor(), isPredicate = (value) => typeof value == "function" || value instanceof RegExp || typeof value == "object", createAssert = (nodeAssert2) => {
726
+ }, { processAssert, processAsyncAssert } = assertProcessor(), isPredicate = (value) => typeof value == "function" || value instanceof RegExp || typeof value == "object", resolveMessage = (errorOrMessage, message) => typeof errorOrMessage == "string" ? errorOrMessage : message, createAssert = (nodeAssert2) => {
730
727
  const ok = (value, message) => processAssert(() => nodeAssert2.ok(value), { message });
731
728
  return Object.assign(
732
729
  ((value, message) => ok(value, message)),
@@ -754,7 +751,7 @@ const poku = (async (targetPaths, configs) => {
754
751
  isPredicate(errorOrMessage) ? await nodeAssert2.doesNotReject(block, errorOrMessage, message) : await nodeAssert2.doesNotReject(block, message);
755
752
  },
756
753
  {
757
- message: typeof errorOrMessage == "string" ? errorOrMessage : message,
754
+ message: resolveMessage(errorOrMessage, message),
758
755
  defaultMessage: "Got unwanted rejection",
759
756
  hideDiff: !0,
760
757
  throw: !0
@@ -775,15 +772,13 @@ const poku = (async (targetPaths, configs) => {
775
772
  doesNotThrow: ((block, errorOrMessage, message) => {
776
773
  processAssert(
777
774
  () => {
778
- if (isPredicate(errorOrMessage))
779
- nodeAssert2.doesNotThrow(block, errorOrMessage, message);
780
- else {
781
- const msg = typeof errorOrMessage == "string" ? errorOrMessage : message;
782
- nodeAssert2.doesNotThrow(block, msg);
783
- }
775
+ isPredicate(errorOrMessage) ? nodeAssert2.doesNotThrow(block, errorOrMessage, message) : nodeAssert2.doesNotThrow(
776
+ block,
777
+ resolveMessage(errorOrMessage, message)
778
+ );
784
779
  },
785
780
  {
786
- message: typeof errorOrMessage == "string" ? errorOrMessage : message,
781
+ message: resolveMessage(errorOrMessage, message),
787
782
  defaultMessage: "Expected function not to throw",
788
783
  hideDiff: !0,
789
784
  throw: !0
@@ -824,15 +819,13 @@ const poku = (async (targetPaths, configs) => {
824
819
  rejects: (async (block, errorOrMessage, message) => {
825
820
  await processAsyncAssert(
826
821
  async () => {
827
- if (isPredicate(errorOrMessage))
828
- await nodeAssert2.rejects(block, errorOrMessage, message);
829
- else {
830
- const msg = typeof errorOrMessage == "string" ? errorOrMessage : message;
831
- await nodeAssert2.rejects(block, msg);
832
- }
822
+ isPredicate(errorOrMessage) ? await nodeAssert2.rejects(block, errorOrMessage, message) : await nodeAssert2.rejects(
823
+ block,
824
+ resolveMessage(errorOrMessage, message)
825
+ );
833
826
  },
834
827
  {
835
- message: typeof errorOrMessage == "string" ? errorOrMessage : message,
828
+ message: resolveMessage(errorOrMessage, message),
836
829
  defaultMessage: "Expected promise to be rejected with specified error",
837
830
  hideDiff: !0,
838
831
  throw: !0
@@ -856,31 +849,27 @@ const poku = (async (targetPaths, configs) => {
856
849
  }), skip$1 = (async (messageOrCb, _cb) => {
857
850
  const message = typeof messageOrCb == "string" ? messageOrCb : "Skipping";
858
851
  GLOBAL.reporter.onSkipModifier({ message });
859
- }), createOnlyDescribe = (describeBase2) => (async (messageOrCb, cb) => {
860
- if (hasOnly || (log$1(
861
- format("Can't run `describe.only` tests without `--only` flag").fail()
862
- ), process$1.exit(1)), checkNoOnly(
852
+ }), assertOnlyEnabled = (message) => {
853
+ hasOnly || (log$1(format(message).fail()), process$1.exit(1));
854
+ }, createOnlyDescribe = (describeBase2) => (async (messageOrCb, cb) => {
855
+ if (assertOnlyEnabled("Can't run `describe.only` tests without `--only` flag"), checkNoOnly(
863
856
  typeof messageOrCb == "function" ? messageOrCb : cb
864
857
  ) && (GLOBAL.runAsOnly = !0), typeof messageOrCb == "string" && cb)
865
858
  return describeBase2(messageOrCb, cb);
866
859
  if (typeof messageOrCb == "function") return describeBase2(messageOrCb);
867
860
  }), createOnlyIt = (itBase2) => (async (messageOrCb, cb) => {
868
- if (hasOnly || (log$1(
869
- format(
870
- "Can't run `it.only` and `test.only` tests without `--only` flag"
871
- ).fail()
872
- ), process$1.exit(1)), typeof messageOrCb == "string" && cb) return itBase2(messageOrCb, cb);
861
+ if (assertOnlyEnabled(
862
+ "Can't run `it.only` and `test.only` tests without `--only` flag"
863
+ ), typeof messageOrCb == "string" && cb) return itBase2(messageOrCb, cb);
873
864
  if (typeof messageOrCb == "function") return itBase2(messageOrCb);
874
865
  }), SCOPE_HOOKS_KEY = /* @__PURE__ */ Symbol.for("@pokujs/poku.test-scope-hooks"), getScopeHook = () => globalThis[SCOPE_HOOKS_KEY], itBase = async (titleOrCb, callback) => {
875
866
  try {
876
- const title = getTitle(titleOrCb), hasTitle = typeof title == "string", cb = getCallback(hasTitle ? callback : titleOrCb);
877
- let success = !0, start, end;
867
+ const title = getTitle(titleOrCb), hasTitle = typeof title == "string", cb = getCallback(hasTitle ? callback : titleOrCb), insideDescribe = errorHoist.depth > 0;
868
+ let success = !0, start, end, onError;
878
869
  if (GLOBAL.reporter.onItStart({ title }), hasTitle && indentation.itDepth++, typeof each.before.cb == "function") {
879
870
  const beforeResult = each.before.cb();
880
871
  beforeResult instanceof Promise && await beforeResult;
881
872
  }
882
- const insideDescribe = errorHoist.depth > 0;
883
- let onError;
884
873
  insideDescribe ? errorHoist.failed = !1 : (onError = (error) => {
885
874
  const ctx = retryContext.stack?.[retryContext.stack.length - 1];
886
875
  ctx ? ctx.failed = !0 : (process$1.exitCode = 1, success = !1, error instanceof nodeAssert.AssertionError || console.error(error));
@@ -910,7 +899,7 @@ const poku = (async (targetPaths, configs) => {
910
899
  afterResult instanceof Promise && await afterResult;
911
900
  }
912
901
  if (!title) return;
913
- const duration = end[0] * 1e3 + end[1] / 1e6;
902
+ const duration = hrtimeToMs(end);
914
903
  indentation.itDepth--, GLOBAL.reporter.onItEnd({ title, duration, success });
915
904
  } catch (error) {
916
905
  if (indentation.itDepth > 0 && indentation.itDepth--, typeof each.after.cb == "function") {
@@ -920,7 +909,7 @@ const poku = (async (targetPaths, configs) => {
920
909
  throw error;
921
910
  }
922
911
  }, itCore = (async (titleOrCb, cb) => {
923
- if (!(GLOBAL.configs.testNamePattern && typeof titleOrCb == "string" && !GLOBAL.configs.testNamePattern.test(titleOrCb)) && !(GLOBAL.configs.testSkipPattern && typeof titleOrCb == "string" && GLOBAL.configs.testSkipPattern.test(titleOrCb)) && !(hasOnly && !GLOBAL.runAsOnly)) {
912
+ if (!(typeof titleOrCb == "string" && (GLOBAL.configs.testNamePattern && !GLOBAL.configs.testNamePattern.test(titleOrCb) || GLOBAL.configs.testSkipPattern?.test(titleOrCb))) && !(hasOnly && !GLOBAL.runAsOnly)) {
924
913
  if (typeof titleOrCb == "string" && cb) return itBase(titleOrCb, cb);
925
914
  if (typeof titleOrCb == "function") return itBase(titleOrCb);
926
915
  }
@@ -948,7 +937,7 @@ const poku = (async (targetPaths, configs) => {
948
937
  }
949
938
  }
950
939
  if (!title) return;
951
- const duration = end[0] * 1e3 + end[1] / 1e6;
940
+ const duration = hrtimeToMs(end);
952
941
  indentation.describeDepth--, reporter2.onDescribeEnd({ title, duration, success }), GLOBAL.runAsOnly = !1;
953
942
  }, describeCore = (async (messageOrCb, cbOrOptions) => {
954
943
  if (typeof messageOrCb == "string" && typeof cbOrOptions != "function")
@@ -1007,23 +996,15 @@ const poku = (async (targetPaths, configs) => {
1007
996
  Object.prototype.hasOwnProperty.call(process$1.env, arg) || (process$1.env[arg] = value);
1008
997
  }, skip = (message = "Skipping") => {
1009
998
  message && GLOBAL.reporter.onSkipFile({ message }), process$1.exit(0);
1010
- }, beforeEach = (callback, options) => (options?.immediate && callback(), each.before.cb = () => {
1011
- if (each.before.status) return callback();
1012
- }, { pause: () => {
1013
- each.before.status = !1;
1014
- }, continue: () => {
1015
- each.before.status = !0;
1016
- }, reset: () => {
1017
- each.before.cb = void 0;
1018
- } }), afterEach = (callback) => (each.after.cb = () => {
1019
- if (each.after.status) return callback();
999
+ }, createEachControl = (slot, callback) => (slot.cb = () => {
1000
+ if (slot.status) return callback();
1020
1001
  }, { pause: () => {
1021
- each.after.status = !1;
1002
+ slot.status = !1;
1022
1003
  }, continue: () => {
1023
- each.after.status = !0;
1004
+ slot.status = !0;
1024
1005
  }, reset: () => {
1025
- each.after.cb = void 0;
1026
- } }), checkPort = (port, host) => new Promise((resolve) => {
1006
+ slot.cb = void 0;
1007
+ } }), beforeEach = (callback, options) => (options?.immediate && callback(), createEachControl(each.before, callback)), afterEach = (callback) => createEachControl(each.after, callback), checkPort = (port, host) => new Promise((resolve) => {
1027
1008
  const client = node_net.createConnection(port, host);
1028
1009
  client.on("connect", () => {
1029
1010
  client.end(), resolve(!0);
@@ -1164,19 +1145,14 @@ const regex = {
1164
1145
  }), killPID = async (PID) => {
1165
1146
  const PIDs = setPortsAndPIDs(PID);
1166
1147
  await Promise.all(
1167
- PIDs.map(async (p) => {
1168
- isWindows ? await killPID$1.windows(p) : await killPID$1.unix(p);
1169
- })
1148
+ PIDs.map(
1149
+ async (p) => isWindows ? killPID$1.windows(p) : killPID$1.unix(p)
1150
+ )
1170
1151
  );
1171
- }, killPort = async (port) => {
1172
- const PIDs = await getPIDs(port);
1173
- for (const PID of PIDs)
1174
- PID && await killPID(PID);
1175
- }, killRange = async (startsAt, endsAt) => {
1176
- const PIDs = await getPIDs.range(startsAt, endsAt);
1152
+ }, killPIDs = async (PIDs) => {
1177
1153
  for (const PID of PIDs)
1178
1154
  PID && await killPID(PID);
1179
- }, kill = {
1155
+ }, killPort = async (port) => killPIDs(await getPIDs(port)), killRange = async (startsAt, endsAt) => killPIDs(await getPIDs.range(startsAt, endsAt)), kill = {
1180
1156
  pid: killPID,
1181
1157
  port: killPort,
1182
1158
  range: killRange
@@ -1267,6 +1243,7 @@ exports.envFile = envFile;
1267
1243
  exports.exit = exit;
1268
1244
  exports.findFileFromStack = findFileFromStack;
1269
1245
  exports.getPIDs = getPIDs;
1246
+ exports.hrtimeToMs = hrtimeToMs;
1270
1247
  exports.it = it;
1271
1248
  exports.kill = kill;
1272
1249
  exports.listFiles = listFiles;