From 7497de02ab4e32eed5adcb2aeca75e1c6458ab5d Mon Sep 17 00:00:00 2001 From: montjeffrey Date: Fri, 9 Oct 2026 17:50:38 -0400 Subject: [PATCH] test(carriers): pin member calls and deeply nested computed arguments Two first-round review findings were never addressed, and both reproduce on the current head: - records.require('./label'), obj?.import('./x') and obj . require('./y') are method calls, but the call pattern's word boundary is satisfied by the dot, so a self-contained object method fails every projection for a file the script never loads. - The dynamic-argument pattern allows one level of nested parentheses, so require(path.join(__dirname, getName())) produces no dynamic warning while require(getName()) does. Control: a genuine require beside the member calls is still a dependency. --- tests/scripts/validate-carrier-closure.test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/scripts/validate-carrier-closure.test.js b/tests/scripts/validate-carrier-closure.test.js index 5c3c25a04..568bd342e 100644 --- a/tests/scripts/validate-carrier-closure.test.js +++ b/tests/scripts/validate-carrier-closure.test.js @@ -137,6 +137,13 @@ test('an extensionless require resolves to a .json file', () => withFixture(root assert.equal(result.status, 'success', JSON.stringify(result.failures)); })); +test('an object method named require is not a module load', () => withFixture(root => { + plantSkillScript(root, "const records = { require: name => name };\nmodule.exports = records.require('./label');\n"); + const result = validator().validate(root); + assert.equal(result.status, 'success', JSON.stringify(result.failures)); + assert.deepEqual(result.warnings, []); +})); + test('a tagged template named from is not an import', () => withFixture(root => { plantSkillScript(root, 'const from = parts => parts[0];\nmodule.exports = from`./helper`;\n'); const result = validator().validate(root); @@ -221,8 +228,16 @@ const SCANNER_CASES = [ "const n = obj?. while(x) / 2, q = \"/\"; require('./after-optional');", ['./after-optional']], ['a tagged template named from', 'const from = p => p[0]; const s = from`./helper`;', []], ['a template import() is still a dependency', 'import(`./templated`);', ['./templated']], + ['member calls named require or import', + "r.require('./label'); obj?.import('./x'); obj . require('./y'); obj.\nimport('./z'); require('./real');", ['./real']], ]; +test('scanner: computed arguments nested more than one level deep still warn', () => { + const { dynamic } = validator().extractReferences( + "require(path.join(__dirname, getName())); require(a(b(c()))); obj.require(hidden());"); + assert.deepEqual(dynamic.sort(), ['a(b(c()))', 'path.join(__dirname, getName())']); +}); + for (const [label, source, expected] of SCANNER_CASES) { test(`scanner: ${label}`, () => { assert.deepEqual(validator().extractReferences(source).specifiers.sort(), [...expected].sort());