diff --git a/.gitignore b/.gitignore index 93103040..cde25441 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ dist dist-self-build dist-types example-runner/example-repos +integration-test/test-cases/**/dist-actual spec-compliance-tests/test262/test262-checkout spec-compliance-tests/babel-tests/babel-tests-checkout integrations/gulp-plugin/dist diff --git a/integration-test/integration-tests.ts b/integration-test/integration-tests.ts index 23912302..49685b8e 100644 --- a/integration-test/integration-tests.ts +++ b/integration-test/integration-tests.ts @@ -1,11 +1,16 @@ import assert from "assert"; import {exec} from "child_process"; import {readdirSync, statSync} from "fs"; -import {writeFile} from "fs/promises"; -import {join, dirname} from "path"; +import {rm, writeFile} from "fs/promises"; +import {join, dirname, resolve} from "path"; import {promisify} from "util"; -import {readFileContents, readJSONFileContentsIfExists} from "../script/util/readFileContents"; +import { + readFileContents, + readJSONFileContents, + readJSONFileContentsIfExists, +} from "../script/util/readFileContents"; +import assertDirectoriesEqual from "./util/assertDirectoriesEqual"; const execPromise = promisify(exec); @@ -101,4 +106,24 @@ describe("integration tests", () => { ); }); } + + /** + * Find CLI integration tests. + * + * Each test must have a test.json file and directories "src" and + * "dist-expected". The Sucrase CLI is invoked with cliOptions and the result + * is expected to exactly match dist-expected. + */ + for (const testFile of discoverTests("test-cases/cli-cases", "test.json")) { + const testDir = dirname(testFile); + it(testDir, async () => { + process.chdir(testDir); + const testConfig = await readJSONFileContents("./test.json"); + await rm("./dist-actual", {recursive: true, force: true}); + await execPromise( + `${__dirname}/../bin/sucrase ./src --out-dir ./dist-actual ${testConfig.cliOptions}`, + ); + await assertDirectoriesEqual(resolve("./dist-actual"), resolve("./dist-expected")); + }); + } }); diff --git a/integration-test/test-cases/cli-cases/respects-disable-es-transforms/dist-expected/main.js b/integration-test/test-cases/cli-cases/respects-disable-es-transforms/dist-expected/main.js new file mode 100644 index 00000000..86ec743e --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-disable-es-transforms/dist-expected/main.js @@ -0,0 +1,4 @@ +class A { + x = 1; + constructor( y) {;this.y = y;} +} diff --git a/integration-test/test-cases/cli-cases/respects-disable-es-transforms/src/main.ts b/integration-test/test-cases/cli-cases/respects-disable-es-transforms/src/main.ts new file mode 100644 index 00000000..f78edb07 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-disable-es-transforms/src/main.ts @@ -0,0 +1,4 @@ +class A { + x: number = 1; + constructor(readonly y: string) {} +} diff --git a/integration-test/test-cases/cli-cases/respects-disable-es-transforms/test.json b/integration-test/test-cases/cli-cases/respects-disable-es-transforms/test.json new file mode 100644 index 00000000..9699e567 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-disable-es-transforms/test.json @@ -0,0 +1,3 @@ +{ + "cliOptions": "--transforms typescript --disable-es-transforms" +} diff --git a/integration-test/test-cases/cli-cases/respects-inject-create-require-for-import-require/dist-expected/main.js b/integration-test/test-cases/cli-cases/respects-inject-create-require-for-import-require/dist-expected/main.js new file mode 100644 index 00000000..bbda1a51 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-inject-create-require-for-import-require/dist-expected/main.js @@ -0,0 +1,6 @@ + import {createRequire as _createRequire} from "module"; const _require = _createRequire(import.meta.url); +const A = _require('../A'); + +function foo() { + console.log(A); +} diff --git a/integration-test/test-cases/cli-cases/respects-inject-create-require-for-import-require/src/main.ts b/integration-test/test-cases/cli-cases/respects-inject-create-require-for-import-require/src/main.ts new file mode 100644 index 00000000..cdad96fc --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-inject-create-require-for-import-require/src/main.ts @@ -0,0 +1,6 @@ + +import A = require('../A'); + +function foo(): void { + console.log(A); +} diff --git a/integration-test/test-cases/cli-cases/respects-inject-create-require-for-import-require/test.json b/integration-test/test-cases/cli-cases/respects-inject-create-require-for-import-require/test.json new file mode 100644 index 00000000..59896e97 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-inject-create-require-for-import-require/test.json @@ -0,0 +1,3 @@ +{ + "cliOptions": "--transforms typescript --inject-create-require-for-import-require" +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-defaults/dist-expected/main.js b/integration-test/test-cases/cli-cases/respects-jsx-defaults/dist-expected/main.js new file mode 100644 index 00000000..65e582b2 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-defaults/dist-expected/main.js @@ -0,0 +1,5 @@ +const _jsxFileName = "src/main.jsx";import React from 'react'; + +function Foo() { + return React.createElement(React.Fragment, null, React.createElement('div', {__self: this, __source: {fileName: _jsxFileName, lineNumber: 4}} )); +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-defaults/src/main.jsx b/integration-test/test-cases/cli-cases/respects-jsx-defaults/src/main.jsx new file mode 100644 index 00000000..a7272f21 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-defaults/src/main.jsx @@ -0,0 +1,5 @@ +import React from 'react'; + +function Foo() { + return <>
>; +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-defaults/test.json b/integration-test/test-cases/cli-cases/respects-jsx-defaults/test.json new file mode 100644 index 00000000..d3e49c02 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-defaults/test.json @@ -0,0 +1,3 @@ +{ + "cliOptions": "--transforms jsx" +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-runtime-automatic/dist-expected/main.js b/integration-test/test-cases/cli-cases/respects-jsx-runtime-automatic/dist-expected/main.js new file mode 100644 index 00000000..5cd5f076 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-runtime-automatic/dist-expected/main.js @@ -0,0 +1,4 @@ +const _jsxFileName = "src/main.tsx";import {jsxDEV as _jsxDEV} from "preact/jsx-dev-runtime"; +function Foo() { + return _jsxDEV('div', {}, void 0, false, {fileName: _jsxFileName, lineNumber: 3}, this ); +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-runtime-automatic/src/main.tsx b/integration-test/test-cases/cli-cases/respects-jsx-runtime-automatic/src/main.tsx new file mode 100644 index 00000000..da3f8440 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-runtime-automatic/src/main.tsx @@ -0,0 +1,4 @@ + +function Foo(): JSX.Element { + return ; +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-runtime-automatic/test.json b/integration-test/test-cases/cli-cases/respects-jsx-runtime-automatic/test.json new file mode 100644 index 00000000..4490aad6 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-runtime-automatic/test.json @@ -0,0 +1,3 @@ +{ + "cliOptions": "--transforms jsx,typescript --jsx-runtime automatic --jsx-import-source preact" +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-runtime-classic/dist-expected/main.js b/integration-test/test-cases/cli-cases/respects-jsx-runtime-classic/dist-expected/main.js new file mode 100644 index 00000000..77c4f777 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-runtime-classic/dist-expected/main.js @@ -0,0 +1,4 @@ + +function Foo() { + return h(React.Fragment, null, h('div', null )); +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-runtime-classic/src/main.jsx b/integration-test/test-cases/cli-cases/respects-jsx-runtime-classic/src/main.jsx new file mode 100644 index 00000000..f50392b1 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-runtime-classic/src/main.jsx @@ -0,0 +1,4 @@ + +function Foo() { + return <>>; +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-runtime-classic/test.json b/integration-test/test-cases/cli-cases/respects-jsx-runtime-classic/test.json new file mode 100644 index 00000000..5c78c501 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-runtime-classic/test.json @@ -0,0 +1,3 @@ +{ + "cliOptions": "--transforms jsx --production --jsx-pragma h jsx-fragment-pragma Frag" +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-runtime-preserve/dist-expected/main.js b/integration-test/test-cases/cli-cases/respects-jsx-runtime-preserve/dist-expected/main.js new file mode 100644 index 00000000..e49be6e0 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-runtime-preserve/dist-expected/main.js @@ -0,0 +1,3 @@ +function Foo() { + return ; +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-runtime-preserve/src/main.tsx b/integration-test/test-cases/cli-cases/respects-jsx-runtime-preserve/src/main.tsx new file mode 100644 index 00000000..a7265e6d --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-runtime-preserve/src/main.tsx @@ -0,0 +1,3 @@ +function Foo(): JSX.Element { + return ; +} diff --git a/integration-test/test-cases/cli-cases/respects-jsx-runtime-preserve/test.json b/integration-test/test-cases/cli-cases/respects-jsx-runtime-preserve/test.json new file mode 100644 index 00000000..6ac9442e --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-jsx-runtime-preserve/test.json @@ -0,0 +1,3 @@ +{ + "cliOptions": "--transforms jsx,typescript --jsx-runtime preserve" +} diff --git a/integration-test/test-cases/cli-cases/respects-keep-unused-imports/dist-expected/main.js b/integration-test/test-cases/cli-cases/respects-keep-unused-imports/dist-expected/main.js new file mode 100644 index 00000000..d5244311 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-keep-unused-imports/dist-expected/main.js @@ -0,0 +1,4 @@ +import A from '../A'; +import B from '../B'; + +console.log(A); diff --git a/integration-test/test-cases/cli-cases/respects-keep-unused-imports/src/main.ts b/integration-test/test-cases/cli-cases/respects-keep-unused-imports/src/main.ts new file mode 100644 index 00000000..d5244311 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-keep-unused-imports/src/main.ts @@ -0,0 +1,4 @@ +import A from '../A'; +import B from '../B'; + +console.log(A); diff --git a/integration-test/test-cases/cli-cases/respects-keep-unused-imports/test.json b/integration-test/test-cases/cli-cases/respects-keep-unused-imports/test.json new file mode 100644 index 00000000..e0789440 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-keep-unused-imports/test.json @@ -0,0 +1,3 @@ +{ + "cliOptions": "--transforms typescript --keep-unused-imports" +} diff --git a/integration-test/test-cases/cli-cases/respects-preserve-dynamic-import/dist-expected/main.js b/integration-test/test-cases/cli-cases/respects-preserve-dynamic-import/dist-expected/main.js new file mode 100644 index 00000000..d7377b6b --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-preserve-dynamic-import/dist-expected/main.js @@ -0,0 +1,6 @@ +"use strict"; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _A = require('../A'); var _A2 = _interopRequireDefault(_A); + +async function foo() { + const B = (await import("../B")).default; + console.log(_A2.default + B); +} diff --git a/integration-test/test-cases/cli-cases/respects-preserve-dynamic-import/src/main.js b/integration-test/test-cases/cli-cases/respects-preserve-dynamic-import/src/main.js new file mode 100644 index 00000000..55cfef29 --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-preserve-dynamic-import/src/main.js @@ -0,0 +1,6 @@ +import A from "../A"; + +async function foo() { + const B = (await import("../B")).default; + console.log(A + B); +} diff --git a/integration-test/test-cases/cli-cases/respects-preserve-dynamic-import/test.json b/integration-test/test-cases/cli-cases/respects-preserve-dynamic-import/test.json new file mode 100644 index 00000000..81c6576f --- /dev/null +++ b/integration-test/test-cases/cli-cases/respects-preserve-dynamic-import/test.json @@ -0,0 +1,3 @@ +{ + "cliOptions": "--transforms imports --preserve-dynamic-import" +} diff --git a/integration-test/util/assertDirectoriesEqual.ts b/integration-test/util/assertDirectoriesEqual.ts new file mode 100644 index 00000000..d8c53721 --- /dev/null +++ b/integration-test/util/assertDirectoriesEqual.ts @@ -0,0 +1,27 @@ +import * as assert from "assert"; +import {readdir, readFile, stat} from "fs/promises"; +import {join} from "path"; + +export default async function assertDirectoriesEqual(dir1: string, dir2: string): Promise