Skip to content

Commit

Permalink
fix(component-testing): ability to import esm modules
Browse files Browse the repository at this point in the history
  • Loading branch information
DudaGod committed Oct 9, 2024
1 parent 8c399d3 commit 7ecf23d
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 6 deletions.
10 changes: 4 additions & 6 deletions src/bundle/test-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { TRANSFORM_EXTENSIONS, JS_EXTENSION_RE } from "./constants";
import { requireModuleSync } from "../utils/module";

import type { NodePath, PluginObj, TransformOptions } from "@babel/core";
import type { ImportDeclaration } from "@babel/types";

const STYLE_EXTESTION_RE = /\.(css|less|scss)$/;
const IGNORE_STYLE_ERRORS = ["Unexpected token"];
Expand All @@ -30,10 +29,10 @@ export const setupTransformHook = (opts: { removeNonJsImports?: boolean } = {}):
],
};

const customIgnoreImportsPlugin = (): PluginObj => ({
const customIgnoreImportsPlugin = ({ types: t }: { types: typeof babel.types }): PluginObj => ({
name: "ignore-imports",
visitor: {
ImportDeclaration(path: NodePath<ImportDeclaration>): void {
ImportDeclaration(path: NodePath<babel.types.ImportDeclaration>): void {
const extname = nodePath.extname(path.node.source.value);

if (extname && !extname.match(JS_EXTENSION_RE)) {
Expand All @@ -49,8 +48,9 @@ export const setupTransformHook = (opts: { removeNonJsImports?: boolean } = {}):
return;
}

if (err.code === "ERR_REQUIRE_ESM") {
if ((err as NodeJS.ErrnoException).code === "ERR_REQUIRE_ESM") {
mockEsmModuleImport(t, path);
return;
}
}
},
Expand Down Expand Up @@ -115,8 +115,6 @@ function genVarDeclKey(
t: typeof babel.types,
node: NodePath<babel.types.ImportDeclaration>["node"],
): babel.types.Identifier | babel.types.ObjectPattern {
console.log("node.specifiers:", node.specifiers);

if (node.specifiers.length === 1) {
if (["ImportDefaultSpecifier", "ImportNamespaceSpecifier"].includes(node.specifiers[0].type)) {
return t.identifier(node.specifiers[0].local.name);
Expand Down
84 changes: 84 additions & 0 deletions test/src/test-reader/test-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,90 @@ describe("test-transformer", () => {

assert.match(transformedCode, new RegExp(`require\\("${moduleName}"\\)`));
});

describe.only("replace import of esm module with a proxy", () => {
const moduleName = "esm-module";
const error = { message: "require() of ES Module", code: "ERR_REQUIRE_ESM" };
const expectedProxyValue =
"" +
`new Proxy({}, {\n` +
` get: function (target, prop) {\n` +
` return prop in target ? target[prop] : new Proxy(() => {}, this);\n` +
` },\n` +
` apply: function () {\n` +
` return new Proxy(() => {}, this);\n` +
` }\n` +
`});\n`;

let setupTransformHookStub!: typeof setupTransformHook;

beforeEach(() => {
const { setupTransformHook } = proxyquire("../../../src/test-reader/test-transformer", {
"../bundle": proxyquire.noCallThru().load("../../../src/bundle/test-transformer", {
"../utils/module": {
requireModuleSync: sandbox.stub().withArgs(moduleName).throws(error),
},
}),
});
setupTransformHookStub = setupTransformHook;
});

it("should replace with default import", async () => {
let transformedCode;
(pirates.addHook as SinonStub).callsFake(cb => {
transformedCode = cb(`import pkg from "${moduleName}"`, moduleName);
});

setupTransformHookStub({ removeNonJsImports: true });

assert.match(transformedCode, `const pkg = ${expectedProxyValue}`);
});

it("should replace with namespace import", async () => {
let transformedCode;
(pirates.addHook as SinonStub).callsFake(cb => {
transformedCode = cb(`import * as pkg from "${moduleName}"`, moduleName);
});

setupTransformHookStub({ removeNonJsImports: true });

assert.match(transformedCode, `const pkg = ${expectedProxyValue}`);
});

it("should replace with property import", async () => {
let transformedCode;
(pirates.addHook as SinonStub).callsFake(cb => {
transformedCode = cb(`import {a, b as c} from "${moduleName}"`, moduleName);
});

setupTransformHookStub({ removeNonJsImports: true });

assert.match(transformedCode, `` + `const {\n` + ` a,\n` + ` c\n` + `} = ${expectedProxyValue}`);
});
});

it("should replace import of esm module with a proxy", () => {
const moduleName = "esm-module";
const error = { message: "require() of ES Module", code: "ERR_REQUIRE_ESM" };

const { setupTransformHook } = proxyquire("../../../src/test-reader/test-transformer", {
"../bundle": proxyquire.noCallThru().load("../../../src/bundle/test-transformer", {
"../utils/module": {
requireModuleSync: sandbox.stub().withArgs(moduleName).throws(error),
},
}),
});

let transformedCode;

(pirates.addHook as SinonStub).callsFake(cb => {
transformedCode = cb(`import "${moduleName}"`, moduleName);
});

setupTransformHook({ removeNonJsImports: true });

assert.match(transformedCode, new RegExp(`require\\("${moduleName}"\\)`));
});
});
});
});

0 comments on commit 7ecf23d

Please sign in to comment.