import traverse from "../lib"; import { parse } from "@babel/parser"; function getPath(code, options = { sourceType: "script" }) { const ast = parse(code, options); let path; traverse(ast, { Program: function (_path) { path = _path; _path.stop(); }, }); return path; } describe("path/introspection", function () { describe("isInStrictMode", function () { describe("classes", function () { it("returns parent's strictness for class", function () { let program = getPath("class Test extends Super {}"); let klass = program.get("body.0"); expect(klass.isInStrictMode()).toBeFalsy(); program = getPath(`"use strict"; class Test extends Super {}`); klass = program.get("body.0"); expect(klass.isInStrictMode()).toBeTruthy(); }); it("returns true for class id", function () { const program = getPath("class Test extends Super {}"); const id = program.get("body.0.id"); expect(id.isInStrictMode()).toBeTruthy(); }); it("returns true for superClass", function () { const program = getPath("class Test extends Super {}"); const superClass = program.get("body.0.superClass"); expect(superClass.isInStrictMode()).toBeTruthy(); }); it("returns true for method", function () { const program = getPath("class Test { test() {} }"); const method = program.get("body.0.body.body.0"); expect(method.isInStrictMode()).toBeTruthy(); }); }); describe("program", function () { describe("when script", function () { it("returns true when strict", function () { let program = getPath(`test;`); expect(program.isInStrictMode()).toBeFalsy(); program = getPath(`"use strict";`); expect(program.isInStrictMode()).toBeTruthy(); }); }); describe("when module", function () { it("returns true", function () { const program = getPath(`test;`, { sourceType: "module" }); expect(program.isInStrictMode()).toBeTruthy(); }); }); }); describe("function", function () { it("returns parent's strictness for function", function () { let program = getPath("function test() {}"); let fn = program.get("body.0"); expect(fn.isInStrictMode()).toBeFalsy(); program = getPath(`function test() {"use strict";}`); fn = program.get("body.0"); expect(fn.isInStrictMode()).toBeFalsy(); program = getPath(`"use strict"; function test() {}`); fn = program.get("body.0"); expect(fn.isInStrictMode()).toBeTruthy(); }); it("returns function's strictness for id", function () { let program = getPath("function test(a) {}"); let id = program.get("body.0.id"); expect(id.isInStrictMode()).toBeFalsy(); program = getPath(`function test(a) {"use strict";}`); id = program.get("body.0.id"); expect(id.isInStrictMode()).toBeTruthy(); }); it("returns function's strictness for parameters", function () { let program = getPath("function test(a) {}"); let param = program.get("body.0.params.0"); expect(param.isInStrictMode()).toBeFalsy(); program = getPath(`function test(a) {"use strict";}`); param = program.get("body.0.params.0"); expect(param.isInStrictMode()).toBeTruthy(); }); }); }); describe("referencesImport", function () { it("accepts a default import", function () { const program = getPath(`import dep from "source"; dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "default")).toBe(true); }); it("rejects a default import from the wrong module", function () { const program = getPath(`import dep from "wrong-source"; dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "default")).toBe(false); }); it("rejects a named instead of default import", function () { const program = getPath(`import { dep } from "source"; dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "default")).toBe(false); }); it("accepts a named import", function () { const program = getPath(`import { dep } from "source"; dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "dep")).toBe(true); }); it("accepts an aliased named import", function () { const program = getPath(`import { dep as alias } from "source"; alias;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "dep")).toBe(true); }); it("accepts a named import via a namespace import member expression", function () { const program = getPath(`import * as ns from "source"; ns.dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "dep")).toBe(true); }); it("accepts a named import via a namespace import optional member expression", function () { const program = getPath(`import * as ns from "source"; ns?.dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "dep")).toBe(true); }); it("accepts a named import via a namespace import computed member expression", function () { const program = getPath(`import * as ns from "source"; ns["😅"];`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "😅")).toBe(true); }); it("rejects a named import from the wrong module", function () { const program = getPath(`import { dep } from "wrong-source"; dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "dep")).toBe(false); }); it("rejects a default instead of named import", function () { const program = getPath(`import dep from "source"; dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "dep")).toBe(false); }); it('rejects the "export called *" trick', function () { const program = getPath(`import * as ns from "source"; ns["*"].nested;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "nested")).toBe(false); }); it("accepts a namespace import", function () { const program = getPath(`import * as dep from "source"; dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "*")).toBe(true); }); it("rejects a namespace import from the wrong module", function () { const program = getPath(`import * as dep from "wrong-source"; dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "*")).toBe(false); }); it("rejects a default instead of a namespace import", () => { const program = getPath(`import dep from "source"; dep;`, { sourceType: "module", }); const reference = program.get("body.1.expression"); expect(reference.referencesImport("source", "*")).toBe(false); }); }); });