Skip to content

Commit

Permalink
Handle ImportExpression nodes (#261)
Browse files Browse the repository at this point in the history
* feat: Analyse ImportExpression nodes

* test: add deeper test for entryFiles non .js extensions

* refactor: replace assert.strictEqual by assert.ok

* add empty line at end of file
  • Loading branch information
jean-michelet authored Apr 25, 2024
1 parent 55f52fa commit cfe2475
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/probes/isImportDeclaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
function validateNode(node) {
return [
// Note: the source property is the right-side Literal part of the Import
node.type === "ImportDeclaration" && node.source.type === "Literal"
["ImportDeclaration", "ImportExpression"].includes(node.type) && node.source.type === "Literal"
];
}

Expand Down
43 changes: 24 additions & 19 deletions test/EntryFilesAnalyser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ describe("EntryFilesAnalyser", () => {
const generator = entryFilesAnalyser.analyse([entryUrl, deepEntryUrl]);

// First entry
await assertReport(generator, entryUrl, true);
await assertReport(generator, new URL("deps/dep1.js", FIXTURE_URL), true);
await assertReport(generator, new URL("shared.js", FIXTURE_URL), true);
await assertReport(generator, new URL("deps/dep2.js", FIXTURE_URL), true);
await assertReport(generator, entryUrl);
await assertReport(generator, new URL("deps/dep1.js", FIXTURE_URL));
await assertReport(generator, new URL("shared.js", FIXTURE_URL));
await assertReport(generator, new URL("deps/dep2.js", FIXTURE_URL));

// Second entry
await assertReport(generator, deepEntryUrl, true);
await assertReport(generator, new URL("deps/dep3.js", FIXTURE_URL), true);
await assertReport(generator, deepEntryUrl);
await assertReport(generator, new URL("deps/dep3.js", FIXTURE_URL));

await assertAllReportsYielded(generator);

Expand All @@ -40,15 +40,15 @@ describe("EntryFilesAnalyser", () => {

const generator = entryFilesAnalyser.analyse([entryUrl]);

await assertReport(generator, entryUrl, true);
await assertReport(generator, entryUrl);

const invalidDepReport = await generator.next();
assert.ok(!invalidDepReport.value.ok);
assert.strictEqual(invalidDepReport.value.url, new URL("deps/invalidDep.js", FIXTURE_URL).pathname);
assert.strictEqual(invalidDepReport.value.warnings[0].kind, "parsing-error");

await assertReport(generator, new URL("deps/dep1.js", FIXTURE_URL), true);
await assertReport(generator, new URL("shared.js", FIXTURE_URL), true);
await assertReport(generator, new URL("deps/dep1.js", FIXTURE_URL));
await assertReport(generator, new URL("shared.js", FIXTURE_URL));

await assertAllReportsYielded(generator);
});
Expand All @@ -60,12 +60,16 @@ describe("EntryFilesAnalyser", () => {
const entryUrl = new URL("entryWithVariousDepExtensions.js", FIXTURE_URL);
const generator = entryFilesAnalyser.analyse([entryUrl]);

await assertReport(generator, entryUrl, true);
await assertReport(generator, new URL("deps/default.js", FIXTURE_URL), true);
await assertReport(generator, new URL("deps/default.cjs", FIXTURE_URL), true);
await assertReport(generator, new URL("deps/default.mjs", FIXTURE_URL), true);
await assertReport(generator, new URL("deps/default.node", FIXTURE_URL), true);
await assertReport(generator, new URL("deps/default.jsx", FIXTURE_URL), true);
await assertReport(generator, entryUrl);
await assertReport(generator, new URL("deps/default.js", FIXTURE_URL));
await assertReport(generator, new URL("deps/default.cjs", FIXTURE_URL));
await assertReport(generator, new URL("deps/dep.cjs", FIXTURE_URL));
await assertReport(generator, new URL("deps/default.mjs", FIXTURE_URL));
await assertReport(generator, new URL("deps/dep.mjs", FIXTURE_URL));
await assertReport(generator, new URL("deps/default.node", FIXTURE_URL));
await assertReport(generator, new URL("deps/dep.node", FIXTURE_URL));
await assertReport(generator, new URL("deps/default.jsx", FIXTURE_URL));
await assertReport(generator, new URL("deps/dep.jsx", FIXTURE_URL));

await assertAllReportsYielded(generator);
});
Expand All @@ -77,16 +81,17 @@ describe("EntryFilesAnalyser", () => {
const entryUrl = new URL("entryWithVariousDepExtensions.js", FIXTURE_URL);
const generator = entryFilesAnalyser.analyse([entryUrl]);

await assertReport(generator, entryUrl, true);
await assertReport(generator, new URL("deps/default.jsx", FIXTURE_URL), true);
await assertReport(generator, entryUrl);
await assertReport(generator, new URL("deps/default.jsx", FIXTURE_URL));
await assertReport(generator, new URL("deps/dep.jsx", FIXTURE_URL));

await assertAllReportsYielded(generator);
});

async function assertReport(generator, expectedUrl, expectedOk) {
async function assertReport(generator, expectedUrl) {
const report = await generator.next();
assert.strictEqual(report.value.url, expectedUrl.pathname);
assert.strictEqual(report.value.ok, expectedOk);
assert.ok(report.value.ok);
}

async function assertAllReportsYielded(generator) {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/entryFiles/deps/default.cjs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
require('externalDep')
require('dep.cjs')
3 changes: 2 additions & 1 deletion test/fixtures/entryFiles/deps/default.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react'
import Bar from './dep.jsx'

export default function Foo() {
return (
<div></div>
<Bar />
)
}
1 change: 1 addition & 0 deletions test/fixtures/entryFiles/deps/default.mjs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import externalDep from 'externalDep';
import('dep.mjs')
2 changes: 1 addition & 1 deletion test/fixtures/entryFiles/deps/default.node
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('some/addon');
module.exports = require('dep.node');
1 change: 1 addition & 0 deletions test/fixtures/entryFiles/deps/dep.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = {}
7 changes: 7 additions & 0 deletions test/fixtures/entryFiles/deps/dep.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react'

export default function Bar() {
return (
<div></div>
)
}
1 change: 1 addition & 0 deletions test/fixtures/entryFiles/deps/dep.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {}
1 change: 1 addition & 0 deletions test/fixtures/entryFiles/deps/dep.node
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('some/addon');
30 changes: 23 additions & 7 deletions test/probes/isImportDeclaration.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,32 @@ test("should detect 1 dependency with no specificiers", () => {
assert.ok(dependencies.has("bar"));
});

test("should detect 1 dependency for an ImportExpression", () => {
const str = "import(\"bar\")";
const ast = parseScript(str);
const { sourceFile } = getSastAnalysis(str, isImportDeclaration)
.execute(ast.body);

const { dependencies } = sourceFile;
assert.ok(dependencies.has("bar"));
});

test("should detect an unsafe import using data:text/javascript and throw a unsafe-import warning", () => {
const expectedValue = "data:text/javascript;base64,Y29uc29sZS5sb2coJ2hlbGxvIHdvcmxkJyk7Cg==";
const str = `import '${expectedValue}';`;

const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isImportDeclaration)
.execute(ast.body);
const importNodes = [
`import '${expectedValue}';`,
`import('${expectedValue}');`
];

importNodes.forEach((str) => {
const ast = parseScript(str);
const sastAnalysis = getSastAnalysis(str, isImportDeclaration)
.execute(ast.body);

assert.strictEqual(sastAnalysis.warnings().length, 1);
assert.strictEqual(sastAnalysis.warnings().length, 1);

const unsafeImport = sastAnalysis.getWarning("unsafe-import");
assert.strictEqual(unsafeImport.value, expectedValue);
const unsafeImport = sastAnalysis.getWarning("unsafe-import");
assert.strictEqual(unsafeImport.value, expectedValue);
});
});

0 comments on commit cfe2475

Please sign in to comment.