elit 3.6.4 → 3.6.5

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.
@@ -55,6 +55,52 @@ function readFileSync(path, options) {
55
55
  }
56
56
  throw new Error("Unsupported runtime");
57
57
  }
58
+ function existsSync(path) {
59
+ try {
60
+ statSync(path);
61
+ return true;
62
+ } catch {
63
+ return false;
64
+ }
65
+ }
66
+ function statSync(path) {
67
+ if (isNode || isBun) {
68
+ return fs.statSync(path);
69
+ } else if (isDeno) {
70
+ const info = Deno.statSync(path);
71
+ return createStatsFromDenoFileInfo(info);
72
+ }
73
+ throw new Error("Unsupported runtime");
74
+ }
75
+ function createStatsFromDenoFileInfo(info) {
76
+ return {
77
+ isFile: () => info.isFile,
78
+ isDirectory: () => info.isDirectory,
79
+ isBlockDevice: () => false,
80
+ isCharacterDevice: () => false,
81
+ isSymbolicLink: () => info.isSymlink || false,
82
+ isFIFO: () => false,
83
+ isSocket: () => false,
84
+ dev: info.dev || 0,
85
+ ino: info.ino || 0,
86
+ mode: info.mode || 0,
87
+ nlink: info.nlink || 1,
88
+ uid: info.uid || 0,
89
+ gid: info.gid || 0,
90
+ rdev: 0,
91
+ size: info.size,
92
+ blksize: info.blksize || 4096,
93
+ blocks: info.blocks || Math.ceil(info.size / 512),
94
+ atimeMs: info.atime?.getTime() || Date.now(),
95
+ mtimeMs: info.mtime?.getTime() || Date.now(),
96
+ ctimeMs: info.birthtime?.getTime() || Date.now(),
97
+ birthtimeMs: info.birthtime?.getTime() || Date.now(),
98
+ atime: info.atime || /* @__PURE__ */ new Date(),
99
+ mtime: info.mtime || /* @__PURE__ */ new Date(),
100
+ ctime: info.birthtime || /* @__PURE__ */ new Date(),
101
+ birthtime: info.birthtime || /* @__PURE__ */ new Date()
102
+ };
103
+ }
58
104
 
59
105
  // src/path.ts
60
106
  function getSeparator(isWin) {
@@ -302,12 +348,16 @@ var testPattern = void 0;
302
348
  var currentTestFile = void 0;
303
349
  var currentSourceMapConsumer = void 0;
304
350
  var wrapperLineOffset = 0;
305
- async function transpileFile(filePath) {
306
- const source = await readFile(filePath, "utf-8");
307
- const result = transformSync(source, {
308
- loader: filePath.endsWith(".ts") || filePath.endsWith(".tsx") ? "ts" : "js",
309
- format: "esm",
310
- sourcemap: "inline",
351
+ var TEST_MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
352
+ function resolveTestLoader(filePath) {
353
+ return /\.(?:ts|tsx|mts|cts)$/i.test(filePath) ? "ts" : "js";
354
+ }
355
+ function createTestTransformOptions(filePath, format, sourcemap) {
356
+ return {
357
+ loader: resolveTestLoader(filePath),
358
+ format,
359
+ sourcemap,
360
+ sourcefile: filePath,
311
361
  target: "es2020",
312
362
  tsconfigRaw: {
313
363
  compilerOptions: {
@@ -316,7 +366,106 @@ async function transpileFile(filePath) {
316
366
  jsxFragmentFactory: "Fragment"
317
367
  }
318
368
  }
319
- });
369
+ };
370
+ }
371
+ function resolveExistingTestModulePath(basePath) {
372
+ const nodePath = __require("path");
373
+ if (existsSync(basePath) && statSync(basePath).isFile()) {
374
+ return basePath;
375
+ }
376
+ for (const extension of TEST_MODULE_EXTENSIONS) {
377
+ const candidatePath = `${basePath}${extension}`;
378
+ if (existsSync(candidatePath) && statSync(candidatePath).isFile()) {
379
+ return candidatePath;
380
+ }
381
+ }
382
+ if (existsSync(basePath) && statSync(basePath).isDirectory()) {
383
+ const packageJsonPath = nodePath.join(basePath, "package.json");
384
+ if (existsSync(packageJsonPath) && statSync(packageJsonPath).isFile()) {
385
+ try {
386
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
387
+ for (const candidateEntry of [packageJson.main, packageJson.module]) {
388
+ if (typeof candidateEntry !== "string" || candidateEntry.trim().length === 0) {
389
+ continue;
390
+ }
391
+ try {
392
+ return resolveExistingTestModulePath(nodePath.resolve(basePath, candidateEntry));
393
+ } catch {
394
+ continue;
395
+ }
396
+ }
397
+ } catch {
398
+ }
399
+ }
400
+ for (const extension of TEST_MODULE_EXTENSIONS) {
401
+ const candidatePath = nodePath.join(basePath, `index${extension}`);
402
+ if (existsSync(candidatePath) && statSync(candidatePath).isFile()) {
403
+ return candidatePath;
404
+ }
405
+ }
406
+ }
407
+ return basePath;
408
+ }
409
+ function resolveTestModulePath(fromFilePath, specifier) {
410
+ if (!specifier.startsWith(".") && !specifier.startsWith("/")) {
411
+ return specifier;
412
+ }
413
+ const nodePath = __require("path");
414
+ const basePath = specifier.startsWith(".") ? nodePath.resolve(dirname(fromFilePath), specifier) : specifier;
415
+ return resolveExistingTestModulePath(basePath);
416
+ }
417
+ function shouldTranspileTestModule(filePath) {
418
+ return /\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i.test(filePath);
419
+ }
420
+ function createTestModuleRequire(fromFilePath, moduleCache) {
421
+ return (specifier) => {
422
+ if (specifier.startsWith("elit/") || specifier === "elit") {
423
+ return __require(specifier);
424
+ }
425
+ const resolvedPath = resolveTestModulePath(fromFilePath, specifier);
426
+ if (resolvedPath === specifier) {
427
+ return __require(specifier);
428
+ }
429
+ if (!existsSync(resolvedPath) || !statSync(resolvedPath).isFile()) {
430
+ return __require(resolvedPath);
431
+ }
432
+ if (!shouldTranspileTestModule(resolvedPath)) {
433
+ return __require(resolvedPath);
434
+ }
435
+ return loadTranspiledTestModule(resolvedPath, moduleCache);
436
+ };
437
+ }
438
+ function loadTranspiledTestModule(modulePath, moduleCache) {
439
+ const cached = moduleCache.get(modulePath);
440
+ if (cached) {
441
+ return cached.exports;
442
+ }
443
+ const source = readFileSync(modulePath, "utf-8");
444
+ let transpiled;
445
+ try {
446
+ transpiled = transformSync(source, createTestTransformOptions(modulePath, "cjs", false));
447
+ } catch (error) {
448
+ throw new Error(`Failed to transpile test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
449
+ }
450
+ const moduleRecord = { exports: {} };
451
+ const moduleObj = { exports: moduleRecord.exports };
452
+ moduleCache.set(modulePath, moduleRecord);
453
+ try {
454
+ const fn = new Function("module", "exports", "require", "__filename", "__dirname", transpiled.code);
455
+ const requireFn = createTestModuleRequire(modulePath, moduleCache);
456
+ fn(moduleObj, moduleObj.exports, requireFn, modulePath, dirname(modulePath));
457
+ } catch (error) {
458
+ throw new Error(`Failed to execute test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
459
+ }
460
+ moduleRecord.exports = moduleObj.exports;
461
+ if (!modulePath.includes(".test.") && !modulePath.includes(".spec.")) {
462
+ coveredFiles.add(modulePath);
463
+ }
464
+ return moduleRecord.exports;
465
+ }
466
+ async function transpileFile(filePath) {
467
+ const source = await readFile(filePath, "utf-8");
468
+ const result = transformSync(source, createTestTransformOptions(filePath, "esm", "inline"));
320
469
  let sourceMap;
321
470
  const sourceMapMatch = result.code.match(/\/\/# sourceMappingURL=data:application\/json;base64,(.+)/);
322
471
  if (sourceMapMatch) {
@@ -328,7 +477,7 @@ async function transpileFile(filePath) {
328
477
  }
329
478
  function createTestFunction(defaultTimeout = 5e3) {
330
479
  const testFn = function(name, fn, timeout) {
331
- const test2 = {
480
+ const test = {
332
481
  name,
333
482
  fn,
334
483
  skip: currentSuite.skip,
@@ -337,10 +486,10 @@ function createTestFunction(defaultTimeout = 5e3) {
337
486
  timeout: timeout ?? defaultTimeout,
338
487
  suite: currentSuite
339
488
  };
340
- currentSuite.tests.push(test2);
489
+ currentSuite.tests.push(test);
341
490
  };
342
491
  testFn.skip = (name, fn, timeout) => {
343
- const test2 = {
492
+ const test = {
344
493
  name,
345
494
  fn,
346
495
  skip: true,
@@ -349,11 +498,11 @@ function createTestFunction(defaultTimeout = 5e3) {
349
498
  timeout: timeout ?? defaultTimeout,
350
499
  suite: currentSuite
351
500
  };
352
- currentSuite.tests.push(test2);
501
+ currentSuite.tests.push(test);
353
502
  };
354
503
  testFn.only = (name, fn, timeout) => {
355
504
  hasOnly = true;
356
- const test2 = {
505
+ const test = {
357
506
  name,
358
507
  fn,
359
508
  skip: false,
@@ -362,10 +511,10 @@ function createTestFunction(defaultTimeout = 5e3) {
362
511
  timeout: timeout ?? defaultTimeout,
363
512
  suite: currentSuite
364
513
  };
365
- currentSuite.tests.push(test2);
514
+ currentSuite.tests.push(test);
366
515
  };
367
516
  testFn.todo = (name, fn, timeout) => {
368
- const test2 = {
517
+ const test = {
369
518
  name,
370
519
  fn,
371
520
  skip: false,
@@ -374,7 +523,7 @@ function createTestFunction(defaultTimeout = 5e3) {
374
523
  timeout: timeout ?? defaultTimeout,
375
524
  suite: currentSuite
376
525
  };
377
- currentSuite.tests.push(test2);
526
+ currentSuite.tests.push(test);
378
527
  };
379
528
  return testFn;
380
529
  }
@@ -940,29 +1089,7 @@ async function runTests(options) {
940
1089
  try {
941
1090
  const source = await readFile(file, "utf-8");
942
1091
  const testFileDir = dirname(file);
943
- const importRegex = /import\s+{\s*([^}]+)\s*}\s+from\s+['"]([^'"]+)['"]/g;
944
- const imports = {};
945
- let importIndex = 0;
946
- let codeWithoutImports = source.replace(importRegex, (_, named, path) => {
947
- const varName = `__import_${importIndex++}`;
948
- const trimmedNamed = named.trim();
949
- imports[varName] = { path, named: trimmedNamed };
950
- return `// ${trimmedNamed} import injected later
951
- `;
952
- });
953
- const result = transformSync(codeWithoutImports, {
954
- loader: file.endsWith(".ts") || file.endsWith(".tsx") ? "ts" : "js",
955
- format: "iife",
956
- sourcemap: "inline",
957
- target: "es2020",
958
- tsconfigRaw: {
959
- compilerOptions: {
960
- jsx: "react",
961
- jsxFactory: "h",
962
- jsxFragmentFactory: "Fragment"
963
- }
964
- }
965
- });
1092
+ const result = transformSync(source, createTestTransformOptions(file, "cjs", "inline"));
966
1093
  let code = result.code;
967
1094
  const sourceMapMatch = code.match(/\/\/# sourceMappingURL=data:application\/json;base64,(.+)/);
968
1095
  if (sourceMapMatch) {
@@ -973,99 +1100,15 @@ async function runTests(options) {
973
1100
  } else {
974
1101
  currentSourceMapConsumer = void 0;
975
1102
  }
976
- const importedValues = {};
977
- const importParamNames = [];
978
- const importAssignments = [];
979
- if (Object.keys(imports).length > 0) {
980
- for (const [, { path, named }] of Object.entries(imports)) {
981
- let resolvedPath = path;
982
- if (path.startsWith(".")) {
983
- const nodePath = __require("path");
984
- resolvedPath = nodePath.resolve(testFileDir, path);
985
- }
986
- if (!resolvedPath.endsWith(".ts") && !resolvedPath.endsWith(".js") && !resolvedPath.endsWith(".mjs") && !resolvedPath.endsWith(".cjs")) {
987
- resolvedPath += ".ts";
988
- }
989
- if (resolvedPath.endsWith(".ts")) {
990
- try {
991
- const importSource = await readFile(resolvedPath, "utf-8");
992
- const transpiled = transformSync(importSource, {
993
- loader: "ts",
994
- format: "cjs",
995
- target: "es2020",
996
- tsconfigRaw: {
997
- compilerOptions: {
998
- jsx: "react",
999
- jsxFactory: "h",
1000
- jsxFragmentFactory: "Fragment"
1001
- }
1002
- }
1003
- });
1004
- const moduleExports = {};
1005
- const moduleObj = { exports: moduleExports };
1006
- const fn2 = new Function("module", "exports", "require", "__filename", "__dirname", transpiled.code);
1007
- const requireFn = (id) => {
1008
- if (id.startsWith("elit/") || id === "elit") {
1009
- return __require(id);
1010
- }
1011
- if (id.startsWith(".")) {
1012
- const nodePath = __require("path");
1013
- const absPath = nodePath.resolve(dirname(resolvedPath), id);
1014
- return __require(absPath);
1015
- }
1016
- return __require(id);
1017
- };
1018
- fn2(moduleObj, moduleExports, requireFn, resolvedPath, dirname(resolvedPath));
1019
- if (!resolvedPath.includes(".test.") && !resolvedPath.includes(".spec.")) {
1020
- coveredFiles.add(resolvedPath);
1021
- }
1022
- let exportedValue = moduleObj.exports[named];
1023
- if (exportedValue === void 0 && moduleObj.exports.default) {
1024
- exportedValue = moduleObj.exports.default[named];
1025
- }
1026
- if (exportedValue === void 0 && typeof moduleObj.exports === "object") {
1027
- exportedValue = moduleObj.exports[named];
1028
- }
1029
- const paramKey = `__import_${Math.random().toString(36).substring(2, 11)}`;
1030
- importedValues[paramKey] = exportedValue;
1031
- importParamNames.push(paramKey);
1032
- importAssignments.push(`const ${named} = ${paramKey};`);
1033
- } catch (err) {
1034
- const paramKey = `__import_${Math.random().toString(36).substring(2, 11)}`;
1035
- importedValues[paramKey] = null;
1036
- importParamNames.push(paramKey);
1037
- importAssignments.push(`const ${named} = ${paramKey}; /* Error importing ${resolvedPath}: ${err} */`);
1038
- }
1039
- } else {
1040
- const requiredModule = __require(resolvedPath);
1041
- const exportedValue = requiredModule[named];
1042
- const paramKey = `__import_${Math.random().toString(36).substring(2, 11)}`;
1043
- importedValues[paramKey] = exportedValue;
1044
- importParamNames.push(paramKey);
1045
- importAssignments.push(`const ${named} = ${paramKey};`);
1046
- }
1047
- }
1048
- }
1049
- let preamble = "";
1050
- if (Object.keys(imports).length > 0) {
1051
- const iifeStartMatch = code.match(/^(\s*(?:var\s+\w+\s*=\s*)?\(\(\)\s*=>\s*\{\n)/);
1052
- if (iifeStartMatch) {
1053
- const iifePrefix = iifeStartMatch[1];
1054
- const assignments = `${importAssignments.join("\n")}
1055
- `;
1056
- preamble = iifePrefix;
1057
- code = iifePrefix + assignments + code.slice(iifeStartMatch[1].length);
1058
- } else {
1059
- preamble = importAssignments.join("\n") + "\n";
1060
- code = preamble + code;
1061
- }
1062
- }
1063
- wrapperLineOffset = preamble.split("\n").length;
1103
+ wrapperLineOffset = 0;
1064
1104
  setupGlobals();
1065
- const allParams = ["describe", "it", "test", "expect", "beforeAll", "afterAll", "beforeEach", "afterEach", "vi", "require", "module", "__filename", "__dirname", ...importParamNames];
1066
- const allArgs = [describe, it, test, expect, beforeAll, afterAll, beforeEach, afterEach, vi, __require, module, file, testFileDir, ...importParamNames.map((p) => importedValues[p])];
1067
- const fn = new Function(...allParams, code);
1068
- await fn(...allArgs);
1105
+ const moduleCache = /* @__PURE__ */ new Map();
1106
+ const moduleRecord = { exports: {} };
1107
+ const moduleObj = { exports: moduleRecord.exports };
1108
+ moduleCache.set(file, moduleRecord);
1109
+ const fn = new Function("module", "exports", "require", "__filename", "__dirname", code);
1110
+ const requireFn = createTestModuleRequire(file, moduleCache);
1111
+ await fn(moduleObj, moduleObj.exports, requireFn, file, testFileDir);
1069
1112
  await executeSuite(currentSuite, timeout, bail);
1070
1113
  if (currentSourceMapConsumer) {
1071
1114
  currentSourceMapConsumer.destroy();
@@ -1130,22 +1173,22 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
1130
1173
  for (const hook of beforeAllHooks) {
1131
1174
  await hook();
1132
1175
  }
1133
- for (const test2 of suite.tests) {
1134
- if (hasOnly && !test2.only && !suite.only) {
1176
+ for (const test of suite.tests) {
1177
+ if (hasOnly && !test.only && !suite.only) {
1135
1178
  continue;
1136
1179
  }
1137
1180
  let testMatches = true;
1138
1181
  if (testPattern) {
1139
1182
  const escapedPattern = escapeRegex(testPattern);
1140
1183
  const regex = new RegExp(escapedPattern, "i");
1141
- testMatches = regex.test(test2.name);
1184
+ testMatches = regex.test(test.name);
1142
1185
  }
1143
1186
  if (!testMatches) {
1144
1187
  continue;
1145
1188
  }
1146
- if (test2.skip || suite.skip) {
1189
+ if (test.skip || suite.skip) {
1147
1190
  testResults.push({
1148
- name: test2.name,
1191
+ name: test.name,
1149
1192
  status: "skip",
1150
1193
  duration: 0,
1151
1194
  suite: suite.name,
@@ -1153,9 +1196,9 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
1153
1196
  });
1154
1197
  continue;
1155
1198
  }
1156
- if (test2.todo) {
1199
+ if (test.todo) {
1157
1200
  testResults.push({
1158
- name: test2.name,
1201
+ name: test.name,
1159
1202
  status: "todo",
1160
1203
  duration: 0,
1161
1204
  suite: suite.name,
@@ -1169,13 +1212,13 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
1169
1212
  const startTime = Date.now();
1170
1213
  try {
1171
1214
  await Promise.race([
1172
- test2.fn(),
1215
+ test.fn(),
1173
1216
  new Promise(
1174
- (_, reject) => setTimeout(() => reject(new Error(`Test timed out after ${test2.timeout}ms`)), test2.timeout)
1217
+ (_, reject) => setTimeout(() => reject(new Error(`Test timed out after ${test.timeout}ms`)), test.timeout)
1175
1218
  )
1176
1219
  ]);
1177
1220
  testResults.push({
1178
- name: test2.name,
1221
+ name: test.name,
1179
1222
  status: "pass",
1180
1223
  duration: Date.now() - startTime,
1181
1224
  suite: suite.name,
@@ -1189,7 +1232,7 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
1189
1232
  codeSnippet = error.codeSnippet;
1190
1233
  }
1191
1234
  testResults.push({
1192
- name: test2.name,
1235
+ name: test.name,
1193
1236
  status: "fail",
1194
1237
  duration: Date.now() - startTime,
1195
1238
  error,