lukeed / uvu

uvu is an extremely fast and lightweight test runner for Node.js and the browser
MIT License
2.97k stars 100 forks source link

`uvu -r` with relative path fails to find module #216

Open leaysgur opened 2 years ago

leaysgur commented 2 years ago

To reproduce,

// setup.js
globalThis.MOCK_VAR = 1;
// test.js
const { test } = require("uvu");
const assert = require("uvu/assert");

test("should load", () => {
  assert.is(globalThis.MOCK_VAR, 1);
});

test.run();

Then run uvu -r ./setup.js.

Error: Cannot find module "./setup.js"
    at /Users/leader22/Codes/uvu-repro/node_modules/uvu/parse/index.js:22:21
    at Array.forEach (<anonymous>)
    at parse (/Users/leader22/Codes/uvu-repro/node_modules/uvu/parse/index.js:20:11)
    at /Users/leader22/Codes/uvu-repro/node_modules/uvu/bin.js:23:20
    at o.parse (/Users/leader22/Codes/uvu-repro/node_modules/sade/lib/index.js:1:3402)
    at Object.<anonymous> (/Users/leader22/Codes/uvu-repro/node_modules/uvu/bin.js:35:3)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)

uvu -r ../../../setup.js or use absolute path works fine. And node -r ./setup.js test.js also works.

It seems regression happened at 0.5.4 > 0.5.5.

iliocatallo commented 1 year ago

I have the same problem here with 0.5.6. Running uvu -r ./src/setup.js as part of an npm script fails with Error: Cannot find module "src/setup.js". It works with an absolute path.

victordidenko commented 1 year ago

Same problem... I cannot update from 0.5.4 because of this. I use https://github.com/theKashey/rewiremock to mock modules, and want to load my module with overrides to avoid requiring it in each test file.

victordidenko commented 1 year ago

Applying this patch (via pnpm patch or yarn patch or patch-package) fixes issue for me, but I'm not sure, how to fix ES module of uvu. This patch is based on code from version 0.5.4 (patch for version 0.5.6)

diff --git a/parse/index.js b/parse/index.js
index a02f1118c49d6a24186fb5ef1dfbdf52d7443c10..0cdb8d5d1cfb15fc0a0a3755554c57d6d24b3714 100644
--- a/parse/index.js
+++ b/parse/index.js
@@ -7,6 +7,11 @@ const ls = promisify(readdir);
 const toStat = promisify(stat);
 const toRegex = x => new RegExp(x, 'i');

+function exists(dep) {
+   try { return require.resolve(dep) }
+   catch (err) { return false }
+}
+
 async function parse(dir, pattern, opts = {}) {
    if (pattern) pattern = toRegex(pattern);
    else if (dir) pattern = /(((?:[^\/]*(?:\/|$))*)[\\\/])?\w+\.([mc]js|[jt]sx?)$/;
@@ -18,8 +23,10 @@ async function parse(dir, pattern, opts = {}) {
    let ignores = ['^.git', 'node_modules'].concat(opts.ignore || []).map(toRegex);

    requires.forEach(name => {
-       try { return require(name) }
-       catch (e) { throw new Error(`Cannot find module "${name}"`) }
+       let tmp = exists(name);
+       if (tmp) return require(tmp);
+       if (tmp = exists(resolve(name))) return require(tmp);
+       throw new Error(`Cannot find module '${name}'`);
    });

    // NOTE: Node 8.x support
derekdon commented 1 year ago

Yeah same, we downgraded