├── .all-contributorsrc ├── .codecov.yml ├── .editorconfig ├── .env.default ├── .eslintrc.js ├── .gitattributes ├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ └── .gitkeep ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .ncurc.js ├── .prettierignore ├── .remarkrc.mjs ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── MAINTAINING.md ├── README.md ├── babel.config.js ├── commitlint.config.js ├── conventional.config.js ├── jest.config.js ├── lint-staged.config.js ├── logo.png ├── package-lock.json ├── package.json ├── prettier.config.js ├── release.config.js ├── spellcheck-commit.js ├── src ├── errors.ts ├── formatters │ └── prettier.ts ├── index.ts ├── plugin-tester.ts ├── serializers │ └── unstring-snapshot.ts ├── symbols.ts └── types.ts ├── test ├── __mocks__ │ └── @babel │ │ └── core.js ├── __snapshots__ │ ├── unit-index.test.ts.snap │ └── unit-plugin-tester.test.ts.snap ├── examples │ ├── __snapshots__ │ │ ├── example-1.test.ts.snap │ │ ├── example-2.test.ts.snap │ │ └── example-4.test.ts.snap │ ├── example-1.test.ts │ ├── example-2.test.ts │ ├── example-3.test.ts │ └── example-4.test.ts ├── fixtures │ ├── README.md │ ├── babelrc-inverted │ │ └── fixture │ │ │ ├── .babelrc │ │ │ ├── code.js │ │ │ └── output.js │ ├── babelrc-missing │ │ └── fixture │ │ │ └── code.jsx │ ├── babelrc │ │ └── fixture │ │ │ ├── cjs │ │ │ ├── .babelrc.cjs │ │ │ └── code.jsx │ │ │ ├── default │ │ │ ├── .babelrc │ │ │ └── code.jsx │ │ │ ├── js │ │ │ ├── .babelrc.js │ │ │ └── code.jsx │ │ │ └── json │ │ │ ├── .babelrc.json │ │ │ └── code.jsx │ ├── code-file-bad │ │ └── fixture │ │ │ ├── code.js │ │ │ └── output.js │ ├── code-files-multiple │ │ └── fixture │ │ │ ├── code.mjs │ │ │ ├── code.ts │ │ │ ├── code.tsx │ │ │ └── output.mjs │ ├── code-output-files-empty │ │ ├── empty-code-output │ │ │ ├── code.ts │ │ │ └── output.ts │ │ ├── empty-code │ │ │ ├── .babelrc.js │ │ │ ├── code.ts │ │ │ └── output.ts │ │ └── empty-output │ │ │ ├── .babelrc │ │ │ ├── code.ts │ │ │ └── output.ts │ ├── codeFixture-empty.js │ ├── codeFixture-indented.js │ ├── codeFixture-unchanging.js │ ├── codeFixture.js │ ├── collate-order-1 │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ ├── collate-order-2 │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ ├── creates-output-file │ │ └── fixture │ │ │ └── code.js │ ├── custom-extension │ │ └── fixture │ │ │ ├── code.multipart.ext │ │ │ └── output.ext │ ├── dir-name-with-dashes │ │ └── fixture-with-dashes │ │ │ ├── code.js │ │ │ └── output.js │ ├── empty │ │ └── .gitkeep │ ├── exec-and-code-files │ │ └── fixture │ │ │ ├── code.js │ │ │ └── exec.js │ ├── exec-and-output-files │ │ └── fixture │ │ │ ├── exec.js │ │ │ └── output.js │ ├── exec-file-bad │ │ └── fixture │ │ │ └── exec.js │ ├── exec-file-empty │ │ └── fixture │ │ │ └── exec.js │ ├── exec-file-failing │ │ └── fixture │ │ │ └── exec.js │ ├── exec-file-passing │ │ ├── cjs │ │ │ └── exec.cjs │ │ ├── js │ │ │ └── exec.js │ │ ├── mjs │ │ │ └── exec.mjs │ │ ├── random │ │ │ └── exec.ext │ │ └── ts │ │ │ ├── .babelrc │ │ │ └── exec.ts │ ├── exec-supports-features │ │ └── fixture │ │ │ ├── exec.js │ │ │ └── imported-file.json │ ├── execFixture-empty.js │ ├── execFixture.js │ ├── multiple-with-only │ │ ├── fixture-1 │ │ │ ├── code.js │ │ │ └── output.js │ │ ├── fixture-2 │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ │ ├── fixture-3 │ │ │ ├── .babelrc │ │ │ ├── code.jsx │ │ │ └── options.json │ │ ├── fixture-4 │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ │ └── fixture-5 │ │ │ ├── code.multipart.ext │ │ │ └── output.ext │ ├── multiple-with-skip │ │ ├── fixture-1 │ │ │ ├── code.js │ │ │ └── output.js │ │ ├── fixture-2 │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ │ ├── fixture-3 │ │ │ ├── .babelrc │ │ │ ├── code.jsx │ │ │ └── options.json │ │ ├── fixture-4 │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ │ └── fixture-5 │ │ │ ├── code.multipart.ext │ │ │ └── output.ext │ ├── multiple │ │ ├── fixture-1 │ │ │ ├── code.js │ │ │ └── output.js │ │ ├── fixture-2 │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ │ ├── fixture-3 │ │ │ ├── .babelrc │ │ │ ├── code.jsx │ │ │ └── output.jsx │ │ ├── fixture-4 │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ │ └── fixture-5 │ │ │ ├── code.multipart.ext │ │ │ └── output.ext │ ├── nested-babelrc │ │ ├── .babelrc.json │ │ ├── nested │ │ │ ├── .babelrc │ │ │ ├── with-babelrc-extends │ │ │ │ ├── .babelrc.js │ │ │ │ └── code.jsx │ │ │ └── with-babelrc-no-extends │ │ │ │ ├── .babelrc │ │ │ │ └── code.jsx │ │ └── with-babelrc-no-extends │ │ │ ├── .babelrc.cjs │ │ │ └── code.jsx │ ├── nested-incorrectly │ │ ├── code.js │ │ ├── correct-within-incorrect │ │ │ ├── code.js │ │ │ ├── incorrect-within-correct │ │ │ │ ├── code.js │ │ │ │ └── output.js │ │ │ └── output.js │ │ └── output.js │ ├── nested-options-js-plugin │ │ ├── nested │ │ │ ├── deeply │ │ │ │ └── with-options │ │ │ │ │ ├── code.js │ │ │ │ │ ├── options.js │ │ │ │ │ └── output.js │ │ │ ├── options.js │ │ │ ├── with-options │ │ │ │ ├── code.js │ │ │ │ ├── options.js │ │ │ │ └── output.js │ │ │ └── without-options │ │ │ │ ├── code.js │ │ │ │ └── output.js │ │ ├── options.js │ │ └── without-options │ │ │ ├── code.js │ │ │ └── output.js │ ├── nested-options-js-preset │ │ ├── nested │ │ │ ├── deeply │ │ │ │ └── with-options │ │ │ │ │ ├── code.js │ │ │ │ │ ├── options.js │ │ │ │ │ └── output.js │ │ │ ├── options.js │ │ │ ├── with-options │ │ │ │ ├── code.js │ │ │ │ ├── options.js │ │ │ │ └── output.js │ │ │ └── without-options │ │ │ │ ├── code.js │ │ │ │ └── output.js │ │ ├── options.js │ │ └── without-options │ │ │ ├── code.js │ │ │ └── output.js │ ├── nested-options-json-and-js-plugin │ │ ├── nested │ │ │ ├── deeply │ │ │ │ └── with-options │ │ │ │ │ ├── code.js │ │ │ │ │ ├── options.js │ │ │ │ │ └── output.js │ │ │ ├── options.js │ │ │ ├── with-options │ │ │ │ ├── code.js │ │ │ │ ├── options.json │ │ │ │ └── output.js │ │ │ └── without-options │ │ │ │ ├── code.js │ │ │ │ └── output.js │ │ ├── options.json │ │ └── without-options │ │ │ ├── code.js │ │ │ └── output.js │ ├── nested-options-json-and-js-preset │ │ ├── nested │ │ │ ├── deeply │ │ │ │ └── with-options │ │ │ │ │ ├── code.js │ │ │ │ │ ├── options.js │ │ │ │ │ └── output.js │ │ │ ├── options.js │ │ │ ├── with-options │ │ │ │ ├── code.js │ │ │ │ ├── options.json │ │ │ │ └── output.js │ │ │ └── without-options │ │ │ │ ├── code.js │ │ │ │ └── output.js │ │ ├── options.json │ │ └── without-options │ │ │ ├── code.js │ │ │ └── output.js │ ├── nested-options-json-plugin │ │ ├── nested │ │ │ ├── deeply │ │ │ │ └── with-options │ │ │ │ │ ├── code.js │ │ │ │ │ ├── options.json │ │ │ │ │ └── output.js │ │ │ ├── options.json │ │ │ ├── with-options │ │ │ │ ├── code.js │ │ │ │ ├── options.json │ │ │ │ └── output.js │ │ │ └── without-options │ │ │ │ ├── code.js │ │ │ │ └── output.js │ │ ├── options.json │ │ └── without-options │ │ │ ├── code.js │ │ │ └── output.js │ ├── nested-options-json-preset │ │ ├── nested │ │ │ ├── deeply │ │ │ │ └── with-options │ │ │ │ │ ├── code.js │ │ │ │ │ ├── options.json │ │ │ │ │ └── output.js │ │ │ ├── options.json │ │ │ ├── with-options │ │ │ │ ├── code.js │ │ │ │ ├── options.json │ │ │ │ └── output.js │ │ │ └── without-options │ │ │ │ ├── code.js │ │ │ │ └── output.js │ │ ├── options.json │ │ └── without-options │ │ │ ├── code.js │ │ │ └── output.js │ ├── nested-titles │ │ ├── nested │ │ │ ├── deeply │ │ │ │ └── with-options │ │ │ │ │ ├── code.js │ │ │ │ │ ├── options.js │ │ │ │ │ └── output.js │ │ │ ├── options.js │ │ │ ├── with-options │ │ │ │ ├── code.js │ │ │ │ ├── options.js │ │ │ │ └── output.js │ │ │ └── without-options │ │ │ │ ├── code.js │ │ │ │ └── output.js │ │ ├── options.js │ │ └── without-options │ │ │ ├── code.js │ │ │ └── output.js │ ├── option-babelOptions-assumptions │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-babelOptions-filename │ │ ├── code │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ │ └── exec │ │ │ ├── exec.js │ │ │ └── options.json │ ├── option-endOfLine-auto │ │ ├── crlf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ │ └── lf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ ├── option-endOfLine-crlf │ │ ├── crlf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ │ └── lf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ ├── option-endOfLine-default │ │ ├── crlf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ │ └── lf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ ├── option-endOfLine-false │ │ ├── crlf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ │ └── lf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ ├── option-endOfLine-lf │ │ ├── crlf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ │ └── lf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ ├── option-endOfLine-preserve-no-eol │ │ ├── empty │ │ │ ├── code.js │ │ │ └── output.js │ │ └── no-eol │ │ │ ├── code.js │ │ │ └── output.js │ ├── option-endOfLine-preserve │ │ ├── crlf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ │ └── lf │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ ├── option-fixtureOutputExt-no-dot │ │ └── fixture │ │ │ ├── code.ts │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-fixtureOutputExt │ │ └── fixture │ │ │ ├── code.ts │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-fixtureOutputName │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── out.js │ ├── option-formatResult │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ ├── option-only │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-pluginOptions │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-presetOptions │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-setup-teardown │ │ ├── no-return │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ │ ├── options.js │ │ ├── return-fn │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ │ └── return-promise │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ ├── option-skip-only │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-skip │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-throws-and-exec-file │ │ └── fixture │ │ │ ├── exec.js │ │ │ └── options.json │ ├── option-throws-and-output-file │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-throws-class │ │ └── fixture │ │ │ ├── code.js │ │ │ └── options.js │ ├── option-throws-error-deprecated │ │ └── fixture │ │ │ ├── code.js │ │ │ └── options.json │ ├── option-throws-false-function │ │ └── fixture │ │ │ ├── code.js │ │ │ └── options.js │ ├── option-throws-false │ │ └── fixture │ │ │ ├── code.js │ │ │ └── options.json │ ├── option-throws-function │ │ └── fixture │ │ │ ├── code.js │ │ │ └── options.js │ ├── option-throws-regex │ │ └── fixture │ │ │ ├── code.js │ │ │ └── options.js │ ├── option-throws-string │ │ └── fixture │ │ │ ├── code.js │ │ │ └── options.js │ ├── option-throws-true │ │ └── fixture │ │ │ ├── code.js │ │ │ └── options.json │ ├── option-title-empty │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── option-title │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── options-bad-babelOptions-babelrc-filename │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ ├── options-js-bad │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ ├── options-js │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ └── output.js │ ├── options-json-and-js │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── options-json-bad │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── options-json │ │ └── fixture │ │ │ ├── code.js │ │ │ ├── options.json │ │ │ └── output.js │ ├── outputFixture-empty.js │ ├── outputFixture-indented.js │ ├── outputFixture.js │ ├── prettier-configured │ │ └── fixture │ │ │ ├── .prettierrc.js │ │ │ ├── code.js │ │ │ └── output.js │ ├── prettier │ │ └── fixture │ │ │ ├── code.js │ │ │ └── output.js │ ├── simple-failing │ │ └── fixture │ │ │ ├── code.js │ │ │ └── output.js │ ├── simple-multiline │ │ └── fixture │ │ │ ├── .gitattributes │ │ │ ├── code.js │ │ │ └── output.js │ ├── simple-reversed │ │ └── fixture │ │ │ ├── code.js │ │ │ └── output.js │ ├── simple │ │ └── fixture │ │ │ ├── code.js │ │ │ └── output.js │ ├── support-jsx │ │ └── fixture │ │ │ ├── .babelrc │ │ │ └── code.jsx │ ├── support-ts │ │ └── fixture │ │ │ ├── .babelrc │ │ │ ├── code.ts │ │ │ └── output.ts │ └── support-tsx │ │ └── fixture │ │ ├── .babelrc │ │ └── code.tsx ├── helpers │ ├── index.ts │ ├── plugin-add-line.js │ ├── plugin-delete-variables.js │ ├── plugin-identifier-reverse.js │ └── plugins.ts ├── integration │ ├── assets │ │ ├── index.ts │ │ ├── main │ │ │ ├── fixtures │ │ │ │ └── dummy-fixture-asset │ │ │ │ │ ├── code.js │ │ │ │ │ ├── options.js │ │ │ │ │ └── output.js │ │ │ ├── invocation-only.js │ │ │ ├── invocation-skip.js │ │ │ ├── invocation-snapshot.js │ │ │ └── invocation.js │ │ ├── plugin-identifier-reverse.js │ │ └── pure │ │ │ ├── fixtures │ │ │ └── dummy-fixture-asset │ │ │ │ ├── code.js │ │ │ │ ├── options.js │ │ │ │ └── output.js │ │ │ ├── invocation-only.js │ │ │ ├── invocation-skip.js │ │ │ ├── invocation-snapshot.js │ │ │ └── invocation.js │ ├── integration-node-interop.test.ts │ ├── integration-node-smoke.test.ts │ ├── test-config.ts │ ├── test-expectations.ts │ └── test-interop.ts ├── setup.ts ├── unit-formatters-prettier.test.ts ├── unit-index.test.ts └── unit-plugin-tester.test.ts ├── tsconfig.eslint.json ├── tsconfig.json ├── tsconfig.lint.json ├── tsconfig.types.json └── types └── unique-filename.d.ts /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "babel-plugin-tester", 3 | "projectOwner": "babel-utils", 4 | "imageSize": 100, 5 | "commit": false, 6 | "contributorsPerLine": 7, 7 | "repoHost": "https://github.com", 8 | "repoType": "github", 9 | "skipCi": false, 10 | "files": [ 11 | "README.md" 12 | ], 13 | "contributors": [ 14 | { 15 | "login": "kentcdodds", 16 | "name": "Kent C. Dodds", 17 | "avatar_url": "https://avatars.githubusercontent.com/u/1500684?v=3", 18 | "profile": "https://kentcdodds.com", 19 | "contributions": [ 20 | "code", 21 | "doc", 22 | "infra", 23 | "test" 24 | ] 25 | }, 26 | { 27 | "login": "jamiebuilds", 28 | "name": "james kyle", 29 | "avatar_url": "https://avatars3.githubusercontent.com/u/952783?v=3", 30 | "profile": "http://thejameskyle.com/", 31 | "contributions": [ 32 | "code", 33 | "doc", 34 | "review", 35 | "test" 36 | ] 37 | }, 38 | { 39 | "login": "bbohen", 40 | "name": "Brad Bohen", 41 | "avatar_url": "https://avatars1.githubusercontent.com/u/1894628?v=3", 42 | "profile": "https://github.com/bbohen", 43 | "contributions": [ 44 | "bug" 45 | ] 46 | }, 47 | { 48 | "login": "kwelch", 49 | "name": "Kyle Welch", 50 | "avatar_url": "https://avatars0.githubusercontent.com/u/1295580?v=3", 51 | "profile": "http://www.krwelch.com", 52 | "contributions": [ 53 | "code", 54 | "doc", 55 | "test" 56 | ] 57 | }, 58 | { 59 | "login": "kontrollanten", 60 | "name": "kontrollanten", 61 | "avatar_url": "https://avatars3.githubusercontent.com/u/6680299?v=4", 62 | "profile": "https://github.com/kontrollanten", 63 | "contributions": [ 64 | "code" 65 | ] 66 | }, 67 | { 68 | "login": "rubennorte", 69 | "name": "Rubén Norte", 70 | "avatar_url": "https://avatars3.githubusercontent.com/u/117921?v=4", 71 | "profile": "https://github.com/rubennorte", 72 | "contributions": [ 73 | "code", 74 | "test" 75 | ] 76 | }, 77 | { 78 | "login": "andrefgneves", 79 | "name": "André Neves", 80 | "avatar_url": "https://avatars2.githubusercontent.com/u/3869532?v=4", 81 | "profile": "http://andreneves.work", 82 | "contributions": [ 83 | "code", 84 | "test" 85 | ] 86 | }, 87 | { 88 | "login": "merceyz", 89 | "name": "Kristoffer K.", 90 | "avatar_url": "https://avatars0.githubusercontent.com/u/3842800?v=4", 91 | "profile": "https://github.com/merceyz", 92 | "contributions": [ 93 | "code", 94 | "test" 95 | ] 96 | }, 97 | { 98 | "login": "lifeart", 99 | "name": "Alex Kanunnikov", 100 | "avatar_url": "https://avatars2.githubusercontent.com/u/1360552?v=4", 101 | "profile": "https://github.com/lifeart", 102 | "contributions": [ 103 | "code", 104 | "test" 105 | ] 106 | }, 107 | { 108 | "login": "eps1lon", 109 | "name": "Sebastian Silbermann", 110 | "avatar_url": "https://avatars3.githubusercontent.com/u/12292047?v=4", 111 | "profile": "https://solverfox.dev", 112 | "contributions": [ 113 | "code" 114 | ] 115 | }, 116 | { 117 | "login": "RIP21", 118 | "name": "Andrey Los", 119 | "avatar_url": "https://avatars1.githubusercontent.com/u/3940079?v=4", 120 | "profile": "http://ololos.space/", 121 | "contributions": [ 122 | "bug" 123 | ] 124 | }, 125 | { 126 | "login": "charlesbodman", 127 | "name": "Charles Bodman", 128 | "avatar_url": "https://avatars2.githubusercontent.com/u/231894?v=4", 129 | "profile": "https://github.com/charlesbodman", 130 | "contributions": [ 131 | "doc" 132 | ] 133 | }, 134 | { 135 | "login": "MichaelDeBoey", 136 | "name": "Michaël De Boey", 137 | "avatar_url": "https://avatars3.githubusercontent.com/u/6643991?v=4", 138 | "profile": "https://michaeldeboey.be", 139 | "contributions": [ 140 | "code" 141 | ] 142 | }, 143 | { 144 | "login": "yuyaryshev", 145 | "name": "yuyaryshev", 146 | "avatar_url": "https://avatars0.githubusercontent.com/u/18558421?v=4", 147 | "profile": "https://github.com/yuyaryshev", 148 | "contributions": [ 149 | "code" 150 | ] 151 | }, 152 | { 153 | "login": "CzBuCHi", 154 | "name": "Marek Buchar", 155 | "avatar_url": "https://avatars0.githubusercontent.com/u/12444673?v=4", 156 | "profile": "https://github.com/CzBuCHi", 157 | "contributions": [ 158 | "code", 159 | "test", 160 | "doc" 161 | ] 162 | }, 163 | { 164 | "login": "jayphelps", 165 | "name": "Jay Phelps", 166 | "avatar_url": "https://avatars1.githubusercontent.com/u/762949?v=4", 167 | "profile": "https://twitter.com/_jayphelps", 168 | "contributions": [ 169 | "review" 170 | ] 171 | }, 172 | { 173 | "login": "mathiassoeholm", 174 | "name": "Mathias", 175 | "avatar_url": "https://avatars0.githubusercontent.com/u/1747242?v=4", 176 | "profile": "https://www.mathiassoeholm.com", 177 | "contributions": [ 178 | "doc" 179 | ] 180 | }, 181 | { 182 | "login": "moon-stripe", 183 | "name": "joe moon", 184 | "avatar_url": "https://avatars.githubusercontent.com/u/40330875?v=4", 185 | "profile": "http://go/moon", 186 | "contributions": [ 187 | "code", 188 | "test" 189 | ] 190 | }, 191 | { 192 | "login": "Xunnamius", 193 | "name": "Bernard", 194 | "avatar_url": "https://avatars.githubusercontent.com/u/656017?v=4", 195 | "profile": "https://xunn.io", 196 | "contributions": [ 197 | "code", 198 | "test", 199 | "doc", 200 | "infra", 201 | "review", 202 | "maintenance" 203 | ] 204 | }, 205 | { 206 | "login": "layershifter", 207 | "name": "Oleksandr Fediashov", 208 | "avatar_url": "https://avatars.githubusercontent.com/u/14183168?v=4", 209 | "profile": "https://www.linkedin.com/in/layershifter/", 210 | "contributions": [ 211 | "bug" 212 | ] 213 | }, 214 | { 215 | "login": "Andarist", 216 | "name": "Mateusz Burzyński", 217 | "avatar_url": "https://avatars.githubusercontent.com/u/9800850?v=4", 218 | "profile": "https://github.com/Andarist", 219 | "contributions": [ 220 | "code" 221 | ] 222 | }, 223 | { 224 | "login": "hulkish", 225 | "name": "Steven Hargrove", 226 | "avatar_url": "https://avatars.githubusercontent.com/u/139332?v=4", 227 | "profile": "https://github.com/hulkish", 228 | "contributions": [ 229 | "code", 230 | "doc" 231 | ] 232 | }, 233 | { 234 | "login": "alexrhogue", 235 | "name": "Alex R Hogue", 236 | "avatar_url": "https://avatars.githubusercontent.com/u/896170?v=4", 237 | "profile": "https://github.com/alexrhogue", 238 | "contributions": [ 239 | "code" 240 | ] 241 | }, 242 | { 243 | "login": "infctr", 244 | "name": "Arthur Zahorski", 245 | "avatar_url": "https://avatars.githubusercontent.com/u/15550153?v=4", 246 | "profile": "https://github.com/infctr", 247 | "contributions": [ 248 | "code" 249 | ] 250 | }, 251 | { 252 | "login": "egoist", 253 | "name": "EGOIST", 254 | "avatar_url": "https://avatars.githubusercontent.com/u/8784712?v=4", 255 | "profile": "https://egoist.dev/", 256 | "contributions": [ 257 | "infra" 258 | ] 259 | }, 260 | { 261 | "login": "ifiokjr", 262 | "name": "Ifiok Jr.", 263 | "avatar_url": "https://avatars.githubusercontent.com/u/1160934?v=4", 264 | "profile": "https://ifiokjr.com/", 265 | "contributions": [ 266 | "platform" 267 | ] 268 | }, 269 | { 270 | "login": "buschtoens", 271 | "name": "Jan Buschtöns", 272 | "avatar_url": "https://avatars.githubusercontent.com/u/834636?v=4", 273 | "profile": "https://jan.buschtoens.me/", 274 | "contributions": [ 275 | "code" 276 | ] 277 | }, 278 | { 279 | "login": "malbernaz", 280 | "name": "Miguel Albernaz", 281 | "avatar_url": "https://avatars.githubusercontent.com/u/10574149?v=4", 282 | "profile": "https://github.com/malbernaz", 283 | "contributions": [ 284 | "code", 285 | "infra" 286 | ] 287 | }, 288 | { 289 | "login": "peterlebrun", 290 | "name": "peterlebrun", 291 | "avatar_url": "https://avatars.githubusercontent.com/u/1267171?v=4", 292 | "profile": "https://github.com/peterlebrun", 293 | "contributions": [ 294 | "doc" 295 | ] 296 | }, 297 | { 298 | "login": "SimenB", 299 | "name": "Simen Bekkhus", 300 | "avatar_url": "https://avatars.githubusercontent.com/u/1404810?v=4", 301 | "profile": "https://github.com/SimenB", 302 | "contributions": [ 303 | "bug" 304 | ] 305 | } 306 | ], 307 | "commitConvention": "angular" 308 | } 309 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | range: '75...100' 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 2 10 | -------------------------------------------------------------------------------- /.env.default: -------------------------------------------------------------------------------- 1 | # When running a (projector) pipeline via GHA/Vercel, all required env vars must 2 | # be defined as repo secrets. With projector, the sync command handles this. 3 | 4 | # Codecov test analysis token 5 | # 6 | # Required: if deploying 7 | # On-Sync: mirror 8 | # 9 | # The token used during CI/CD to analyze and upload build artifact code quality 10 | # data to Codecov. 11 | CODECOV_TOKEN= 12 | 13 | # GitHub deploy token 14 | # 15 | # Alias: GH_TOKEN 16 | # Required: if deploying 17 | # On-Sync: mirror 18 | # 19 | # The token used during CI/CD to interact with GitHub's API. 20 | GITHUB_TOKEN= 21 | 22 | # NPM deploy token 23 | # 24 | # Required: if deploying 25 | # On-Sync: mirror 26 | # 27 | # The token used during CD to login to NPM. Not referenced during non-CI/CD 28 | # (i.e. local, manual) deployments. 29 | NPM_TOKEN= 30 | 31 | # Git push author name 32 | # 33 | # Required: if deploying 34 | # On-Sync: mirror 35 | # 36 | # The token used during CD to set the author name of the git push. 37 | GIT_AUTHOR_NAME= 38 | 39 | # Git commit committer name 40 | # 41 | # Required: if deploying 42 | # On-Sync: mirror 43 | # 44 | # The token used during CD to set the name attached to any git commits. 45 | GIT_COMMITTER_NAME= 46 | 47 | # Git push author email 48 | # 49 | # Required: if deploying 50 | # On-Sync: mirror 51 | # 52 | # The token used during CD to set the author email of the git push. 53 | GIT_AUTHOR_EMAIL= 54 | 55 | # Git commit committer email 56 | # 57 | # Required: if deploying 58 | # On-Sync: mirror 59 | # 60 | # The token used during CD to set the email attached to any git commits. 61 | GIT_COMMITTER_EMAIL= 62 | 63 | # GPG private key passphrase 64 | # 65 | # Required: if deploying with CI/CD 66 | # On-Sync: mirror 67 | # 68 | # The passphrase used to unlock GPG_PRIVATE_KEY. Not referenced during non-CI/CD 69 | # (i.e. local, manual) deployments. 70 | GPG_PASSPHRASE= 71 | 72 | # GPG private key 73 | # 74 | # Required: if deploying with CI/CD 75 | # On-Sync: mirror 76 | # 77 | # The GPG key used to sign all git commits and releases. Not referenced during 78 | # non-CI/CD (i.e. local, manual) deployments. 79 | GPG_PRIVATE_KEY= 80 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const plugins = ['unicorn', '@typescript-eslint', 'import']; 4 | 5 | const xtends = [ 6 | 'eslint:recommended', 7 | 'plugin:@typescript-eslint/eslint-recommended', 8 | 'plugin:@typescript-eslint/recommended', 9 | 'plugin:import/errors', 10 | 'plugin:import/warnings', 11 | 'plugin:import/typescript', 12 | 'plugin:unicorn/recommended' 13 | ]; 14 | 15 | const environment = { 16 | es2022: true, 17 | node: true 18 | // * Instead of including more options here, enable them on a per-file basis 19 | }; 20 | 21 | const rules = { 22 | 'no-console': 'warn', 23 | 'no-return-await': 'warn', 24 | 'no-await-in-loop': 'warn', 25 | 'import/no-unresolved': ['error', { commonjs: true }], 26 | 'no-extra-boolean-cast': 'off', 27 | 'no-empty': 'off', 28 | '@typescript-eslint/camelcase': 'off', 29 | '@typescript-eslint/explicit-function-return-type': 'off', 30 | '@typescript-eslint/explicit-module-boundary-types': 'off', 31 | '@typescript-eslint/prefer-ts-expect-error': 'warn', 32 | '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }], 33 | '@typescript-eslint/ban-ts-comment': [ 34 | 'warn', 35 | { 36 | 'ts-expect-error': 'allow-with-description', 37 | minimumDescriptionLength: 6 38 | } 39 | ], 40 | '@typescript-eslint/no-unused-vars': [ 41 | 'warn', 42 | { 43 | argsIgnorePattern: '^_+', 44 | varsIgnorePattern: '^_+', 45 | caughtErrorsIgnorePattern: '^ignored?\\d*$', 46 | caughtErrors: 'all' 47 | } 48 | ], 49 | // ? Ever since v4, we will rely on TypeScript to catch these 50 | 'no-undef': 'off', 51 | '@typescript-eslint/no-var-requires': 'off', 52 | // ? I'll be good, I promise 53 | '@typescript-eslint/no-non-null-assertion': 'off', 54 | '@typescript-eslint/consistent-type-imports': [ 55 | 'error', 56 | { disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' } 57 | ], 58 | '@typescript-eslint/consistent-type-exports': [ 59 | 'error', 60 | { fixMixedExportsWithInlineTypeSpecifier: true } 61 | ], 62 | 'no-unused-vars': 'off', 63 | 'unicorn/no-keyword-prefix': 'warn', 64 | 'unicorn/prefer-string-replace-all': 'warn', 65 | // ? Handled by integration tests 66 | 'unicorn/prefer-module': 'off', 67 | // ? I am of the opinion that there is a difference between something being 68 | // ? defined as nothing and something being undefined 69 | 'unicorn/no-null': 'off', 70 | // ? If MongoDB can get away with "DB" in its name, so can we. Also, 71 | // ? unnecessary underscores are a big no-no. 72 | 'unicorn/prevent-abbreviations': [ 73 | 'warn', 74 | { 75 | checkFilenames: false, 76 | replacements: { 77 | args: false, 78 | str: false, 79 | fn: false, 80 | db: false, 81 | dir: false, 82 | dist: false, 83 | tmp: false, 84 | pkg: false, 85 | src: false, 86 | dest: false, 87 | obj: false, 88 | val: false, 89 | env: false 90 | }, 91 | ignore: [/stderr/i] 92 | } 93 | ], 94 | // ? Actually, I rather like this curt syntax 95 | 'unicorn/no-await-expression-member': 'off', 96 | // ? Between disabling this and disabling no-empty-function, I choose this 97 | 'unicorn/no-useless-undefined': 'off', 98 | // ? Not sure why this isn't the default 99 | 'unicorn/prefer-export-from': ['warn', { ignoreUsedVariables: true }], 100 | // ? Yeah, I read The Good Parts too, I know what I'm doing 101 | 'unicorn/consistent-function-scoping': 'off', 102 | // ? It's 2022. Use Prettier 103 | 'unicorn/no-nested-ternary': 'off', 104 | // ? `Array.from` communicates intent much better than `[...]` 105 | 'unicorn/prefer-spread': 'off', 106 | // ? Not realistic when using TypeScript 107 | 'unicorn/prefer-native-coercion-functions': 'off', 108 | // ? Premature optimization is evil 109 | 'unicorn/no-array-for-each': 'off', 110 | // ? Lol, no 111 | 'unicorn/explicit-length-check': 'off', 112 | // ? I don't think so 113 | 'unicorn/no-negated-condition': 'off' 114 | }; 115 | 116 | module.exports = { 117 | parser: '@typescript-eslint/parser', 118 | plugins, 119 | extends: xtends, 120 | parserOptions: { 121 | ecmaVersion: 'latest', 122 | sourceType: 'module', 123 | ecmaFeatures: { 124 | impliedStrict: true, 125 | jsx: true 126 | }, 127 | project: 'tsconfig.eslint.json' 128 | }, 129 | env: environment, 130 | rules, 131 | overrides: [ 132 | { 133 | files: ['*.test.*'], 134 | plugins: [...plugins, 'jest'], 135 | env: { ...environment, jest: true }, 136 | extends: [...xtends, 'plugin:jest/all', 'plugin:jest/style'], 137 | rules: { 138 | ...rules, 139 | 'jest/lowercase': 'off', 140 | 'jest/consistent-test-it': 'off', 141 | 'jest/require-top-level-describe': 'off', 142 | 'jest/valid-describe': 'off', 143 | 'jest/no-hooks': 'off', 144 | 'jest/require-to-throw-message': 'off', 145 | 'jest/prefer-called-with': 'off', 146 | 'jest/prefer-spy-on': 'off', 147 | 'jest/no-if': 'off', 148 | 'jest/no-disabled-tests': 'warn', 149 | 'jest/no-commented-out-tests': 'warn', 150 | 'jest/no-alias-methods': 'off', 151 | 'jest/max-expects': 'off', 152 | 'jest/prefer-mock-promise-shorthand': 'off', 153 | 'jest/no-conditional-in-test': 'off', 154 | 'jest/no-conditional-expect': 'off', 155 | 'jest/prefer-each': 'off', 156 | 'jest/prefer-snapshot-hint': 'off' 157 | } 158 | } 159 | ], 160 | settings: { 161 | react: { 162 | version: 'detect' 163 | }, 164 | 'import/extensions': ['.ts', '.tsx', '.js', '.jsx'], 165 | // ? Switch parsers depending on which type of file we're looking at 166 | 'import/parsers': { 167 | '@typescript-eslint/parser': ['.ts', '.tsx', '.cts', '.mts'], 168 | '@babel/eslint-parser': ['.js', '.jsx', '.cjs', '.mjs'] 169 | }, 170 | 'import/resolver': { 171 | node: {}, 172 | typescript: {} 173 | }, 174 | 'import/ignore': [ 175 | // ? Don't go complaining about anything that we don't own 176 | '.*/node_modules/.*', 177 | '.*/bin/.*' 178 | ] 179 | }, 180 | ignorePatterns: ['coverage', 'dist', 'fixtures', '__fixtures__', '__snapshots__'] 181 | }; 182 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of 9 | experience, nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language. 18 | - Being respectful of differing viewpoints and experiences. 19 | - Gracefully accepting constructive criticism. 20 | - Focusing on what is best for the community. 21 | - Showing empathy towards other community members. 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances. 27 | - Trolling, insulting/derogatory comments, and personal or political attacks. 28 | - Public or private harassment. 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission. 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting. 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or reject 41 | comments, commits, code, wiki edits, issues, and other contributions that are 42 | not aligned to this Code of Conduct, or to ban temporarily or permanently any 43 | contributor for other behaviors that they deem inappropriate, threatening, 44 | offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [kent+coc@doddsfamily.us][1]. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an 62 | incident. Further details of specific enforcement policies may be posted 63 | separately. 64 | 65 | Project maintainers who do not follow or enforce the Code of Conduct in good 66 | faith may face temporary or permanent repercussions as determined by other 67 | members of the project's leadership. 68 | 69 | ## Attribution 70 | 71 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 72 | version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 73 | 74 | [homepage]: http://contributor-covenant.org 75 | [version]: http://contributor-covenant.org/version/1/4 76 | [1]: mailto:kent+coc@doddsfamily.us 77 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | - `babel-plugin-tester` version: 15 | - `node` version: 16 | - `npm` (or `yarn`) version: 17 | 18 | Relevant code or config 19 | 20 | ```javascript 21 | 22 | ``` 23 | 24 | What you did: 25 | 26 | What happened: 27 | 28 | 29 | 30 | Reproduction repository: 31 | 32 | 36 | 37 | Problem description: 38 | 39 | Suggested solution: 40 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | **What**: 19 | 20 | 21 | 22 | **Why**: 23 | 24 | 25 | 26 | **How**: 27 | 28 | 29 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: daily 7 | commit-message: 8 | prefix: 'chore' 9 | prefix-development: 'chore' 10 | include: 'scope' 11 | 12 | - package-ecosystem: npm 13 | directory: / 14 | schedule: 15 | interval: daily 16 | commit-message: 17 | prefix: 'build' 18 | prefix-development: 'chore' 19 | include: 'scope' 20 | -------------------------------------------------------------------------------- /.github/workflows/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/.github/workflows/.gitkeep -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.ignore 2 | *.ignore.* 3 | ignore.* 4 | *.tsbuildinfo 5 | dist 6 | build 7 | .vscode 8 | !.vscode/launch.json 9 | .vercel 10 | .env 11 | .npmrc 12 | external-scripts/bin 13 | next-env.d.ts 14 | node_modules 15 | coverage 16 | .DS_Store 17 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname $0)/_/husky.sh" 3 | 4 | npx commitlint -e 5 | if [ -z $GAC_VERIFY_SIMPLE ]; then npm run test; fi 6 | echo 7 | node spellcheck-commit.js 8 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname $0)/_/husky.sh" 3 | 4 | if [ -z $GAC_VERIFY_SIMPLE ]; then npm run lint; fi 5 | NODE_ENV=format npx lint-staged --concurrent false 6 | -------------------------------------------------------------------------------- /.ncurc.js: -------------------------------------------------------------------------------- 1 | // * https://www.npmjs.com/package/npm-check-updates#configuration-files 2 | 3 | module.exports = { 4 | reject: [ 5 | // ? Pin the CJS version of strip-indent 6 | 'strip-indent', 7 | // ? Pin the CJS version of execa 8 | 'execa' 9 | ] 10 | }; 11 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Paths below are ignored by prettier as well as remark and doctoc when called 2 | # with npm run format) 3 | build 4 | external-scripts/bin 5 | node_modules 6 | dist 7 | coverage 8 | package-lock.json 9 | fixtures 10 | docs 11 | CHANGELOG.md 12 | test/integration/assets/main 13 | test/integration/assets/pure 14 | -------------------------------------------------------------------------------- /.remarkrc.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @typedef {{settings?: import('mdast-util-to-markdown').Options, plugins?: 3 | * import('unified-engine/lib/configuration').PluggableList | 4 | * import('unified-engine/lib/configuration').PluginIdList}} Config 5 | */ 6 | 7 | /** 8 | * Remark configuration loaded when `NODE_ENV == 'lint'`. The goal here is to 9 | * check for things that will not be corrected by prettier or remark during a 10 | * formatting pass (see below). 11 | * 12 | * @type {Config} 13 | */ 14 | const lintConfig = { 15 | plugins: [ 16 | 'ignore', 17 | 'frontmatter', 18 | 'gfm', 19 | 'lint', 20 | 'lint-definition-case', 21 | 'lint-fenced-code-flag', 22 | 'lint-fenced-code-flag-case', 23 | 'lint-file-extension', 24 | 'lint-first-heading-level', 25 | 'lint-heading-increment', 26 | 'lint-heading-whitespace', 27 | [ 28 | 'lint-list-item-style', 29 | // ? Add ":" as allowed punctuation 30 | { checkPunctuation: ['(\\.|\\?|;|:|,|!|\\p{Emoji}\uFE0F|\\p{Emoji_Presentation})'] } 31 | ], 32 | 'lint-no-duplicate-defined-urls', 33 | 'lint-no-duplicate-headings-in-section', 34 | 'lint-no-empty-sections', 35 | 'lint-no-empty-url', 36 | 'lint-heading-word-length', 37 | 'lint-no-heading-like-paragraph', 38 | 'lint-no-heading-punctuation', 39 | 'lint-no-inline-padding', 40 | 'lint-no-literal-urls', 41 | 'lint-no-multiple-toplevel-headings', 42 | 'lint-no-reference-like-url', 43 | 'lint-no-shell-dollars', 44 | 'lint-no-shortcut-reference-image', 45 | 'lint-no-shortcut-reference-link', 46 | 'lint-no-tabs', 47 | 'lint-no-undefined-references', 48 | 'lint-ordered-list-marker-value', 49 | ['lint-strikethrough-marker', '~~'], 50 | // ? Prettier will reformat list markers UNLESS they precede checkboxes 51 | ['lint-unordered-list-marker-style', '-'], 52 | 'validate-links' 53 | ] 54 | }; 55 | 56 | /** 57 | * Remark configuration loaded when `NODE_ENV == 'format'`. The goal here is to 58 | * correct things that will not be taken care of by prettier. 59 | * 60 | * @type {Config} 61 | */ 62 | const formatConfig = { 63 | plugins: [ 64 | 'ignore', 65 | 'frontmatter', 66 | 'gfm', 67 | 'tight-comments', 68 | ['capitalize-headings', { excludeHeadingLevel: { h1: true } }], 69 | 'remove-unused-definitions', 70 | 'remove-url-trailing-slash', 71 | 'renumber-references', 72 | 'sort-definitions' 73 | ] 74 | }; 75 | 76 | if (!['lint', 'format'].includes(process.env.NODE_ENV)) { 77 | throw new Error('remark expects NODE_ENV to be one of either: lint, format'); 78 | } 79 | 80 | /** 81 | * @type {Config} 82 | */ 83 | export default { 84 | settings: { 85 | bullet: '-', 86 | emphasis: '_', 87 | fences: true, 88 | listItemIndent: 'one', 89 | rule: '-', 90 | strong: '*', 91 | tightDefinitions: true, 92 | ...(process.env.NODE_ENV == 'lint' ? lintConfig.settings : formatConfig.settings) 93 | }, 94 | plugins: [ 95 | ...(process.env.NODE_ENV == 'lint' ? lintConfig.plugins : formatConfig.plugins) 96 | ] 97 | }; 98 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for being willing to contribute! 4 | 5 | **Working on your first Pull Request?** You can learn how from this _free_ 6 | series [How to Contribute to an Open Source Project on GitHub][egghead] 7 | 8 | ## Project Setup 9 | 10 | 1. Fork and clone the repo. 11 | 2. `$ npm ci` to install dependencies without affecting the `package-lock.json` 12 | file. 13 | 3. `$ npm run test` to validate you've got it working. 14 | 4. Create a branch for your PR. 15 | 16 | > Tip: Keep your `master` branch pointing at the original repository and make 17 | > pull requests from branches on your fork. To do this, run: 18 | > 19 | > ```shell 20 | > git remote add upstream https://github.com/babel-utils/babel-plugin-tester 21 | > git fetch upstream 22 | > git branch --set-upstream-to=upstream/master master 23 | > ``` 24 | > 25 | > This will add the original repository as a "remote" called "upstream," Then 26 | > fetch the git information from that remote, then set your local `master` 27 | > branch to use the upstream master branch whenever you run `git pull`. Then you 28 | > can make all of your pull request branches based on this `master` branch. 29 | > Whenever you want to update your version of `master`, do a regular `git pull`. 30 | 31 | ## Committing and Pushing Changes 32 | 33 | Please make sure to run the unit _and integration_ tests before you send your 34 | PR. You can do so by running `npm run test:all`, which will run all possible 35 | tests. On some Windows/WSL systems, the concurrent integration tests can be 36 | unstable, so set the environment variable `NO_CONCURRENT=true` to run the tests 37 | serially (which will be slow) if you encounter strange errors. 38 | 39 | Also, this project comes with Husky git hooks that run unit tests, linters, and 40 | formatters on the source before each commit. To prevent your contributions from 41 | being rejected, avoid circumventing these git hooks. 42 | 43 | ## Help Needed 44 | 45 | Please checkout the [the open issues][issues]. 46 | 47 | Also, please watch the repo and respond to questions, bug reports, and feature 48 | requests! Thanks! 49 | 50 | 51 | 52 | 53 | [egghead]: 54 | https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github 55 | [issues]: https://github.com/kentcdodds/generator-kcd-oss/issues 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2017 Kent C. Dodds 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /MAINTAINING.md: -------------------------------------------------------------------------------- 1 | # Maintaining 2 | 3 | This is documentation for maintainers of this project. 4 | 5 | ## Code of Conduct 6 | 7 | Please [review][1], understand, and be an example of it. Violations of the code 8 | of conduct are taken seriously, even (especially) for maintainers. 9 | 10 | ## Issues 11 | 12 | We want to support and build the community. We do that best by helping people 13 | learn to solve their own problems. We have an issue template and hopefully most 14 | folks follow it. If it's not clear what the issue is, invite them to create a 15 | minimal reproduction of what they're trying to accomplish or the bug they think 16 | they've found. 17 | 18 | Once it's determined that a code change is necessary, point people to 19 | [makeapullrequest.com][2] and invite them to make a pull request. If they're the 20 | one who needs the feature, they're the one who can build it. If they need some 21 | hand holding and you have time to lend a hand, please do so. It's an investment 22 | into another human being, and an investment into a potential maintainer. 23 | 24 | Remember that this is open source, so the code is not yours, it's ours. If 25 | someone needs a change in the codebase, you don't have to make it happen 26 | yourself. Commit as much time to the project as you want/need to. Nobody can ask 27 | any more of you than that. 28 | 29 | ## Pull Requests 30 | 31 | As a maintainer, you're fine to make your branches on the main repo or on your 32 | own fork. Either way is fine. 33 | 34 | When we receive a pull request, a GitHub Actions build is kicked off 35 | automatically (see [`.github/workflows`][3]). We avoid merging anything that 36 | fails the Actions workflow. 37 | 38 | Please review PRs and focus on the code rather than the individual. You never 39 | know when this is someone's first ever PR and we want their experience to be as 40 | positive as possible, so be uplifting and constructive. 41 | 42 | When you merge the pull request, 99% of the time you should use the [rebase and 43 | merge][4] feature. This keeps our git history clean. If commit messages need to 44 | be adjusted, maintainers should force push new commits with adjusted messages to 45 | the PR branch before merging it in. 46 | 47 | The [squash and merge][5] feature can also be used, but keep in mind that 48 | squashing commits will likely damage the [generated][6] [CHANGELOG.md][7], 49 | hinder [bisection][8], and result in [non-atomic commits][9], so use it 50 | sparingly. 51 | 52 | ## Release 53 | 54 | Our releases are automatic. They happen whenever code lands into `master`. A 55 | GitHub Actions build gets kicked off and, if it's successful, a tool called 56 | [`semantic-release`][10] is used to automatically publish a new release to npm 57 | and GitHub along with an updated changelog. It is only able to determine the 58 | version and whether a release is necessary by the git commit messages. With this 59 | in mind, **please brush up on [the commit message convention][commit] which 60 | drives our releases.** 61 | 62 | > One important note about this: please make sure that commit messages do NOT 63 | > contain the words "BREAKING CHANGE" in them unless we want to push a major 64 | > version. I've been burned by this more than once where someone will include 65 | > "BREAKING CHANGE: None" and it will end up releasing a new major version. Do 66 | > not do this! 67 | 68 | ### Manual Releases 69 | 70 | This project has an automated release set up. That means things are only 71 | released when there are useful changes in the code that justify a release. See 72 | [the release rules][11] for a list of commit types that trigger releases. 73 | 74 | However, sometimes things get messed up (e.g. CI workflow / GitHub Actions 75 | breaks) and we need to trigger a release ourselves. When this happens, 76 | semantic-release can be triggered locally by following these steps: 77 | 78 | > If one of these steps fails, you should address the failure before running the 79 | > next step. 80 | 81 | ```bash 82 | # These command must be run from the project root. It is recommended to clone a 83 | # fresh version of the repo to a temp directory and run these commands from 84 | # there. 85 | 86 | # 1. Install dependencies and add your auth tokens to the .env file. 87 | # ! DO NOT COMMIT THE .env FILE ! 88 | cp .env.default .env 89 | npm ci 90 | 91 | # 2. Reset the working directory to a clean state (deletes all ignored files). 92 | npm run clean 93 | 94 | # 3. Lint all files. 95 | npm run lint:all 96 | 97 | # 4. Build distributables. 98 | npm run build:dist 99 | 100 | # 5. Build auxiliary documentation. 101 | npm run build:docs 102 | 103 | # 6. Build any external executables (used in GitHub Actions workflows). 104 | npm run build:externals 105 | 106 | # 7. Format all files. 107 | npm run format 108 | 109 | # 8. Run all possible tests and generate coverage information. 110 | npm run test:all 111 | 112 | # 9. Upload coverage information to codecov (only if you have the proper token). 113 | CODECOV_TOKEN=$(npx --yes dotenv-cli -p CODECOV_TOKEN) codecov 114 | 115 | # 10. Trigger semantic-release locally and generate a new release. This requires 116 | # having tokens for NPM and GitHub with the appropriate permissions. 117 | # 118 | # Do a dry run first: 119 | NPM_TOKEN="$(npx --yes dotenv-cli -p NPM_TOKEN)" GH_TOKEN="$(npx --yes dotenv-cli -p GITHUB_TOKEN)" HUSKY=0 UPDATE_CHANGELOG=true GIT_AUTHOR_NAME="$(npx --yes dotenv-cli -p GIT_AUTHOR_NAME)" GIT_COMMITTER_NAME="$(npx --yes dotenv-cli -p GIT_COMMITTER_NAME)" GIT_AUTHOR_EMAIL="$(npx --yes dotenv-cli -p GIT_AUTHOR_EMAIL)" GIT_COMMITTER_EMAIL="$(npx --yes dotenv-cli -p GIT_COMMITTER_EMAIL)" node node_modules/.bin/semantic-release --no-ci --extends "$(pwd)/release.config.js" --dry-run 120 | # Then do the actual publish: 121 | NPM_TOKEN="$(npx --yes dotenv-cli -p NPM_TOKEN)" GH_TOKEN="$(npx --yes dotenv-cli -p GITHUB_TOKEN)" HUSKY=0 UPDATE_CHANGELOG=true GIT_AUTHOR_NAME="$(npx --yes dotenv-cli -p GIT_AUTHOR_NAME)" GIT_COMMITTER_NAME="$(npx --yes dotenv-cli -p GIT_COMMITTER_NAME)" GIT_AUTHOR_EMAIL="$(npx --yes dotenv-cli -p GIT_AUTHOR_EMAIL)" GIT_COMMITTER_EMAIL="$(npx --yes dotenv-cli -p GIT_COMMITTER_EMAIL)" node node_modules/.bin/semantic-release --no-ci --extends "$(pwd)/release.config.js" 122 | ``` 123 | 124 | 125 | 126 | ## Thanks! 127 | 128 | Thank you so much for helping to maintain this project! 129 | 130 | [commit]: 131 | https://github.com/conventional-changelog-archived-repos/conventional-changelog-angular/blob/ed32559941719a130bb0327f886d6a32a8cbc2ba/convention.md 132 | [1]: ./.github/CODE_OF_CONDUCT.md 133 | [2]: http://makeapullrequest.com 134 | [3]: ./.github/workflows 135 | [4]: 136 | https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#rebase-and-merge-your-commits 137 | [5]: 138 | https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits 139 | [6]: https://github.com/conventional-changelog/conventional-changelog 140 | [7]: https://www.conventionalcommits.org/en/v1.0.0 141 | [8]: 142 | https://www.metaltoad.com/blog/beginners-guide-git-bisect-process-elimination 143 | [9]: https://dev.to/paulinevos/atomic-commits-will-help-you-git-legit-35i7 144 | [10]: https://github.com/semantic-release/semantic-release 145 | [11]: 146 | https://github.com/babel-utils/babel-plugin-tester/blob/c13a2e0ff4ea9289d7a79a5da8949c125c636130/release.config.js#L27 147 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // ? https://nodejs.org/en/about/releases 4 | const NODE_LTS = 'maintained node versions'; 5 | 6 | module.exports = { 7 | comments: false, 8 | parserOpts: { strictMode: true }, 9 | plugins: ['@babel/plugin-proposal-export-default-from'], 10 | // ? Sub-keys under the "env" config key will augment the above 11 | // ? configuration depending on the value of NODE_ENV and friends. Default 12 | // ? is: development 13 | env: { 14 | // * Used by Jest and `npm test` 15 | test: { 16 | comments: true, 17 | sourceMaps: 'both', 18 | presets: [ 19 | ['@babel/preset-env', { targets: { node: true } }], 20 | ['@babel/preset-typescript', { allowDeclareFields: true }] 21 | ], 22 | plugins: [ 23 | // ? Only active when testing, the plugin solves the following problem: 24 | // ? https://stackoverflow.com/q/40771520/1367414 25 | 'explicit-exports-references' 26 | ] 27 | }, 28 | // * Used by `npm run build` for compiling CJS to code output in ./dist 29 | 'production-cjs': { 30 | presets: [ 31 | [ 32 | '@babel/preset-env', 33 | { 34 | // ? https://babeljs.io/docs/en/babel-preset-env#modules 35 | modules: 'cjs', 36 | targets: NODE_LTS, 37 | useBuiltIns: 'usage', 38 | corejs: '3.27', 39 | shippedProposals: true 40 | } 41 | ], 42 | ['@babel/preset-typescript', { allowDeclareFields: true }] 43 | ] 44 | } 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | extends: ['@commitlint/config-conventional'], 5 | rules: { 6 | 'body-leading-blank': [2, 'always'], 7 | 'footer-leading-blank': [2, 'always'], 8 | 'type-enum': [ 9 | 2, 10 | 'always', 11 | [ 12 | 'feat', 13 | 'feature', 14 | 'fix', 15 | 'perf', 16 | 'revert', 17 | 'build', 18 | 'docs', 19 | 'style', 20 | 'refactor', 21 | 'test', 22 | 'ci', 23 | 'cd', 24 | 'chore' 25 | ] 26 | ] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /conventional.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = require('@xunnamius/conventional-changelog-projector')({ 3 | // * Your customizations here 4 | }); 5 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @type {import('jest').Config} 5 | */ 6 | module.exports = { 7 | restoreMocks: true, 8 | resetMocks: true, 9 | testEnvironment: 'node', 10 | testRunner: 'jest-circus/runner', 11 | // ? 24h if debugging so MMS and other tools don't choke, otherwise 1m 12 | testTimeout: 13 | 1000 * 14 | 60 * 15 | (process.env.VSCODE_INSPECTOR_OPTIONS 16 | ? 60 * 24 17 | : process.platform == 'win32' 18 | ? 5 19 | : 1), 20 | // ? Minimum of 2 concurrent tests executed at once; maximum of cpu cores - 1 21 | maxConcurrency: Math.max(require('node:os').cpus().length - 1, 2), 22 | verbose: false, 23 | testPathIgnorePatterns: ['/node_modules/', '/dist/'], 24 | setupFilesAfterEnv: ['./test/setup.ts'], 25 | collectCoverageFrom: ['src/**/*.ts?(x)'], 26 | // ? Make sure jest-haste-map doesn't try to parse and cache fixtures 27 | modulePathIgnorePatterns: ['/test/fixtures'] 28 | }; 29 | -------------------------------------------------------------------------------- /lint-staged.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * These scripts are the constituent parts of the `npm run format` command. 5 | */ 6 | module.exports = { 7 | '*.md': [ 8 | 'npx remark --output --ignore-path=.prettierignore --silently-ignore', 9 | 'npx doctoc --no-title --maxlevel=3 --update-only' 10 | ], 11 | 'package.json': 'sort-package-json', 12 | '*': 'prettier --write --ignore-unknown' 13 | }; 14 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/logo.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-plugin-tester", 3 | "version": "11.0.4", 4 | "description": "Utilities for testing babel plugins", 5 | "keywords": [ 6 | "babel", 7 | "plugin", 8 | "tester" 9 | ], 10 | "homepage": "https://github.com/babel-utils/babel-plugin-tester#readme", 11 | "bugs": { 12 | "url": "https://github.com/babel-utils/babel-plugin-tester/issues" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/babel-utils/babel-plugin-tester" 17 | }, 18 | "license": "MIT", 19 | "author": "Kent C. Dodds (https://kentcdodds.com)", 20 | "sideEffects": false, 21 | "type": "commonjs", 22 | "exports": { 23 | ".": { 24 | "types": "./dist/index.d.ts", 25 | "default": "./dist/index.js" 26 | }, 27 | "./pure": { 28 | "types": "./dist/plugin-tester.d.ts", 29 | "default": "./dist/plugin-tester.js" 30 | }, 31 | "./package": "./package.json", 32 | "./package.json": "./package.json" 33 | }, 34 | "typesVersions": { 35 | "*": { 36 | "pure": [ 37 | "./dist/plugin-tester.d.ts" 38 | ], 39 | "*": [ 40 | "./dist/index.d.ts" 41 | ] 42 | } 43 | }, 44 | "files": [ 45 | "/dist", 46 | "/LICENSE", 47 | "/package.json", 48 | "/README.md" 49 | ], 50 | "scripts": { 51 | "build": "npm run build:dist --", 52 | "build:changelog": "conventional-changelog --outfile CHANGELOG.md --config ./conventional.config.js --release-count 0 --skip-unstable && (if [ \"$CHANGELOG_SKIP_TITLE\" != 'true' ]; then { node -e 'console.log(require(\"./conventional.config.js\").changelogTitle)'; cat CHANGELOG.md; } > CHANGELOG.md.ignore && mv CHANGELOG.md.ignore CHANGELOG.md; fi) && NODE_ENV=format remark --output --frail CHANGELOG.md && prettier --write CHANGELOG.md", 53 | "build:dist": "NODE_ENV=production tsc --project tsconfig.types.json --incremental false && tsconfig-replace-paths --project tsconfig.types.json && NODE_ENV=production-cjs babel src --extensions .ts --out-dir dist", 54 | "clean": "git ls-files --exclude-standard --ignored --others --directory | grep -vE '^((\\.(env|vscode|husky))|next-env\\.d\\.ts|node_modules)($|\\/)' | xargs -p rm -rf", 55 | "format": "MD_FILES=$(node -e 'console.log(require(`glob-gitignore`).sync(`**/*.md`, { ignore: require(`fs`).readFileSync(`.prettierignore`, `utf8`).split(`\n`).filter(Boolean), dot: true }).join(`\n`))') && (echo $MD_FILES | xargs remark --no-config --no-stdout --quiet --frail --use gfm --use lint-no-undefined-references || (echo -n '\u001b' && echo '[37;41;1m FAIL \u001b[0m cannot continue with undefined references present' && false)) && sort-package-json './package.json' './packages/*/package.json' && echo $MD_FILES | NODE_ENV=format xargs remark --output --frail && echo $MD_FILES | xargs doctoc --no-title --maxlevel 3 --update-only && prettier --write .", 56 | "lint": "stdbuf -i0 -o0 -e0 tsc --project tsconfig.lint.json; X=$?; stdbuf -i0 -o0 -e0 eslint --parser-options=project:tsconfig.lint.json --no-error-on-unmatched-pattern packages src; Y=$?; MD_FILES=$(node -e 'console.log(require(`glob-gitignore`).sync(`**/*.md`, { ignore: require(`fs`).readFileSync(`.prettierignore`, `utf8`).split(`\n`).filter(Boolean), dot: true }).join(`\n`))') && echo $MD_FILES | NODE_ENV=lint xargs remark --quiet --frail --no-stdout; Z=$?; [ $X -eq 0 ] && [ $Y -eq 0 ] && [ $Z -eq 0 ]", 57 | "lint:all": "stdbuf -i0 -o0 -e0 tsc --project tsconfig.eslint.json; X=$?; stdbuf -i0 -o0 -e0 eslint --parser-options=project:tsconfig.eslint.json .; Y=$?; MD_FILES=$(node -e 'console.log(require(`glob-gitignore`).sync(`**/*.md`, { ignore: require(`fs`).readFileSync(`.prettierignore`, `utf8`).split(`\n`).filter(Boolean), dot: true }).join(`\n`))') && echo $MD_FILES | NODE_ENV=lint xargs remark --quiet --frail --no-stdout; Z=$?; [ $X -eq 0 ] && [ $Y -eq 0 ] && [ $Z -eq 0 ]", 58 | "list-tasks": "node -e 'console.log(Object.keys(require(\"./package.json\").scripts).join(\"\\n\"))' && (npm run -ws list-tasks --if-present 2>/dev/null || true)", 59 | "prepare": "node -e \"execa = require('execa'); if(process.env.CI === undefined && (process.env.NODE_ENV === undefined || process.env.NODE_ENV == 'development')) { execa.sync('npx', ['husky', 'install'], { stdout: 'inherit', stderr: 'inherit' }); } else { console.log('skipped installing husky git hooks'); }\"", 60 | "test": "npm run test:unit --", 61 | "test:all": "NODE_ENV=test jest --coverage", 62 | "test:integration": "NODE_ENV=test jest 'integration-.*\\.test\\.ts.*'", 63 | "test:unit": "NODE_ENV=test jest --testPathIgnorePatterns 'integration-.*\\.test\\.ts.*' dist", 64 | "test:update": "npm test:all -- --updateSnapshot" 65 | }, 66 | "dependencies": { 67 | "core-js": "^3.27.2", 68 | "debug": "^4.3.4", 69 | "lodash.mergewith": "^4.6.2", 70 | "prettier": "^2.8.3", 71 | "strip-indent": "^3.0.0" 72 | }, 73 | "devDependencies": { 74 | "@babel/cli": "^7.20.7", 75 | "@babel/core": "^7.20.12", 76 | "@babel/eslint-parser": "^7.19.1", 77 | "@babel/helper-plugin-utils": "^7.20.2", 78 | "@babel/plugin-proposal-export-default-from": "^7.18.10", 79 | "@babel/plugin-syntax-jsx": "^7.18.6", 80 | "@babel/preset-env": "^7.20.2", 81 | "@babel/preset-typescript": "^7.18.6", 82 | "@commitlint/cli": "^17.4.2", 83 | "@commitlint/config-conventional": "^17.4.2", 84 | "@semantic-release/changelog": "^6.0.2", 85 | "@semantic-release/exec": "^6.0.3", 86 | "@semantic-release/git": "^10.0.1", 87 | "@types/babel__helper-plugin-utils": "^7.10.0", 88 | "@types/jest": "^29.2.6", 89 | "@types/lodash.mergewith": "^4.6.7", 90 | "@types/node": "^18.11.18", 91 | "@typescript-eslint/eslint-plugin": "^5.49.0", 92 | "@typescript-eslint/parser": "^5.49.0", 93 | "@xunnamius/conventional-changelog-projector": "^1.2.1", 94 | "@xunnamius/jest-types": "^1.1.3", 95 | "@xunnamius/types": "^1.3.0", 96 | "all-contributors-cli": "^6.24.0", 97 | "babel-jest": "^29.4.0", 98 | "babel-loader": "^9.1.2", 99 | "babel-plugin-explicit-exports-references": "^1.0.2", 100 | "browserslist": "^4.21.4", 101 | "conventional-changelog-cli": "https://xunn.at/conventional-changelog-cli", 102 | "doctoc": "^2.2.1", 103 | "dotenv": "^16.0.3", 104 | "eslint": "^8.32.0", 105 | "eslint-import-resolver-typescript": "^3.5.3", 106 | "eslint-plugin-import": "^2.27.5", 107 | "eslint-plugin-jest": "^27.2.1", 108 | "eslint-plugin-unicorn": "^45.0.2", 109 | "execa": "^5.1.1", 110 | "glob-gitignore": "^1.0.14", 111 | "husky": "^8.0.3", 112 | "jest": "^29.4.0", 113 | "jest-circus": "^29.4.0", 114 | "jest-extended": "^3.2.3", 115 | "lint-staged": "^13.1.0", 116 | "remark-capitalize-headings": "^1.0.2", 117 | "remark-cli": "^11.0.0", 118 | "remark-comment-config": "^7.0.1", 119 | "remark-frontmatter": "^4.0.1", 120 | "remark-gfm": "^3.0.1", 121 | "remark-ignore": "^1.0.5", 122 | "remark-lint": "^9.1.1", 123 | "remark-lint-definition-case": "^3.1.1", 124 | "remark-lint-fenced-code-flag": "^3.1.1", 125 | "remark-lint-fenced-code-flag-case": "^1.0.3", 126 | "remark-lint-file-extension": "^2.1.1", 127 | "remark-lint-first-heading-level": "^3.1.1", 128 | "remark-lint-heading-increment": "^3.1.1", 129 | "remark-lint-heading-whitespace": "^1.0.0", 130 | "remark-lint-heading-word-length": "^1.0.2", 131 | "remark-lint-list-item-style": "^1.1.2", 132 | "remark-lint-no-duplicate-defined-urls": "^2.1.1", 133 | "remark-lint-no-duplicate-headings-in-section": "^3.1.1", 134 | "remark-lint-no-empty-sections": "^4.0.0", 135 | "remark-lint-no-empty-url": "https://xunn.at/remark-lint-no-empty-url", 136 | "remark-lint-no-heading-like-paragraph": "^3.1.1", 137 | "remark-lint-no-heading-punctuation": "^3.1.1", 138 | "remark-lint-no-inline-padding": "^4.1.1", 139 | "remark-lint-no-literal-urls": "^3.1.1", 140 | "remark-lint-no-multiple-toplevel-headings": "^3.1.1", 141 | "remark-lint-no-reference-like-url": "^3.1.1", 142 | "remark-lint-no-shell-dollars": "^3.1.1", 143 | "remark-lint-no-shortcut-reference-image": "^3.1.1", 144 | "remark-lint-no-shortcut-reference-link": "^3.1.1", 145 | "remark-lint-no-tabs": "^3.1.1", 146 | "remark-lint-no-undefined-references": "^4.2.0", 147 | "remark-lint-ordered-list-marker-value": "^3.1.1", 148 | "remark-lint-strikethrough-marker": "^2.1.1", 149 | "remark-lint-unordered-list-marker-style": "^3.1.1", 150 | "remark-reference-links": "^6.0.1", 151 | "remark-remove-unused-definitions": "^1.0.3", 152 | "remark-remove-url-trailing-slash": "^1.0.1", 153 | "remark-renumber-references": "^1.0.4", 154 | "remark-sort-definitions": "^1.0.4", 155 | "remark-tight-comments": "^1.0.5", 156 | "remark-validate-links": "^12.1.0", 157 | "semantic-release": "https://xunn.at/semantic-release-atam", 158 | "sort-package-json": "^2.2.0", 159 | "source-map-support": "^0.5.21", 160 | "spellchecker": "^3.7.1", 161 | "toss-expression": "^0.1.2", 162 | "tsconfig-replace-paths": "^0.0.11", 163 | "type-fest": "^3.5.3", 164 | "typescript": "^4.9.4", 165 | "unique-filename": "^3.0.0" 166 | }, 167 | "peerDependencies": { 168 | "@babel/core": ">=7.11.6" 169 | }, 170 | "engines": { 171 | "node": "^14.20.0 || ^16.16.0 || >=18.5.0" 172 | }, 173 | "publishConfig": { 174 | "access": "public" 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | endOfLine: 'lf', 5 | printWidth: 80, 6 | proseWrap: 'always', 7 | semi: true, 8 | singleQuote: true, 9 | tabWidth: 2, 10 | trailingComma: 'none', 11 | overrides: [ 12 | { 13 | files: '**/*.?(@(c|m))@(ts|js)?(x)', 14 | options: { 15 | parser: 'babel-ts', 16 | printWidth: 90 17 | } 18 | } 19 | ] 20 | }; 21 | -------------------------------------------------------------------------------- /release.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // TODO: replace this with @xunnamius/semantic-release-projector-config 4 | 5 | const updateChangelog = 6 | process.env.UPDATE_CHANGELOG === 'true' || 7 | // ? Legacy 8 | process.env.SHOULD_UPDATE_CHANGELOG === 'true'; 9 | 10 | const { changelogTitle, parserOpts, writerOpts } = require('./conventional.config'); 11 | 12 | module.exports = { 13 | branches: [ 14 | '+([0-9])?(.{+([0-9]),x}).x', 15 | 'master', 16 | { 17 | name: 'canary', 18 | channel: 'canary', 19 | prerelease: true 20 | } 21 | ], 22 | plugins: [ 23 | [ 24 | '@semantic-release/commit-analyzer', 25 | { 26 | parserOpts, 27 | releaseRules: [ 28 | // ? releaseRules are checked first; if none match, defaults are 29 | // ? checked next. 30 | 31 | // ! These two lines must always appear first and in order: 32 | { breaking: true, release: 'major' }, 33 | { revert: true, release: 'patch' }, 34 | 35 | // * Custom release rules, if any, may appear next: 36 | { type: 'build', release: 'patch' } 37 | ] 38 | } 39 | ], 40 | [ 41 | '@semantic-release/release-notes-generator', 42 | { 43 | parserOpts, 44 | writerOpts 45 | } 46 | ], 47 | ...(updateChangelog 48 | ? [ 49 | [ 50 | '@semantic-release/exec', 51 | { 52 | prepareCmd: 'CHANGELOG_SKIP_TITLE=true npm run build:changelog' 53 | } 54 | ], 55 | ['@semantic-release/changelog', { changelogTitle }], 56 | [ 57 | '@semantic-release/exec', 58 | { 59 | prepareCmd: 'NODE_ENV=format npx remark --output --frail CHANGELOG.md' 60 | } 61 | ], 62 | [ 63 | '@semantic-release/exec', 64 | { 65 | prepareCmd: 'npx prettier --write CHANGELOG.md' 66 | } 67 | ] 68 | ] 69 | : []), 70 | ['@semantic-release/npm'], 71 | [ 72 | '@semantic-release/git', 73 | { 74 | assets: [ 75 | 'package.json', 76 | 'package-lock.json', 77 | 'npm-shrinkwrap.json', 78 | 'CHANGELOG.md', 79 | 'docs' 80 | ], 81 | message: 'release: ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}' 82 | } 83 | ], 84 | ['@semantic-release/github'] 85 | ] 86 | }; 87 | -------------------------------------------------------------------------------- /spellcheck-commit.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable unicorn/no-abusive-eslint-disable */ 2 | /* eslint-disable */ 3 | 'use strict'; 4 | 5 | const spellcheck = require('spellchecker'); 6 | const pkg = require('./package.json'); 7 | const read = require('fs').promises.readFile; 8 | const execa = require('execa'); 9 | 10 | const debug = require('debug')( 11 | `${require(`${process.cwd()}/package.json`).name}:spellcheck-commit` 12 | ); 13 | 14 | const tryToRead = async (path) => { 15 | try { 16 | debug(`attempting to read ${path}`); 17 | const data = await read(path); 18 | debug(`successfully read ${path}`); 19 | return data; 20 | } catch (ignored) { 21 | debug(`failed to read ${path}`); 22 | return ''; 23 | } 24 | }; 25 | 26 | const asJson = (str) => { 27 | try { 28 | const json = JSON.parse(str.toString('utf-8')); 29 | debug('json parse successful!'); 30 | return [ 31 | ...(json?.['cSpell.words'] || []), 32 | ...(json?.['cSpell.userWords'] || []), 33 | ...(json?.['cSpell.ignoreWords'] || []) 34 | ]; 35 | } catch (ignored) { 36 | debug('json parse failed!'); 37 | return []; 38 | } 39 | }; 40 | 41 | const asText = (str) => str.toString('utf-8').split('\n'); 42 | const isPascalCase = (w) => /^([A-Z]{2,}.+|[A-Z][a-z]+[A-Z].*)$/.test(w); 43 | const isCamelCase = (w) => /^[a-z]+[A-Z]+.*$/.test(w); 44 | const isAllCaps = (w) => /^[^a-z]+$/.test(w); 45 | 46 | const splitOutWords = (phrase) => 47 | [...phrase.split(/[^a-zA-Z]+/g), phrase].filter(Boolean); 48 | 49 | const keys = (obj) => Object.keys(obj).map(splitOutWords); 50 | 51 | (async () => { 52 | const lastCommitMsg = (await read('./.git/COMMIT_EDITMSG')).toString('utf-8'); 53 | const homeDir = require('os').homedir(); 54 | 55 | debug(`lastCommitMsg: ${lastCommitMsg}`); 56 | debug(`homeDir: ${homeDir}`); 57 | 58 | const ignoreWords = Array.from( 59 | new Set( 60 | [ 61 | ...(await Promise.all([ 62 | tryToRead('./.spellcheckignore').then(asText), 63 | tryToRead(`${homeDir}/.config/_spellcheckignore`).then(asText), 64 | tryToRead('./.vscode/settings.json').then(asJson), 65 | tryToRead(`${homeDir}/.config/Code/User/settings.json`).then(asJson) 66 | ])), 67 | ...require('text-extensions'), 68 | // ? Popular contractions 69 | ...['ve', 're', 's', 'll', 't', 'd', 'o', 'ol'], 70 | ...keys(pkg.dependencies || {}), 71 | ...keys(pkg.devDependencies || {}), 72 | ...keys(pkg.scripts || {}), 73 | ...splitOutWords( 74 | (await execa('git', ['log', '--format="%B"', 'HEAD~1'])).stdout 75 | ).slice(0, -1) 76 | ] 77 | .flat() 78 | .filter(Boolean) 79 | .map((word) => splitOutWords(word.trim().toLowerCase())) 80 | .flat() 81 | ) 82 | ); 83 | 84 | const typos = Array.from( 85 | new Set( 86 | spellcheck 87 | .checkSpelling(lastCommitMsg) 88 | .map((typoLocation) => 89 | lastCommitMsg.slice(typoLocation.start, typoLocation.end).trim().split("'") 90 | ) 91 | .flat() 92 | .filter((w) => !isAllCaps(w) && !isCamelCase(w) && !isPascalCase(w)) 93 | .map((w) => w.toLowerCase()) 94 | .filter((typo) => !ignoreWords.includes(typo)) 95 | ) 96 | ); 97 | 98 | debug('typos: %O', typos); 99 | 100 | if (typos.length) { 101 | console.warn('WARNING: there may be misspelled words in your commit message!'); 102 | console.warn('Commit messages can be fixed before push with `git commit -S --amend`'); 103 | console.warn('---'); 104 | 105 | for (const typo of typos.slice(0, 5)) { 106 | const corrections = spellcheck.getCorrectionsForMisspelling(typo); 107 | const suggestion = corrections.length 108 | ? ` (did you mean ${corrections.slice(0, 5).join(', ')}?)` 109 | : ''; 110 | 111 | console.warn(`${typo}${suggestion}`); 112 | } 113 | 114 | typos.length > 5 && console.warn(`${typos.length - 5} more...`); 115 | typos.length && console.warn('---'); 116 | } 117 | })(); 118 | -------------------------------------------------------------------------------- /src/errors.ts: -------------------------------------------------------------------------------- 1 | import { types } from 'node:util'; 2 | 3 | import { $type } from './symbols'; 4 | 5 | import type { 6 | MaybePluginTesterTestConfig, 7 | PluginTesterTestConfig, 8 | PluginTesterTestFixtureConfig, 9 | Range 10 | } from './index'; 11 | 12 | const { isNativeError } = types; 13 | 14 | /** 15 | * A collection of possible errors and warnings. 16 | */ 17 | export const ErrorMessage = { 18 | TestEnvironmentUndefinedDescribe: () => 19 | 'incompatible testing environment: testing environment must define `describe` in its global scope', 20 | TestEnvironmentUndefinedIt: () => 21 | 'incompatible testing environment: testing environment must define `it` in its global scope', 22 | TestEnvironmentNoSnapshotSupport: () => 23 | 'testing environment does not support `expect(...).toMatchSnapshot` method', 24 | TestEnvironmentNoSkipSupport: () => 25 | 'testing environment does not support `it.skip(...)` method', 26 | TestEnvironmentNoOnlySupport: () => 27 | 'testing environment does not support `it.only(...)` method', 28 | BadConfigPluginAndPreset: () => 29 | 'failed to validate configuration: cannot test a plugin and a preset simultaneously. Specify one set of options or the other', 30 | BadConfigNoPluginOrPreset: () => 31 | 'failed to validate configuration: must provide either `plugin` or `preset` option', 32 | BadConfigInvalidTitleNumbering: () => 33 | 'failed to validate configuration: invalid `titleNumbering` option', 34 | BadConfigFixturesNotString: () => 35 | 'failed to validate configuration: `fixtures`, if defined, must be a string', 36 | BadConfigInvalidTestsType: () => 37 | 'failed to validate configuration: `tests`, if defined, must be an array or an object', 38 | BadConfigInvalidTestsArrayItemType: (index: number) => 39 | `failed to validate configuration: \`tests\` array item at index ${index} must be a string, TestObject, or nullish`, 40 | BadConfigInvalidTestsObjectProperty: (title: string) => 41 | `failed to validate configuration: \`tests\` object property "${title}" must have a value of type string, TestObject, or nullish`, 42 | BadConfigInvalidEndOfLine: (endOfLine: unknown) => 43 | `failed to validate configuration: invalid \`endOfLine\` option "${endOfLine}"`, 44 | BadEnvironmentVariableRange: (name: string, rangeStr: string, range?: Range) => 45 | `invalid environment variable "${name}": invalid range ${rangeStr}` + 46 | (range ? `: ${range.start} is greater than ${range.end}` : ''), 47 | SetupFunctionFailed: (error: unknown) => 48 | `setup function failed: ${isNativeError(error) ? error.message : error}`, 49 | TeardownFunctionFailed: (functionError: unknown, frameworkError?: unknown) => { 50 | const frameworkErrorMessage = frameworkError 51 | ? `\n\nAdditionally, the testing framework reported the following error: ${ 52 | isNativeError(frameworkError) ? frameworkError.message : frameworkError 53 | }` 54 | : ''; 55 | return `teardown function failed: ${ 56 | isNativeError(functionError) ? functionError.message : functionError 57 | }${frameworkErrorMessage}`; 58 | }, 59 | ExpectedBabelToThrow: () => 'expected babel to throw an error, but it did not', 60 | // eslint-disable-next-line @typescript-eslint/ban-types 61 | ExpectedErrorToBeInstanceOf: (expectedError: Function | { name?: string }) => 62 | `expected error to be an instance of ${expectedError.name || 'the expected error'}`, 63 | ExpectedThrowsFunctionToReturnTrue: () => 64 | 'expected `throws`/`error` function to return true', 65 | ExpectedErrorToIncludeString: (resultString: string, expectedError: string) => 66 | `expected "${resultString}" to include "${expectedError}"`, 67 | ExpectedErrorToMatchRegExp: (resultString: string, expectedError: RegExp) => 68 | `expected "${resultString}" to match ${expectedError}`, 69 | BabelOutputTypeIsNotString: (rawBabelOutput: unknown) => 70 | `unexpected babel output type "${typeof rawBabelOutput}" (expected string)`, 71 | BabelOutputUnexpectedlyEmpty: () => 72 | 'attempted to execute babel output but it was empty. An empty string cannot be evaluated', 73 | AttemptedToSnapshotUnmodifiedBabelOutput: () => 74 | 'code was unmodified but attempted to take a snapshot. If the code should not be modified, set `snapshot: false`', 75 | ExpectedOutputToEqualActual: ( 76 | testConfig: 77 | | { 78 | [$type]: Exclude; 79 | } 80 | | Pick 81 | ) => { 82 | return `actual output does not match ${ 83 | testConfig[$type] == 'fixture-object' 84 | ? testConfig.fixtureOutputBasename 85 | : 'expected output' 86 | }`; 87 | }, 88 | ExpectedOutputNotToChange: () => 'expected output not to change, but it did', 89 | ValidationFailed: (title: string, message: string) => 90 | `failed to validate configuration for test "${title}": ${message}`, 91 | InvalidHasCodeAndCodeFixture: () => 92 | '`code` cannot be provided with `codeFixture` or `fixture`', 93 | InvalidHasOutputAndOutputFixture: () => 94 | '`output` cannot be provided with `outputFixture`', 95 | InvalidHasExecAndExecFixture: () => '`exec` cannot be provided with `execFixture`', 96 | InvalidHasSnapshotAndOutput: () => 97 | 'neither `output` nor `outputFixture` can be provided with `snapshot` enabled', 98 | InvalidHasSnapshotAndExec: () => 99 | 'neither `exec` nor `execFixture` can be provided with `snapshot` enabled', 100 | InvalidHasSnapshotAndThrows: () => 101 | 'neither `throws` nor `error` can be provided with `snapshot` enabled', 102 | InvalidHasSkipAndOnly: () => 'cannot enable both `skip` and `only` in the same test', 103 | InvalidHasThrowsAndOutput: ( 104 | testConfig: Pick 105 | ) => { 106 | return testConfig[$type] == 'test-object' 107 | ? 'neither `output` nor `outputFixture` can be provided with `throws` or `error`' 108 | : 'a fixture cannot be provided with `throws` or `error` and also contain an output file'; 109 | }, 110 | InvalidHasThrowsAndExec: ( 111 | testConfig: Pick 112 | ) => { 113 | return testConfig[$type] == 'test-object' 114 | ? 'neither `exec` nor `execFixture` can be provided with `throws` or `error`' 115 | : 'a fixture cannot be provided with `throws` or `error` and also contain an exec file'; 116 | }, 117 | InvalidMissingCodeOrExec: ( 118 | testConfig: Pick 119 | ) => { 120 | /* istanbul ignore next */ 121 | return testConfig[$type] == 'test-object' 122 | ? 'a string or object with a `code`, `codeFixture`, `fixture`, `exec`, or `execFixture` must be provided' 123 | : 'a fixture must contain either a code file or an exec file'; 124 | }, 125 | InvalidHasExecAndCodeOrOutput: ( 126 | testConfig: Pick 127 | ) => { 128 | return testConfig[$type] == 'test-object' 129 | ? 'neither `code`, `codeFixture`, `fixture`, `output`, nor `outputFixture` can be provided with `exec` or `execFixture`' 130 | : 'a fixture cannot contain both an exec file and a code or output file'; 131 | }, 132 | InvalidHasBabelrcButNoFilename: () => 133 | '`babelOptions.babelrc` is enabled but `babelOptions.filename` was not provided', 134 | InvalidThrowsType: () => 135 | '`throws`/`error` must be a function, string, boolean, RegExp, or Error subtype', 136 | GenericErrorWithPath: (error: unknown, path: string | undefined) => { 137 | const message = `${isNativeError(error) ? error.message : error}`; 138 | // ? Some realms/runtimes don't include the failing path, so we make sure 139 | return !path || message.includes(path) ? message : `${path}: ${message}`; 140 | }, 141 | PathIsNotAbsolute: /* istanbul ignore next */ (path: string) => 142 | `"${path}" is not an absolute path`, 143 | UnableToDeriveAbsolutePath: ( 144 | filepath: unknown, 145 | filepathName: string, 146 | basename: unknown, 147 | basenameName: string 148 | ) => 149 | `unable to derive an absolute path from the provided ${filepathName} and ${basenameName}:\n\n${filepathName}: ${filepath}\n${basenameName}: ${basename}` 150 | }; 151 | -------------------------------------------------------------------------------- /src/formatters/prettier.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import debugFactory from 'debug'; 3 | 4 | import { 5 | resolveConfig as resolvePrettierConfig, 6 | format as formatWithPrettier, 7 | type Options as PrettierOptions 8 | } from 'prettier'; 9 | 10 | import type { ResultFormatter } from '..'; 11 | 12 | const debug = debugFactory('babel-plugin-tester:formatter'); 13 | 14 | type MaybePrettierOptions = PrettierOptions | null; 15 | const configDirectoryCache: Record = Object.create(null); 16 | 17 | const getCachedConfig = (filepath: string) => { 18 | if (!(filepath in configDirectoryCache)) { 19 | configDirectoryCache[filepath] = resolvePrettierConfig.sync(filepath); 20 | debug( 21 | `caching prettier configuration resolved from ${filepath}: %O`, 22 | configDirectoryCache[filepath] 23 | ); 24 | } else { 25 | debug(`using cached prettier configuration resolved from ${filepath}`); 26 | } 27 | 28 | return configDirectoryCache[filepath]; 29 | }; 30 | 31 | export type { PrettierOptions }; 32 | 33 | /** 34 | * A prettier-based formatter used to normalize babel output. 35 | * 36 | * If no `filepath` is given, it will be set to `${cwd}/dummy.js` by 37 | * default. This is useful to leverage prettier's extension-based parser 38 | * inference (which usually ends up triggering babel). 39 | * 40 | * @see https://prettier.io/docs/en/options.html#file-path 41 | */ 42 | export const prettierFormatter: ResultFormatter<{ 43 | /** 44 | * Options passed directly to prettier, allowing you to override the defaults. 45 | */ 46 | prettierOptions: MaybePrettierOptions; 47 | /** 48 | * If this deprecated parameter is given as an argument, treat it as the value 49 | * of `prettierOptions`. Otherwise, it should not be used. 50 | * 51 | * @deprecated Use `prettierOptions` instead. 52 | */ 53 | config: MaybePrettierOptions; 54 | }> = ( 55 | code, 56 | { 57 | cwd = process.cwd(), 58 | filename, 59 | filepath = filename || path.join(cwd, 'dummy.js'), 60 | config, 61 | prettierOptions = config || getCachedConfig(filepath) 62 | } = {} 63 | ) => { 64 | const finalPrettierOptions = { 65 | filepath, 66 | ...prettierOptions 67 | }; 68 | 69 | debug('cwd: %O', cwd); 70 | debug('filepath: %O', filepath); 71 | debug('prettier options: %O', finalPrettierOptions); 72 | debug('original code: %O', code); 73 | 74 | const formattedCode = formatWithPrettier(code, finalPrettierOptions); 75 | debug('formatted code: %O', code); 76 | 77 | return formattedCode; 78 | }; 79 | 80 | export default prettierFormatter; 81 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import debugFactory from 'debug'; 2 | 3 | import { prettierFormatter } from './formatters/prettier'; 4 | import { unstringSnapshotSerializer } from './serializers/unstring-snapshot'; 5 | 6 | import { 7 | pluginTester, 8 | runPluginUnderTestHere, 9 | runPresetUnderTestHere 10 | } from './plugin-tester'; 11 | 12 | import type { PluginTesterOptions } from './types'; 13 | 14 | const debug = debugFactory('babel-plugin-tester:index'); 15 | 16 | if ('expect' in globalThis && typeof expect?.addSnapshotSerializer == 'function') { 17 | debug( 18 | 'added unstring snapshot serializer globally; all snapshots after this point will be affected' 19 | ); 20 | expect.addSnapshotSerializer(unstringSnapshotSerializer); 21 | } else { 22 | /* istanbul ignore next */ 23 | debug( 24 | 'unable to add unstring snapshot serializer: global expect object is missing or unsupported' 25 | ); 26 | } 27 | 28 | /** 29 | * An abstraction around babel to help you write tests for your babel plugin or 30 | * preset. 31 | */ 32 | function defaultPluginTester(options?: PluginTesterOptions) { 33 | return pluginTester({ formatResult: prettierFormatter, ...options }); 34 | } 35 | 36 | export { 37 | defaultPluginTester as default, 38 | defaultPluginTester as pluginTester, 39 | prettierFormatter, 40 | unstringSnapshotSerializer, 41 | runPluginUnderTestHere, 42 | runPresetUnderTestHere 43 | }; 44 | 45 | export * from './types'; 46 | 47 | // ? What follows is some not-so-pretty interop for backwards compatible require 48 | // ? calls using the old CJS default import syntax. In the next major version of 49 | // ? babel-plugin-tester, all default exports will be removed entirely. 50 | defaultPluginTester.default = defaultPluginTester; 51 | defaultPluginTester.pluginTester = defaultPluginTester; 52 | defaultPluginTester.prettierFormatter = prettierFormatter; 53 | defaultPluginTester.unstringSnapshotSerializer = unstringSnapshotSerializer; 54 | defaultPluginTester.runPluginUnderTestHere = runPluginUnderTestHere; 55 | defaultPluginTester.runPresetUnderTestHere = runPresetUnderTestHere; 56 | module.exports = defaultPluginTester; 57 | -------------------------------------------------------------------------------- /src/serializers/unstring-snapshot.ts: -------------------------------------------------------------------------------- 1 | import debugFactory from 'debug'; 2 | import type { SnapshotSerializer } from '..'; 3 | 4 | const debug = debugFactory('babel-plugin-tester:serializer'); 5 | 6 | /** 7 | * If you're using jest and snapshots, then the snapshot output could have a 8 | * bunch of bothersome `\"` to escape quotes because when Jest serializes a 9 | * string, it will wrap everything in double quotes. 10 | * 11 | * This snapshot serializer removes these quotes. 12 | */ 13 | export const unstringSnapshotSerializer: SnapshotSerializer = { 14 | test: (value: unknown) => { 15 | const isTriggered = typeof value === 'string'; 16 | 17 | debug(`unstring serializer is triggered: ${isTriggered ? 'yes' : 'no'}`); 18 | return isTriggered; 19 | }, 20 | print: (value: unknown) => { 21 | debug('original value: %O', value); 22 | 23 | const serializedValue = String(value); 24 | debug('serialized value: %O', serializedValue); 25 | 26 | return serializedValue; 27 | } 28 | }; 29 | 30 | export default unstringSnapshotSerializer; 31 | -------------------------------------------------------------------------------- /src/symbols.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * An internal symbol representing the type of a normalized test configuration. 3 | * 4 | * @internal 5 | */ 6 | export const $type = Symbol.for('@xunnamius/test-object-type'); 7 | -------------------------------------------------------------------------------- /test/__mocks__/@babel/core.js: -------------------------------------------------------------------------------- 1 | import * as babel from '@babel/core'; 2 | 3 | // ? Doing things this way so we can spyOn babel APIs and without this we were 4 | // ? getting errors: TypeError: Cannot set property transform of # which 5 | // ? has only a getter 6 | module.exports = { ...babel }; 7 | -------------------------------------------------------------------------------- /test/__snapshots__/unit-index.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`captains-log 2. captains-log: 2. captains-log 1`] = ` 4 | 5 | var output = paragraph + "one"+ 6 | 7 | 'paragraph' + \`\\two\` 8 | 9 | ↓ ↓ ↓ ↓ ↓ ↓ 10 | 11 | var output = paragraph + 'one' + 'paragraph' + \`\\two\`; 12 | 13 | `; 14 | -------------------------------------------------------------------------------- /test/__snapshots__/unit-plugin-tester.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`tests targeting the TestObject interface takes a snapshot if \`snapshot\` is enabled: 1. captains-log (explicit) 1`] = ` 4 | 5 | var hi = 'hey'; 6 | 7 | ↓ ↓ ↓ ↓ ↓ ↓ 8 | 9 | var ih = 'hey'; 10 | 11 | `; 12 | 13 | exports[`tests targeting the TestObject interface takes a snapshot if \`snapshot\` is enabled: 2. black-box (preset) 1`] = ` 14 | 15 | var hi = 'hey'; 16 | 17 | ↓ ↓ ↓ ↓ ↓ ↓ 18 | 19 | var ih = 'hey'; 20 | 21 | `; 22 | -------------------------------------------------------------------------------- /test/examples/__snapshots__/example-1.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`unknown plugin 5. using jest snapshots: 5. using jest snapshots 1`] = ` 4 | 5 | 6 | function sayHi(person) { 7 | return 'Hello ' + person + '!' 8 | } 9 | 10 | 11 | ↓ ↓ ↓ ↓ ↓ ↓ 12 | 13 | function iHyas(nosrep) { 14 | return 'Hello ' + nosrep + '!'; 15 | } 16 | 17 | `; 18 | -------------------------------------------------------------------------------- /test/examples/__snapshots__/example-2.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`unknown plugin 1. unknown plugin: 1. unknown plugin 1`] = ` 4 | 5 | "hello"; 6 | 7 | ↓ ↓ ↓ ↓ ↓ ↓ 8 | 9 | 'hello'; 10 | 11 | `; 12 | 13 | exports[`unknown plugin 3. unknown plugin: 3. unknown plugin 1`] = ` 14 | 15 | 16 | function sayHi(person) { 17 | return 'Hello ' + person + '!' 18 | } 19 | console.log(sayHi('Jenny')) 20 | 21 | 22 | ↓ ↓ ↓ ↓ ↓ ↓ 23 | 24 | function iHyas(nosrep) { 25 | return 'Hello ' + nosrep + '!'; 26 | } 27 | elosnoc.gol(iHyas('Jenny')); 28 | 29 | `; 30 | -------------------------------------------------------------------------------- /test/examples/__snapshots__/example-4.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`describe block title 5. identifier reverse: 5. identifier reverse 1`] = ` 4 | 5 | 6 | function sayHi(person) { 7 | return 'Hello ' + person + '!'; 8 | } 9 | 10 | 11 | ↓ ↓ ↓ ↓ ↓ ↓ 12 | 13 | function iHyas(nosrep) { 14 | return 'Hello ' + nosrep + '!'; 15 | } 16 | 17 | `; 18 | -------------------------------------------------------------------------------- /test/examples/example-1.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint jest/require-hook: ["error", { "allowedFunctionCalls": ["pluginTester"] }] */ 2 | 3 | import path from 'node:path'; 4 | 5 | import { pluginTester } from '../../src/index'; 6 | import { identifierReversePlugin } from '../helpers/plugins'; 7 | 8 | // * babel-plugin-tester example from 9 | // * https://github.com/jamiebuilds/babel-handbook/blob/master/translations/nl/plugin-handbook.md#babel-plugin-tester 10 | pluginTester({ 11 | filepath: path.join(__dirname, '../file.js'), 12 | plugin: identifierReversePlugin, 13 | fixtures: 'fixtures/simple-reversed', 14 | tests: { 15 | 'does not change code with no identifiers': "'hello';", 16 | 'changes this code': { 17 | code: "var hello = 'hi';", 18 | output: "var olleh = 'hi';" 19 | }, 20 | 'using fixtures files': { 21 | fixture: 'fixtures/codeFixture.js', 22 | outputFixture: 'fixtures/outputFixture.js' 23 | }, 24 | 'using jest snapshots': { 25 | code: ` 26 | function sayHi(person) { 27 | return 'Hello ' + person + '!' 28 | } 29 | `, 30 | snapshot: true 31 | } 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /test/examples/example-2.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint jest/require-hook: ["error", { "allowedFunctionCalls": ["pluginTester"] }] */ 2 | 3 | import { pluginTester } from '../../src/index'; 4 | import { identifierReversePlugin } from '../helpers/plugins'; 5 | 6 | // * Simple example from README.md 7 | pluginTester({ 8 | plugin: identifierReversePlugin, 9 | snapshot: true, 10 | tests: [ 11 | { 12 | code: '"hello";' 13 | // Snapshot should show that code has not changed. 14 | }, 15 | { 16 | snapshot: false, 17 | code: 'var hello = "hi";', 18 | output: "var olleh = 'hi';" 19 | }, 20 | ` 21 | function sayHi(person) { 22 | return 'Hello ' + person + '!' 23 | } 24 | console.log(sayHi('Jenny')) 25 | ` 26 | ] 27 | }); 28 | -------------------------------------------------------------------------------- /test/examples/example-3.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint jest/require-hook: ["error", { "allowedFunctionCalls": ["pluginTester"] }] */ 2 | 3 | import { pluginTester } from '../../src/index'; 4 | import { identifierReversePlugin } from '../helpers/plugins'; 5 | 6 | const customFormatFunction = (r: string) => r; 7 | 8 | // * Full example from README.md (variant 1) 9 | pluginTester({ 10 | // One (and ONLY ONE) of the two following lines MUST be included. 11 | plugin: identifierReversePlugin, 12 | //preset: coolNewBabelPreset, 13 | 14 | // Usually unnecessary if it is returned by the plugin. This will default to 15 | // 'unknown plugin' if a name cannot otherwise be inferred. 16 | pluginName: 'identifier reverse', 17 | // Unlike with pluginName, there is no presetName inference. This will default 18 | // to 'unknown preset' if a name is not provided. 19 | //presetName: 'cool-new-babel-preset', 20 | 21 | // Used to test specific plugin options. 22 | pluginOptions: { 23 | optionA: true 24 | }, 25 | //presetOptions: { 26 | // optionB: false, 27 | //} 28 | 29 | // Defaults to the plugin name. 30 | title: 'describe block title', 31 | 32 | // Only useful if you are using fixtures, codeFixture, outputFixture, or 33 | // execFixture options. Defaults to the absolute path of the file the 34 | // pluginTester function was invoked from, which in this case is equivalent 35 | // to the following line: 36 | filepath: __filename, 37 | 38 | // These are the defaults that will be lodash.mergeWith'd with the provided 39 | // babelOptions option. 40 | babelOptions: { 41 | parserOpts: {}, 42 | generatorOpts: {}, 43 | babelrc: false, 44 | configFile: false 45 | }, 46 | 47 | // Do not use snapshots across all tests, which is the default anyway. Note 48 | // that snapshots are only guaranteed to work with Jest 49 | snapshot: false, 50 | 51 | // Defaults to a function that formats with prettier 52 | formatResult: customFormatFunction, 53 | 54 | // You can provide tests as an object 55 | tests: { 56 | // The key is the title. The value is the code that is unchanged (because 57 | // snapshot == false across all tests). Test title will be: "1. does not 58 | // change code with no identifiers" 59 | 'does not change code with no identifiers': '"hello";', 60 | 61 | // Test title will be: "2. changes this code" 62 | 'changes this code': { 63 | // Input to the plugin 64 | code: 'var hello = "hi";', 65 | // Expected output 66 | output: 'var olleh = "hi";' 67 | } 68 | } 69 | }); 70 | -------------------------------------------------------------------------------- /test/examples/example-4.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint jest/require-hook: ["error", { "allowedFunctionCalls": ["pluginTester"] }] */ 2 | 3 | import path from 'node:path'; 4 | 5 | import { pluginTester } from '../../src/index'; 6 | import { identifierReversePlugin } from '../helpers/plugins'; 7 | 8 | const customFormatFunction = (r: string) => r; 9 | 10 | // * Full example from README.md (variant 2) 11 | pluginTester({ 12 | // One (and ONLY ONE) of the two following lines MUST be included. 13 | plugin: identifierReversePlugin, 14 | //preset: coolNewBabelPreset, 15 | 16 | // Usually unnecessary if it is returned by the plugin. This will default to 17 | // 'unknown plugin' if a name cannot otherwise be inferred. 18 | pluginName: 'identifier reverse', 19 | // Unlike with pluginName, there is no presetName inference. This will default 20 | // to 'unknown preset' if a name is not provided. 21 | //presetName: 'cool-new-babel-preset', 22 | 23 | // Used to test specific plugin options. 24 | pluginOptions: { 25 | optionA: true 26 | }, 27 | //presetOptions: { 28 | // optionB: false, 29 | //} 30 | 31 | // Defaults to the plugin name. 32 | title: 'describe block title', 33 | 34 | // Only useful if you are using fixtures, codeFixture, outputFixture, or 35 | // execFixture options. Defaults to the absolute path of the file the 36 | // pluginTester function was invoked from, which in this case is equivalent 37 | // to the following line: 38 | filepath: __filename, 39 | 40 | // These are the defaults that will be lodash.mergeWith'd with the provided 41 | // babelOptions option. 42 | babelOptions: { 43 | parserOpts: {}, 44 | generatorOpts: {}, 45 | babelrc: false, 46 | configFile: false 47 | }, 48 | 49 | // Do not use snapshots across all tests, which is the default anyway. Note 50 | // that snapshots are only guaranteed to work with Jest 51 | snapshot: false, 52 | 53 | // Defaults to a function that formats with prettier 54 | formatResult: customFormatFunction, 55 | 56 | // Alternatively, you can provide tests as an array 57 | tests: [ 58 | // Should be unchanged by the plugin (because snapshot == false across all 59 | // tests). Test title will be: "1. identifier reverse" 60 | '"hello";', 61 | { 62 | // Test title will be: "2. identifier reverse" 63 | code: 'var hello = "hi";', 64 | output: 'var olleh = "hi";' 65 | }, 66 | { 67 | // Test title will be: "3. unchanged code" 68 | title: 'unchanged code', 69 | // Because this is an absolute path, the filepath option above will not 70 | // be used to resolve this path 71 | codeFixture: path.join(__dirname, '..', 'fixtures', 'codeFixture-unchanging.js') 72 | // No output, outputFixture, or snapshot, so the assertion will be that 73 | // the plugin does not change this code 74 | }, 75 | { 76 | // Because these are not absolute paths, they will be joined with the 77 | // directory of the filepath option provided above 78 | codeFixture: path.join('..', 'fixtures', 'codeFixture.js'), 79 | // Because outputFixture is provided, the assertion will be that the 80 | // plugin will change the contents of "changed.js" to the contents of 81 | // "changed-output.js" 82 | outputFixture: path.join('..', 'fixtures', 'outputFixture.js') 83 | }, 84 | { 85 | // As a convenience, this will have the indentation striped and it will 86 | // be trimmed 87 | code: ` 88 | function sayHi(person) { 89 | return 'Hello ' + person + '!'; 90 | } 91 | `, 92 | // This will take a Jest snapshot, overwriting the default/global 93 | // settings (set above). The snapshot will contain both source code and 94 | // the transformed output, making the snapshot file easier to understand 95 | snapshot: true 96 | }, 97 | { 98 | code: 'var hello = "hi";', 99 | output: 'var olleh = "hi";', 100 | // This can be used to overwrite pluginOptions (set above) 101 | pluginOptions: { 102 | optionA: false 103 | } 104 | // This can be used to overwrite presetOptions (set above) 105 | //presetOptions: { 106 | // optionB: true 107 | //} 108 | }, 109 | { 110 | title: 'unchanged code', 111 | code: "'no change';", 112 | setup() { 113 | // Runs before this test 114 | return function teardown() { 115 | // Runs after this tests 116 | }; 117 | // Can also return a promise 118 | }, 119 | teardown() { 120 | // Runs after this test 121 | // Can return a promise 122 | } 123 | }, 124 | { 125 | // This source will be transformed just like the code property, except the 126 | // produced code will be evaluated in the same CJS context as the test 127 | // runner. This lets us make more advanced assertions on the output. 128 | exec: ` 129 | const hello = "hi"; 130 | // The plugin will reverse ALL identifiers, even globals like "expect"! 131 | tcepxe(hello)['toBe']("hi"); 132 | ` 133 | } 134 | ] 135 | }); 136 | -------------------------------------------------------------------------------- /test/fixtures/README.md: -------------------------------------------------------------------------------- 1 | # Dummy Fixtures 2 | 3 | These are all dummy [fixtures](/README.md#fixtures) used in 4 | babel-plugin-tester's unit tests. Each directory within `test/fixtures` is 5 | considered a distinct fixture whose path should be passed as the value of the 6 | [`fixtures`](/README.md#fixtures) option. Most of these fixtures have a 7 | structure similar to the following: 8 | 9 | ```text 10 | fixture-name-here 11 | └── fixture 12 |    └── ... (one or more fixture-specific files like `code.js` or `options.js`) 13 | ``` 14 | -------------------------------------------------------------------------------- /test/fixtures/babelrc-inverted/fixture/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["../../../helpers/plugin-identifier-reverse.js"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/babelrc-inverted/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); 2 | -------------------------------------------------------------------------------- /test/fixtures/babelrc-inverted/fixture/output.js: -------------------------------------------------------------------------------- 1 | elosnoc.gol('hello'); 2 | -------------------------------------------------------------------------------- /test/fixtures/babelrc-missing/fixture/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; -------------------------------------------------------------------------------- /test/fixtures/babelrc/fixture/cjs/.babelrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require.resolve('@babel/plugin-syntax-jsx')] 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/babelrc/fixture/cjs/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; -------------------------------------------------------------------------------- /test/fixtures/babelrc/fixture/default/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-syntax-jsx"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/babelrc/fixture/default/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; -------------------------------------------------------------------------------- /test/fixtures/babelrc/fixture/js/.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require.resolve('@babel/plugin-syntax-jsx')] 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/babelrc/fixture/js/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; -------------------------------------------------------------------------------- /test/fixtures/babelrc/fixture/json/.babelrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-syntax-jsx"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/babelrc/fixture/json/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; -------------------------------------------------------------------------------- /test/fixtures/code-file-bad/fixture/code.js: -------------------------------------------------------------------------------- 1 | []fd;s;] 2 | -------------------------------------------------------------------------------- /test/fixtures/code-file-bad/fixture/output.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/code-file-bad/fixture/output.js -------------------------------------------------------------------------------- /test/fixtures/code-files-multiple/fixture/code.mjs: -------------------------------------------------------------------------------- 1 | export const hi = 'hey'; 2 | -------------------------------------------------------------------------------- /test/fixtures/code-files-multiple/fixture/code.ts: -------------------------------------------------------------------------------- 1 | export const nope = 'bad'; 2 | -------------------------------------------------------------------------------- /test/fixtures/code-files-multiple/fixture/code.tsx: -------------------------------------------------------------------------------- 1 | export const nope = 'bad'; 2 | -------------------------------------------------------------------------------- /test/fixtures/code-files-multiple/fixture/output.mjs: -------------------------------------------------------------------------------- 1 | export const hi = 'hey'; 2 | -------------------------------------------------------------------------------- /test/fixtures/code-output-files-empty/empty-code-output/code.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/code-output-files-empty/empty-code-output/code.ts -------------------------------------------------------------------------------- /test/fixtures/code-output-files-empty/empty-code-output/output.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/code-output-files-empty/empty-code-output/output.ts -------------------------------------------------------------------------------- /test/fixtures/code-output-files-empty/empty-code/.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ['@babel/plugin-syntax-typescript', '../../../helpers/plugin-add-line.js'] 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/code-output-files-empty/empty-code/code.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/code-output-files-empty/empty-code/code.ts -------------------------------------------------------------------------------- /test/fixtures/code-output-files-empty/empty-code/output.ts: -------------------------------------------------------------------------------- 1 | "hello world" 2 | -------------------------------------------------------------------------------- /test/fixtures/code-output-files-empty/empty-output/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "@babel/plugin-syntax-typescript", 4 | "../../../helpers/plugin-delete-variables.js" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/code-output-files-empty/empty-output/code.ts: -------------------------------------------------------------------------------- 1 | const val = "hello world"; 2 | -------------------------------------------------------------------------------- /test/fixtures/code-output-files-empty/empty-output/output.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/code-output-files-empty/empty-output/output.ts -------------------------------------------------------------------------------- /test/fixtures/codeFixture-empty.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/codeFixture-empty.js -------------------------------------------------------------------------------- /test/fixtures/codeFixture-indented.js: -------------------------------------------------------------------------------- 1 | const hello = 'hey'; 2 | const helloTwo = 'hey'; 3 | const helloThree = 'hey'; 4 | -------------------------------------------------------------------------------- /test/fixtures/codeFixture-unchanging.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | -------------------------------------------------------------------------------- /test/fixtures/codeFixture.js: -------------------------------------------------------------------------------- 1 | const hello = 'hey'; 2 | -------------------------------------------------------------------------------- /test/fixtures/collate-order-1/fixture/code.js: -------------------------------------------------------------------------------- 1 | const hello = 'world'; 2 | -------------------------------------------------------------------------------- /test/fixtures/collate-order-1/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | babelOptions: { 3 | plugins: [ 4 | () => { 5 | return { 6 | name: 'plugin1', 7 | visitor: { 8 | Identifier(idPath) { 9 | idPath.node.name += '_plugin1'; 10 | } 11 | } 12 | }; 13 | } 14 | ], 15 | presets: [ 16 | () => ({ 17 | plugins: [ 18 | { 19 | name: 'preset1', 20 | visitor: { 21 | Identifier(idPath) { 22 | idPath.node.name += '_preset1'; 23 | } 24 | } 25 | } 26 | ] 27 | }) 28 | ] 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /test/fixtures/collate-order-1/fixture/output.js: -------------------------------------------------------------------------------- 1 | const hello_plugin2_plugin1_plugin3_preset1_preset2_preset3 = 'world'; 2 | -------------------------------------------------------------------------------- /test/fixtures/collate-order-2/fixture/code.js: -------------------------------------------------------------------------------- 1 | const hello = 'world'; 2 | -------------------------------------------------------------------------------- /test/fixtures/collate-order-2/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | babelOptions: { 3 | plugins: [ 4 | () => { 5 | return { 6 | name: 'plugin1', 7 | visitor: { 8 | Identifier(idPath) { 9 | idPath.node.name += '_plugin1'; 10 | } 11 | } 12 | }; 13 | } 14 | ], 15 | presets: [ 16 | () => ({ 17 | plugins: [ 18 | { 19 | name: 'preset1', 20 | visitor: { 21 | Identifier(idPath) { 22 | idPath.node.name += '_preset1'; 23 | } 24 | } 25 | } 26 | ] 27 | }) 28 | ] 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /test/fixtures/collate-order-2/fixture/output.js: -------------------------------------------------------------------------------- 1 | const hello_plugin3_plugin2_plugin1_preset1_preset2_preset3 = 'world'; 2 | -------------------------------------------------------------------------------- /test/fixtures/creates-output-file/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/custom-extension/fixture/code.multipart.ext: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/custom-extension/fixture/output.ext: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/dir-name-with-dashes/fixture-with-dashes/code.js: -------------------------------------------------------------------------------- 1 | var hi = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/dir-name-with-dashes/fixture-with-dashes/output.js: -------------------------------------------------------------------------------- 1 | var hi = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/empty/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/empty/.gitkeep -------------------------------------------------------------------------------- /test/fixtures/exec-and-code-files/fixture/code.js: -------------------------------------------------------------------------------- 1 | var hi = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/exec-and-code-files/fixture/exec.js: -------------------------------------------------------------------------------- 1 | var hi = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/exec-and-output-files/fixture/exec.js: -------------------------------------------------------------------------------- 1 | var hi = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/exec-and-output-files/fixture/output.js: -------------------------------------------------------------------------------- 1 | var hi = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/exec-file-bad/fixture/exec.js: -------------------------------------------------------------------------------- 1 | []fd;s;] 2 | -------------------------------------------------------------------------------- /test/fixtures/exec-file-empty/fixture/exec.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/exec-file-empty/fixture/exec.js -------------------------------------------------------------------------------- /test/fixtures/exec-file-failing/fixture/exec.js: -------------------------------------------------------------------------------- 1 | expect('failed!').toBe('passed!'); 2 | -------------------------------------------------------------------------------- /test/fixtures/exec-file-passing/cjs/exec.cjs: -------------------------------------------------------------------------------- 1 | expect(() => { 2 | throw new Error('not a throw expression'); 3 | }).toThrow('not a throw expression'); 4 | -------------------------------------------------------------------------------- /test/fixtures/exec-file-passing/js/exec.js: -------------------------------------------------------------------------------- 1 | expect(() => { 2 | throw new Error('not a throw expression'); 3 | }).toThrow('not a throw expression'); 4 | -------------------------------------------------------------------------------- /test/fixtures/exec-file-passing/mjs/exec.mjs: -------------------------------------------------------------------------------- 1 | expect(() => { 2 | throw new Error('not a throw expression'); 3 | }).toThrow('not a throw expression'); 4 | -------------------------------------------------------------------------------- /test/fixtures/exec-file-passing/random/exec.ext: -------------------------------------------------------------------------------- 1 | expect(() => { 2 | throw new Error('not a throw expression'); 3 | }).toThrow('not a throw expression'); 4 | -------------------------------------------------------------------------------- /test/fixtures/exec-file-passing/ts/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env", { "targets": { "node": true } }], 4 | ["@babel/preset-typescript"] 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/exec-file-passing/ts/exec.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | expect(() => { 4 | throw new Error('not a throw expression'); 5 | }).toThrow('not a throw expression'); 6 | -------------------------------------------------------------------------------- /test/fixtures/exec-supports-features/fixture/exec.js: -------------------------------------------------------------------------------- 1 | expect(require('path').dirname(__filename)).toBe(__dirname) 2 | expect(JSON.stringify(require(`${__dirname}/imported-file.json`))).toStrictEqual(JSON.stringify({ data: 'imported' })); 3 | -------------------------------------------------------------------------------- /test/fixtures/exec-supports-features/fixture/imported-file.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": "imported" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/execFixture-empty.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/execFixture-empty.js -------------------------------------------------------------------------------- /test/fixtures/execFixture.js: -------------------------------------------------------------------------------- 1 | const olleh = 'hey'; 2 | tcepxe(olleh)['toBe']('hey'); 3 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-1/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-1/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-2/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-2/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { only: true }; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-2/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-3/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-syntax-jsx"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-3/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-3/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "only": false 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-4/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-4/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "only": true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-4/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-5/code.multipart.ext: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-only/fixture-5/output.ext: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-1/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-1/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-2/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-2/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { skip: true }; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-2/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-3/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-syntax-jsx"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-3/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-3/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "skip": false 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-4/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-4/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "skip": true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-4/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-5/code.multipart.ext: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple-with-skip/fixture-5/output.ext: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-1/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-1/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-2/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-2/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { pluginOptions: { foo: 'bar' } }; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-2/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-3/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-syntax-jsx"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-3/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-3/output.jsx: -------------------------------------------------------------------------------- 1 | export default
; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-4/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-4/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "fixtureOutputExt": "js", 3 | "fixtureOutputName": "out", 4 | "pluginOptions": { 5 | "bar": "baz" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-4/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-5/code.multipart.ext: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/multiple/fixture-5/output.ext: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-babelrc/.babelrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-syntax-jsx"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/nested-babelrc/nested/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.babelrc.json" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/nested-babelrc/nested/with-babelrc-extends/.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '../.babelrc' 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/nested-babelrc/nested/with-babelrc-extends/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; -------------------------------------------------------------------------------- /test/fixtures/nested-babelrc/nested/with-babelrc-no-extends/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-syntax-jsx"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/nested-babelrc/nested/with-babelrc-no-extends/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; -------------------------------------------------------------------------------- /test/fixtures/nested-babelrc/with-babelrc-no-extends/.babelrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ['@babel/plugin-syntax-jsx'] 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/nested-babelrc/with-babelrc-no-extends/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; -------------------------------------------------------------------------------- /test/fixtures/nested-incorrectly/code.js: -------------------------------------------------------------------------------- 1 | 'this one should not be seen'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-incorrectly/correct-within-incorrect/code.js: -------------------------------------------------------------------------------- 1 | 'only this one should run'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-incorrectly/correct-within-incorrect/incorrect-within-correct/code.js: -------------------------------------------------------------------------------- 1 | 'this one should not be seen'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-incorrectly/correct-within-incorrect/incorrect-within-correct/output.js: -------------------------------------------------------------------------------- 1 | 'this one should not be seen'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-incorrectly/correct-within-incorrect/output.js: -------------------------------------------------------------------------------- 1 | 'only this one should run'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-incorrectly/output.js: -------------------------------------------------------------------------------- 1 | 'this one should not be seen'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/nested/deeply/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/nested/deeply/with-options/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | bar: 'baz' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/nested/deeply/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/nested/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | foo: 'bar' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/nested/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/nested/with-options/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | rootFoo: null, 4 | foo: null 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/nested/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/nested/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/nested/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | rootFoo: 'rootBar' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-plugin/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/nested/deeply/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/nested/deeply/with-options/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presetOptions: { 3 | bar: 'baz' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/nested/deeply/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/nested/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presetOptions: { 3 | foo: 'bar' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/nested/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/nested/with-options/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presetOptions: { 3 | rootFoo: null, 4 | foo: null 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/nested/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/nested/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/nested/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presetOptions: { 3 | rootFoo: 'rootBar' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-js-preset/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/nested/deeply/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/nested/deeply/with-options/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | bar: 'baz' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/nested/deeply/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/nested/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | foo: 'bar' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/nested/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/nested/with-options/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "rootFoo": null, 4 | "foo": null 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/nested/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/nested/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/nested/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "rootFoo": "rootBar" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-plugin/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/nested/deeply/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/nested/deeply/with-options/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presetOptions: { 3 | bar: 'baz' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/nested/deeply/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/nested/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presetOptions: { 3 | foo: 'bar' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/nested/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/nested/with-options/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "presetOptions": { 3 | "rootFoo": null, 4 | "foo": null 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/nested/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/nested/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/nested/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "presetOptions": { 3 | "rootFoo": "rootBar" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-and-js-preset/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/nested/deeply/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/nested/deeply/with-options/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "bar": "baz" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/nested/deeply/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/nested/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "foo": "bar" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/nested/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/nested/with-options/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "rootFoo": null, 4 | "foo": null 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/nested/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/nested/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/nested/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "rootFoo": "rootBar" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-plugin/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/nested/deeply/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/nested/deeply/with-options/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "presetOptions": { 3 | "bar": "baz" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/nested/deeply/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/nested/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "presetOptions": { 3 | "foo": "bar" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/nested/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/nested/with-options/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "presetOptions": { 3 | "rootFoo": null, 4 | "foo": null 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/nested/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/nested/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/nested/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "presetOptions": { 3 | "rootFoo": "rootBar" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-options-json-preset/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/nested/deeply/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/nested/deeply/with-options/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'n3' 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/nested/deeply/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/nested/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'n2' 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/nested/with-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/nested/with-options/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'n4' 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/nested/with-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/nested/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/nested/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'n1' 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/without-options/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/nested-titles/without-options/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-babelOptions-assumptions/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); 2 | -------------------------------------------------------------------------------- /test/fixtures/option-babelOptions-assumptions/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "babelOptions": { 3 | "assumptions": { 4 | "constantReexports": false 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/option-babelOptions-assumptions/fixture/output.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); 2 | -------------------------------------------------------------------------------- /test/fixtures/option-babelOptions-filename/code/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); 2 | -------------------------------------------------------------------------------- /test/fixtures/option-babelOptions-filename/code/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "babelOptions": { 3 | "filename": "/something/or/other/does/not/exist.js" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/option-babelOptions-filename/code/output.js: -------------------------------------------------------------------------------- 1 | elosnoc.gol('hello'); 2 | -------------------------------------------------------------------------------- /test/fixtures/option-babelOptions-filename/exec/exec.js: -------------------------------------------------------------------------------- 1 | var hello = 'hi'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-babelOptions-filename/exec/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "babelOptions": { 3 | "filename": "/something/or/other/does/not/exist.js" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-auto/crlf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=crlf eol=crlf 2 | # The goal here is to get Git to populate the working tree with native EOL 3 | output.js text=lf -eol 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-auto/crlf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-auto/crlf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-auto/lf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=lf eol=lf 2 | # The goal here is to get Git to populate the working tree with native EOL 3 | output.js text=lf -eol 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-auto/lf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-auto/lf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-crlf/crlf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=crlf eol=crlf 2 | output.js text=crlf eol=crlf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-crlf/crlf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-crlf/crlf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-crlf/lf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=lf eol=lf 2 | output.js text=crlf eol=crlf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-crlf/lf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-crlf/lf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-default/crlf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=crlf eol=crlf 2 | output.js text=lf eol=lf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-default/crlf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-default/crlf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-default/lf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=lf eol=lf 2 | output.js text=lf eol=lf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-default/lf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-default/lf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-false/crlf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=crlf eol=crlf 2 | output.js text=lf eol=lf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-false/crlf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-false/crlf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-false/lf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=lf eol=lf 2 | output.js text=lf eol=lf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-false/lf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-false/lf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-lf/crlf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=crlf eol=crlf 2 | output.js text=lf eol=lf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-lf/crlf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-lf/crlf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-lf/lf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=lf eol=lf 2 | output.js text=lf eol=lf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-lf/lf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-lf/lf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve-no-eol/empty/code.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/option-endOfLine-preserve-no-eol/empty/code.js -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve-no-eol/empty/output.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/option-endOfLine-preserve-no-eol/empty/output.js -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve-no-eol/no-eol/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve-no-eol/no-eol/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve/crlf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=crlf eol=crlf 2 | output.js text=crlf eol=crlf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve/crlf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve/crlf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve/lf/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=lf eol=lf 2 | output.js text=lf eol=lf 3 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve/lf/code.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-endOfLine-preserve/lf/output.js: -------------------------------------------------------------------------------- 1 | var foo = ''; 2 | var bar = ''; 3 | var baz = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-fixtureOutputExt-no-dot/fixture/code.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-fixtureOutputExt-no-dot/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "fixtureOutputExt": "js" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-fixtureOutputExt-no-dot/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-fixtureOutputExt/fixture/code.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-fixtureOutputExt/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "fixtureOutputExt": ".js" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-fixtureOutputExt/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-fixtureOutputName/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-fixtureOutputName/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "fixtureOutputName": "out" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-fixtureOutputName/fixture/out.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-formatResult/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; -------------------------------------------------------------------------------- /test/fixtures/option-formatResult/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | formatResult: (r) => `<< ${r} >>` 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-formatResult/fixture/output.js: -------------------------------------------------------------------------------- 1 | << 'use strict'; >> -------------------------------------------------------------------------------- /test/fixtures/option-only/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-only/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "only": true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-only/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-pluginOptions/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-pluginOptions/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "optionA": false 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/option-pluginOptions/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-presetOptions/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-presetOptions/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "presetOptions": { 3 | "optionA": false 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/option-presetOptions/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/no-return/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/no-return/options.js: -------------------------------------------------------------------------------- 1 | const fs = require('node:fs'); 2 | 3 | module.exports = { 4 | setup: () => { 5 | fs.writeFileSync('/dne/fake-setup-output.js', 'fake setup content 1'); 6 | }, 7 | teardown: () => { 8 | fs.writeFileSync('/dne/fake-teardown-output.js', 'fake teardown content 1'); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/no-return/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | setup: () => { 3 | throw new Error('this setup function should not run'); 4 | }, 5 | teardown: () => { 6 | throw new Error('this teardown function should not run'); 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/return-fn/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/return-fn/options.js: -------------------------------------------------------------------------------- 1 | const fs = require('node:fs'); 2 | 3 | module.exports = { 4 | setup: () => { 5 | fs.writeFileSync('/dne/fake-setup-output.js', 'fake setup content 2'); 6 | return () => fs.writeFileSync('/dne/fake-teardown-output.js', 'fake teardown content 2'); 7 | }, 8 | teardown: undefined 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/return-fn/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/return-promise/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/return-promise/options.js: -------------------------------------------------------------------------------- 1 | const fs = require('node:fs'); 2 | 3 | module.exports = { 4 | setup: async () => { 5 | fs.writeFileSync('/dne/fake-setup-output.js', 'fake setup content 3'); 6 | return Promise.resolve(() => fs.writeFileSync('/dne/fake-teardown-output.js', 'fake teardown content 3')); 7 | }, 8 | teardown: async () => { 9 | fs.writeFileSync('/dne/fake-teardown-output.js', 'fake teardown content 4'); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/option-setup-teardown/return-promise/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-skip-only/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-skip-only/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "skip": true, 3 | "only": true 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/option-skip-only/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-skip/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-skip/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "skip": true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-skip/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-and-exec-file/fixture/exec.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-and-exec-file/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "throws": true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-and-output-file/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-and-output-file/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "throws": true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-and-output-file/fixture/output.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-class/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-class/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "throws": SyntaxError 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-error-deprecated/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-error-deprecated/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-false-function/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-false-function/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | throws: () => false 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-false/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-false/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "throws": false 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-function/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-function/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "throws": (error) => error instanceof SyntaxError && /captured/.test(error.message) 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-regex/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-regex/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | throws: /captured/ 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-string/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-string/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | throws: 'expected this error to be captured' 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/option-throws-true/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); -------------------------------------------------------------------------------- /test/fixtures/option-throws-true/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "throws": true 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-title-empty/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-title-empty/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-title-empty/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-title/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/option-title/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "some-custom-title" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/option-title/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-bad-babelOptions-babelrc-filename/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); 2 | -------------------------------------------------------------------------------- /test/fixtures/options-bad-babelOptions-babelrc-filename/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | babelOptions: { 3 | babelrc: true, 4 | filename: undefined 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/options-bad-babelOptions-babelrc-filename/fixture/output.js: -------------------------------------------------------------------------------- 1 | console.log('hello'); 2 | -------------------------------------------------------------------------------- /test/fixtures/options-js-bad/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-js-bad/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | bar: 4 | }, 5 | presetOptions: { 6 | bar: 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/options-js-bad/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-js/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-js/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | bar: 'baz' 4 | }, 5 | presetOptions: { 6 | bar: 'baz' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/options-js/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-json-and-js/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-json-and-js/fixture/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | bar: 'from-js' 4 | }, 5 | presetOptions: { 6 | bar: 'from-js' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/options-json-and-js/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "bar": "from-json" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/options-json-and-js/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-json-bad/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-json-bad/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "bar": 4 | }, 5 | "presetOptions": { 6 | "bar": 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/options-json-bad/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-json/fixture/code.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/options-json/fixture/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginOptions": { 3 | "bar": "baz" 4 | }, 5 | "presetOptions": { 6 | "bar": "baz" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/options-json/fixture/output.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/outputFixture-empty.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/babel-utils/babel-plugin-tester/08fed9cb78c9acc0e28b408422945b62453b936b/test/fixtures/outputFixture-empty.js -------------------------------------------------------------------------------- /test/fixtures/outputFixture-indented.js: -------------------------------------------------------------------------------- 1 | const olleh = 'hey'; 2 | const owTolleh = 'hey'; 3 | const eerhTolleh = 'hey'; 4 | -------------------------------------------------------------------------------- /test/fixtures/outputFixture.js: -------------------------------------------------------------------------------- 1 | const olleh = 'hey'; 2 | -------------------------------------------------------------------------------- /test/fixtures/prettier-configured/fixture/.prettierrc.js: -------------------------------------------------------------------------------- 1 | // * These are prettier's defaults as of 01/02/2023 2 | // * https://gist.github.com/adbutterfield/6b91625b5b07ca2c29f6322245e3e2bb?permalink_comment_id=3865049#gistcomment-3865049 3 | 4 | module.exports = { 5 | printWidth: 80, 6 | tabWidth: 2, 7 | useTabs: false, 8 | semi: true, 9 | singleQuote: false, 10 | quoteProps: "as-needed", 11 | jsxSingleQuote: false, 12 | trailingComma: "es5", 13 | bracketSpacing: true, 14 | bracketSameLine: false, 15 | jsxBracketSameLine: false, 16 | arrowParens: "always", 17 | rangeEnd: null, 18 | requirePragma: false, 19 | insertPragma: false, 20 | proseWrap: "preserve", 21 | htmlWhitespaceSensitivity: "css", 22 | vueIndentScriptAndStyle: false, 23 | endOfLine: "lf", 24 | embeddedLanguageFormatting: "auto", 25 | singleAttributePerLine: false, 26 | overrides: [ 27 | { 28 | files: "**/*.mts", 29 | options: { 30 | parser: "babel-ts", 31 | singleQuote: true 32 | }, 33 | }, 34 | ], 35 | }; 36 | -------------------------------------------------------------------------------- /test/fixtures/prettier-configured/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log( "hey" ) 2 | -------------------------------------------------------------------------------- /test/fixtures/prettier-configured/fixture/output.js: -------------------------------------------------------------------------------- 1 | console.log("hey"); 2 | -------------------------------------------------------------------------------- /test/fixtures/prettier/fixture/code.js: -------------------------------------------------------------------------------- 1 | console.log( "hey" ) 2 | -------------------------------------------------------------------------------- /test/fixtures/prettier/fixture/output.js: -------------------------------------------------------------------------------- 1 | console.log('hey'); 2 | -------------------------------------------------------------------------------- /test/fixtures/simple-failing/fixture/code.js: -------------------------------------------------------------------------------- 1 | var hi = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/simple-failing/fixture/output.js: -------------------------------------------------------------------------------- 1 | var xyz = 'xyz'; 2 | -------------------------------------------------------------------------------- /test/fixtures/simple-multiline/fixture/.gitattributes: -------------------------------------------------------------------------------- 1 | code.js text=lf eol=lf 2 | output.js text=crlf eol=crlf 3 | -------------------------------------------------------------------------------- /test/fixtures/simple-multiline/fixture/code.js: -------------------------------------------------------------------------------- 1 | var hi1 = 'hey'; 2 | var hi2 = 'hey'; 3 | var hi3 = 'there are two newlines at the bottom of this file on purpose'; 4 | 5 | -------------------------------------------------------------------------------- /test/fixtures/simple-multiline/fixture/output.js: -------------------------------------------------------------------------------- 1 | var hi1 = 'hey'; 2 | var hi2 = 'hey'; 3 | var hi3 = 'there are two newlines at the bottom of this file on purpose'; 4 | 5 | -------------------------------------------------------------------------------- /test/fixtures/simple-reversed/fixture/code.js: -------------------------------------------------------------------------------- 1 | const hello = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/simple-reversed/fixture/output.js: -------------------------------------------------------------------------------- 1 | const olleh = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/simple/fixture/code.js: -------------------------------------------------------------------------------- 1 | var hi = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/simple/fixture/output.js: -------------------------------------------------------------------------------- 1 | var hi = 'hey'; -------------------------------------------------------------------------------- /test/fixtures/support-jsx/fixture/.babelrc: -------------------------------------------------------------------------------- 1 | { "plugins": [["@babel/plugin-syntax-jsx"]] } 2 | -------------------------------------------------------------------------------- /test/fixtures/support-jsx/fixture/code.jsx: -------------------------------------------------------------------------------- 1 | export default
; 2 | -------------------------------------------------------------------------------- /test/fixtures/support-ts/fixture/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [["@babel/plugin-syntax-typescript"]] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/support-ts/fixture/code.ts: -------------------------------------------------------------------------------- 1 | export default (): { something: string } => { 2 | return { something: 'string' }; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/support-ts/fixture/output.ts: -------------------------------------------------------------------------------- 1 | export default ((): { 2 | something: string; 3 | } => { 4 | return { 5 | something: 'string' 6 | }; 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/support-tsx/fixture/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [["@babel/plugin-syntax-typescript", { "isTSX": true }]] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/support-tsx/fixture/code.tsx: -------------------------------------------------------------------------------- 1 | export default (
as any); 2 | -------------------------------------------------------------------------------- /test/helpers/plugin-add-line.js: -------------------------------------------------------------------------------- 1 | // * This file exists for tests that might require this file directly, hence 2 | // * it must be a simple JavaScript file and not, say, a TypeScript file. 3 | 4 | module.exports = addLinePlugin; 5 | 6 | /** 7 | * Dummy plugin that deletes everything and results in an empty string output. 8 | */ 9 | function addLinePlugin() { 10 | return { 11 | name: 'add-line', 12 | visitor: { 13 | Program(path) { 14 | path.unshiftContainer('body', { 15 | type: 'StringLiteral', 16 | value: 'hello world' 17 | }); 18 | } 19 | } 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /test/helpers/plugin-delete-variables.js: -------------------------------------------------------------------------------- 1 | // * This file exists for tests that might require this file directly, hence 2 | // * it must be a simple JavaScript file and not, say, a TypeScript file. 3 | 4 | module.exports = deleteVariablesPlugin; 5 | 6 | /** 7 | * Dummy plugin that deletes variable declarations. 8 | */ 9 | function deleteVariablesPlugin() { 10 | return { 11 | name: 'cleanup', 12 | visitor: { 13 | VariableDeclaration(p) { 14 | p.remove(); 15 | } 16 | } 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /test/helpers/plugin-identifier-reverse.js: -------------------------------------------------------------------------------- 1 | // * This file exists for tests that might require this file directly, hence 2 | // * it must be a simple JavaScript file and not, say, a TypeScript file. 3 | 4 | module.exports = identifierReversePlugin; 5 | 6 | /** 7 | * Dummy plugin that reverses the character order of all identifiers. 8 | */ 9 | function identifierReversePlugin() { 10 | return { 11 | visitor: { 12 | Identifier(idPath) { 13 | idPath.node.name = idPath.node.name.split('').reverse().join(''); 14 | } 15 | } 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /test/helpers/plugins.ts: -------------------------------------------------------------------------------- 1 | import type { PluginItem, PluginObj, PluginPass as State } from '@babel/core'; 2 | import type { PluginTesterOptions } from '../../src/index'; 3 | 4 | /** 5 | * Dummy plugin that reverses the character order of all identifiers. 6 | */ 7 | export const identifierReversePlugin: () => PluginObj = require('./plugin-identifier-reverse'); 8 | 9 | /** 10 | * Dummy plugin that deletes variable declarations. 11 | */ 12 | export const deleteVariablesPlugin: () => PluginObj = require('./plugin-delete-variables'); 13 | 14 | /** 15 | * Dummy plugin that adds a single "hello world" string to the beginning of a 16 | * program. 17 | */ 18 | export const addLinePlugin: () => PluginObj = require('./plugin-add-line'); 19 | 20 | /** 21 | * When called, returns a no-op babel plugin that tracks invocation order. 22 | */ 23 | export function makePluginWithOrderTracking(orderArray: number[], orderInt: number) { 24 | return (): PluginObj => { 25 | return { 26 | name: 'order-tracker', 27 | visitor: { 28 | Program() { 29 | orderArray.push(orderInt); 30 | } 31 | } 32 | }; 33 | }; 34 | } 35 | 36 | /** 37 | * When called, returns a babel plugin that appends a string to all identifiers. 38 | */ 39 | export function makePluginThatAppendsToIdentifier(suffix: string) { 40 | return (): PluginObj => { 41 | return { 42 | name: suffix, 43 | visitor: { 44 | Identifier(idPath) { 45 | idPath.node.name += `_${suffix}`; 46 | } 47 | } 48 | }; 49 | }; 50 | } 51 | 52 | /** 53 | * When called, returns a babel preset containing the provided plugin. 54 | */ 55 | export function makePresetFromPlugin( 56 | pluginOrFn: PluginItem | (() => PluginObj) 57 | ): NonNullable { 58 | return () => ({ 59 | plugins: [typeof pluginOrFn == 'function' ? pluginOrFn() : pluginOrFn] 60 | }); 61 | } 62 | -------------------------------------------------------------------------------- /test/integration/assets/index.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'node:fs'; 2 | 3 | export const assets = { 4 | invocation: { 5 | main: readFileSync(`${__dirname}/main/invocation.js`, 'utf8'), 6 | pure: readFileSync(`${__dirname}/pure/invocation.js`, 'utf8') 7 | }, 8 | invocationOnly: { 9 | main: readFileSync(`${__dirname}/main/invocation-only.js`, 'utf8'), 10 | pure: readFileSync(`${__dirname}/pure/invocation-only.js`, 'utf8') 11 | }, 12 | invocationSkip: { 13 | main: readFileSync(`${__dirname}/main/invocation-skip.js`, 'utf8'), 14 | pure: readFileSync(`${__dirname}/pure/invocation-skip.js`, 'utf8') 15 | }, 16 | invocationSnapshot: { 17 | main: readFileSync(`${__dirname}/main/invocation-snapshot.js`, 'utf8'), 18 | pure: readFileSync(`${__dirname}/pure/invocation-snapshot.js`, 'utf8') 19 | }, 20 | dummyFixtureAssetCode: { 21 | main: readFileSync(`${__dirname}/main/fixtures/dummy-fixture-asset/code.js`, 'utf8'), 22 | pure: readFileSync(`${__dirname}/pure/fixtures/dummy-fixture-asset/code.js`, 'utf8') 23 | }, 24 | dummyFixtureAssetOptions: { 25 | main: readFileSync( 26 | `${__dirname}/main/fixtures/dummy-fixture-asset/options.js`, 27 | 'utf8' 28 | ), 29 | pure: readFileSync( 30 | `${__dirname}/pure/fixtures/dummy-fixture-asset/options.js`, 31 | 'utf8' 32 | ) 33 | }, 34 | dummyFixtureAssetOutput: { 35 | main: readFileSync( 36 | `${__dirname}/main/fixtures/dummy-fixture-asset/output.js`, 37 | 'utf8' 38 | ), 39 | pure: readFileSync(`${__dirname}/pure/fixtures/dummy-fixture-asset/output.js`, 'utf8') 40 | }, 41 | pluginIdentifierReverse: readFileSync( 42 | `${__dirname}/plugin-identifier-reverse.js`, 43 | 'utf8' 44 | ) 45 | }; 46 | -------------------------------------------------------------------------------- /test/integration/assets/main/fixtures/dummy-fixture-asset/code.js: -------------------------------------------------------------------------------- 1 | const hello = 'hey'; -------------------------------------------------------------------------------- /test/integration/assets/main/fixtures/dummy-fixture-asset/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'asset-test', 3 | setup: () => console.log('working') 4 | }; 5 | -------------------------------------------------------------------------------- /test/integration/assets/main/fixtures/dummy-fixture-asset/output.js: -------------------------------------------------------------------------------- 1 | const olleh = "hey"; 2 | -------------------------------------------------------------------------------- /test/integration/assets/main/invocation-only.js: -------------------------------------------------------------------------------- 1 | pluginTester({ 2 | filepath: `${__dirname}/../fixtures/fake.js`, 3 | plugin: identifierReversePlugin, 4 | tests: { 5 | 'does not change code with no identifiers': '"hello";', 6 | 'changes this code': { 7 | only: true, 8 | code: "var hello = 'hi';", 9 | output: 'var olleh = "hi";' 10 | }, 11 | 'using fixtures files': { 12 | fixture: 'dummy-fixture-asset/code.js', 13 | outputFixture: 'dummy-fixture-asset/output.js' 14 | } 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /test/integration/assets/main/invocation-skip.js: -------------------------------------------------------------------------------- 1 | pluginTester({ 2 | plugin: identifierReversePlugin, 3 | tests: { 4 | 'does not change code with no identifiers': '"hello";', 5 | 'changes this code': { 6 | skip: true, 7 | code: "var hello = 'hi';", 8 | output: 'var olleh = "hi";' 9 | }, 10 | 'using fixtures files': { 11 | skip: true, 12 | fixture: '../fixtures/dummy-fixture-asset/code.js', 13 | outputFixture: '../fixtures/dummy-fixture-asset/output.js' 14 | } 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /test/integration/assets/main/invocation-snapshot.js: -------------------------------------------------------------------------------- 1 | pluginTester({ 2 | plugin: identifierReversePlugin, 3 | tests: { 4 | 'using snapshots': { 5 | code: ` 6 | function sayHi(person) { 7 | return 'Hello ' + person + '!' 8 | } 9 | `, 10 | snapshot: true 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /test/integration/assets/main/invocation.js: -------------------------------------------------------------------------------- 1 | pluginTester({ 2 | plugin: identifierReversePlugin, 3 | fixtures: '../fixtures', 4 | tests: { 5 | 'does not change code with no identifiers': '"hello";', 6 | 'changes this code': { 7 | code: "var hello = 'hi';", 8 | output: 'var olleh = "hi";' 9 | }, 10 | 'using fixtures files': { 11 | fixture: '../fixtures/dummy-fixture-asset/code.js', 12 | outputFixture: '../fixtures/dummy-fixture-asset/output.js' 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /test/integration/assets/plugin-identifier-reverse.js: -------------------------------------------------------------------------------- 1 | // * This file exists for tests that might require this file directly, hence 2 | // * it must be a simple JavaScript file and not, say, a TypeScript file. 3 | 4 | module.exports = identifierReversePlugin; 5 | 6 | /** 7 | * Dummy plugin that reverses the character order of all identifiers. 8 | */ 9 | function identifierReversePlugin() { 10 | return { 11 | visitor: { 12 | Identifier(idPath) { 13 | idPath.node.name = idPath.node.name.split('').reverse().join(''); 14 | } 15 | } 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /test/integration/assets/pure/fixtures/dummy-fixture-asset/code.js: -------------------------------------------------------------------------------- 1 | const hello = 'hey'; -------------------------------------------------------------------------------- /test/integration/assets/pure/fixtures/dummy-fixture-asset/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'asset-test', 3 | setup: () => console.log('working') 4 | }; 5 | -------------------------------------------------------------------------------- /test/integration/assets/pure/fixtures/dummy-fixture-asset/output.js: -------------------------------------------------------------------------------- 1 | const olleh = 'hey'; 2 | -------------------------------------------------------------------------------- /test/integration/assets/pure/invocation-only.js: -------------------------------------------------------------------------------- 1 | pluginTester({ 2 | filepath: `${__dirname}/../fixtures/fake.js`, 3 | plugin: identifierReversePlugin, 4 | tests: { 5 | 'does not change code with no identifiers': "'hello';", 6 | 'changes this code': { 7 | only: true, 8 | code: "var hello = 'hi';", 9 | output: "var olleh = 'hi';" 10 | }, 11 | 'using fixtures files': { 12 | fixture: 'dummy-fixture-asset/code.js', 13 | outputFixture: 'dummy-fixture-asset/output.js' 14 | } 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /test/integration/assets/pure/invocation-skip.js: -------------------------------------------------------------------------------- 1 | pluginTester({ 2 | plugin: identifierReversePlugin, 3 | tests: { 4 | 'does not change code with no identifiers': "'hello';", 5 | 'changes this code': { 6 | skip: true, 7 | code: "var hello = 'hi';", 8 | output: "var olleh = 'hi';" 9 | }, 10 | 'using fixtures files': { 11 | skip: true, 12 | fixture: '../fixtures/dummy-fixture-asset/code.js', 13 | outputFixture: '../fixtures/dummy-fixture-asset/output.js' 14 | } 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /test/integration/assets/pure/invocation-snapshot.js: -------------------------------------------------------------------------------- 1 | pluginTester({ 2 | plugin: identifierReversePlugin, 3 | tests: { 4 | 'using snapshots': { 5 | code: ` 6 | function sayHi(person) { 7 | return 'Hello ' + person + '!' 8 | } 9 | `, 10 | snapshot: true 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /test/integration/assets/pure/invocation.js: -------------------------------------------------------------------------------- 1 | pluginTester({ 2 | plugin: identifierReversePlugin, 3 | fixtures: '../fixtures', 4 | tests: { 5 | 'does not change code with no identifiers': "'hello';", 6 | 'changes this code': { 7 | code: "var hello = 'hi';", 8 | output: "var olleh = 'hi';" 9 | }, 10 | 'using fixtures files': { 11 | fixture: '../fixtures/dummy-fixture-asset/code.js', 12 | outputFixture: '../fixtures/dummy-fixture-asset/output.js' 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /test/integration/integration-node-interop.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable jest/require-hook */ 2 | /* eslint-disable jest/no-conditional-in-test, jest/no-conditional-expect */ 3 | 4 | // * These are tests that ensure babel-plugin-tester works (1) in ESM vs CJS 5 | // * environments, (2) using modern vs modern-default vs default vs dot-default 6 | // * import syntax, (3) using main vs pure import specifiers, (4) across all 7 | // * maintained versions of NodeJS. 8 | 9 | import { existsSync } from 'node:fs'; 10 | import debugFactory from 'debug'; 11 | import mergeWith from 'lodash.mergewith'; 12 | import path from 'node:path'; 13 | 14 | import { name as pkgName, exports as pkgExports } from '../../package.json'; 15 | import { withMockedFixture } from '../setup'; 16 | import { assets } from './assets'; 17 | import { expectSuccessAndOutput } from './test-expectations'; 18 | 19 | import { 20 | defaultFixtureOptions, 21 | BABEL_VERSIONS_UNDER_TEST, 22 | IMPORT_SPECIFIERS_UNDER_TEST, 23 | IMPORT_STYLES_UNDER_TEST, 24 | NODE_VERSIONS_UNDER_TEST 25 | } from './test-config'; 26 | 27 | const TEST_IDENTIFIER = 'node-interop'; 28 | const debug = debugFactory(`${pkgName}:${TEST_IDENTIFIER}`); 29 | 30 | const pkgMainPath = `${__dirname}/../../${pkgExports['.'].default}`; 31 | const pkgPurePath = `${__dirname}/../../${pkgExports['./pure'].default}`; 32 | 33 | debug('BABEL_VERSIONS_UNDER_TEST: %O', BABEL_VERSIONS_UNDER_TEST); 34 | debug('IMPORT_SPECIFIERS_UNDER_TEST: %O', IMPORT_SPECIFIERS_UNDER_TEST); 35 | debug('IMPORT_STYLES_UNDER_TEST: %O', IMPORT_STYLES_UNDER_TEST); 36 | 37 | beforeAll(async () => { 38 | if (!existsSync(pkgMainPath)) { 39 | debug(`unable to find main export: ${pkgMainPath}`); 40 | throw new Error('must build distributables first (try `npm run build-dist`)'); 41 | } 42 | 43 | if (!existsSync(pkgPurePath)) { 44 | debug(`unable to find pure export: ${pkgPurePath}`); 45 | throw new Error('must build distributables first (try `npm run build-dist`)'); 46 | } 47 | }); 48 | 49 | let counter = 1; 50 | 51 | for (const esm of [true, false] as const) { 52 | for (const importSpecifierName of IMPORT_SPECIFIERS_UNDER_TEST) { 53 | for (const importStyleName of IMPORT_STYLES_UNDER_TEST) { 54 | for (const nodeVersion of NODE_VERSIONS_UNDER_TEST) { 55 | const count = counter++; 56 | const title = `${count}. works as a ${importStyleName} ${importSpecifierName} ${ 57 | esm ? 'ESM' : 'CJS' 58 | } import using ${nodeVersion}`; 59 | 60 | if (esm && importStyleName == 'dot-default') { 61 | debug(`skipped test due to incompatible options: ${title}`); 62 | continue; 63 | } 64 | 65 | debug(`registered test: ${title}`); 66 | 67 | // eslint-disable-next-line jest/valid-title 68 | (process.env.NO_CONCURRENT ? it : it.concurrent)(title, async () => { 69 | // eslint-disable-next-line jest/no-standalone-expect 70 | expect.hasAssertions(); 71 | 72 | debug(`started running test: ${title}`); 73 | 74 | const indexPath = `src/index.test.${esm ? 'm' : ''}js`; 75 | const importSpecifier = `${pkgName}${ 76 | importSpecifierName == 'main' ? '' : '/pure' 77 | }`; 78 | 79 | const importStyle = { 80 | modern: '{ pluginTester }', 81 | 'modern-default': '{ default: pluginTester }', 82 | default: 'pluginTester', 83 | 'dot-default': 'pluginTester' 84 | }[importStyleName]; 85 | 86 | const fixtureOptions = mergeWith( 87 | {}, 88 | defaultFixtureOptions, 89 | { 90 | performCleanup: false, 91 | runInstallScripts: true, 92 | npmInstall: ['@babel/core@latest', 'jest@latest', nodeVersion], 93 | runWith: { 94 | binary: 'npx', 95 | args: [ 96 | 'node', 97 | '--experimental-vm-modules', 98 | path.join('node_modules', 'jest', 'bin', 'jest') 99 | ] 100 | } 101 | }, 102 | { 103 | initialFileContents: { 104 | 'jest.config.js': 105 | 'module.exports = {testMatch:["**/?(*.)+(spec|test).?(m)[jt]s?(x)"],transform:{}};', 106 | 'fixtures/dummy-fixture-asset/code.js': 107 | assets.dummyFixtureAssetCode[importSpecifierName], 108 | 'fixtures/dummy-fixture-asset/options.js': 109 | assets.dummyFixtureAssetOptions[importSpecifierName], 110 | 'fixtures/dummy-fixture-asset/output.js': 111 | assets.dummyFixtureAssetOutput[importSpecifierName] 112 | } 113 | } 114 | ); 115 | 116 | const sourceInput = assets.invocation[importSpecifierName]; 117 | const sourceCode = 118 | typeof sourceInput == 'string' 119 | ? sourceInput 120 | : sourceInput[esm ? 'esm' : 'cjs']; 121 | 122 | fixtureOptions.initialFileContents[indexPath] = esm 123 | ? ` 124 | import ${ 125 | esm ? importStyle.replaceAll(':', ' as') : importStyle 126 | } from '${importSpecifier}'; 127 | import identifierReversePlugin from '../plugin-identifier-reverse.js'; 128 | 129 | ${sourceCode} 130 | ` 131 | : ` 132 | const ${importStyle} = require('${importSpecifier}')${ 133 | importStyleName == 'dot-default' ? '.default' : '' 134 | }; 135 | const identifierReversePlugin = require('../plugin-identifier-reverse.js'); 136 | 137 | ${sourceCode} 138 | `; 139 | 140 | await withMockedFixture({ 141 | testIdentifier: TEST_IDENTIFIER, 142 | options: fixtureOptions, 143 | fn: async (context) => { 144 | if (!context.testResult) { 145 | throw new Error('must use node-import-test fixture'); 146 | } 147 | 148 | expectSuccessAndOutput(context); 149 | } 150 | }); 151 | }); 152 | } 153 | } 154 | } 155 | } 156 | 157 | debug('finished registering tests'); 158 | debug(`registered a total of ${counter} tests!`); 159 | -------------------------------------------------------------------------------- /test/integration/integration-node-smoke.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable jest/require-hook */ 2 | /* eslint-disable jest/no-conditional-in-test, jest/no-conditional-expect */ 3 | 4 | // * These are tests that ensure babel-plugin-tester works (1) with the babel 5 | // * versions we claim it does, (2) with the test frameworks we claim it does, 6 | // * (3) with the feature set we claim and interoperability code given in the 7 | // * documentation. 8 | 9 | import { existsSync } from 'node:fs'; 10 | import debugFactory from 'debug'; 11 | import mergeWith from 'lodash.mergewith'; 12 | 13 | import { name as pkgName, exports as pkgExports } from '../../package.json'; 14 | import { withMockedFixture } from '../setup'; 15 | import { assets } from './assets'; 16 | 17 | import { 18 | defaultFixtureOptions, 19 | BABEL_VERSIONS_UNDER_TEST, 20 | FRAMEWORKS_UNDER_TEST, 21 | type IMPORT_SPECIFIERS_UNDER_TEST 22 | } from './test-config'; 23 | 24 | const TEST_IDENTIFIER = 'node-smoke'; 25 | const TEST_TARGET: (typeof IMPORT_SPECIFIERS_UNDER_TEST)[number] = 'main'; // * Or: 'pure' 26 | const debug = debugFactory(`${pkgName}:${TEST_IDENTIFIER}`); 27 | 28 | const pkgMainPath = `${__dirname}/../../${pkgExports['.'].default}`; 29 | const pkgPurePath = `${__dirname}/../../${pkgExports['./pure'].default}`; 30 | 31 | debug('FRAMEWORKS_UNDER_TEST: %O', FRAMEWORKS_UNDER_TEST); 32 | debug('BABEL_VERSIONS_UNDER_TEST: %O', BABEL_VERSIONS_UNDER_TEST); 33 | 34 | beforeAll(async () => { 35 | if (!existsSync(pkgMainPath)) { 36 | debug(`unable to find main export: ${pkgMainPath}`); 37 | throw new Error('must build distributables first (try `npm run build-dist`)'); 38 | } 39 | 40 | if (!existsSync(pkgPurePath)) { 41 | debug(`unable to find pure export: ${pkgPurePath}`); 42 | throw new Error('must build distributables first (try `npm run build-dist`)'); 43 | } 44 | }); 45 | 46 | let counter = 1; 47 | 48 | for (const [babelPkg, ...otherBabelPkgs] of BABEL_VERSIONS_UNDER_TEST) { 49 | for (const { 50 | frameworkPkg, 51 | frameworkArgs, 52 | otherFrameworkPkgs, 53 | tests 54 | } of FRAMEWORKS_UNDER_TEST) { 55 | const otherPkgs = otherBabelPkgs.concat(otherFrameworkPkgs || []); 56 | const pkgsString = [babelPkg, frameworkPkg, ...otherPkgs].join(', '); 57 | 58 | for (const [index, { source, expectations }] of tests.entries()) { 59 | const count = counter++; 60 | const title = `${count}. works with ${pkgsString} [ subtest #${index + 1} ]`; 61 | 62 | debug(`registered test: ${title}`); 63 | 64 | // eslint-disable-next-line jest/valid-title 65 | (process.env.NO_CONCURRENT ? it : it.concurrent)(title, async () => { 66 | // eslint-disable-next-line jest/no-standalone-expect 67 | expect.hasAssertions(); 68 | 69 | debug(`started running test: ${title}`); 70 | 71 | const indexPath = 'src/index.test.js'; 72 | const importSpecifier = `${pkgName}${TEST_TARGET == 'main' ? '' : '/pure'}`; 73 | 74 | const fixtureOptions = mergeWith( 75 | {}, 76 | defaultFixtureOptions, 77 | { 78 | npmInstall: [frameworkPkg, babelPkg, ...otherPkgs].filter( 79 | (p) => !p.startsWith('node:') 80 | ), 81 | runWith: { 82 | binary: 'npx', 83 | args: [...frameworkArgs] 84 | } 85 | }, 86 | { 87 | initialFileContents: { 88 | 'fixtures/dummy-fixture-asset/code.js': 89 | assets.dummyFixtureAssetCode[TEST_TARGET], 90 | 'fixtures/dummy-fixture-asset/options.js': 91 | assets.dummyFixtureAssetOptions[TEST_TARGET], 92 | 'fixtures/dummy-fixture-asset/output.js': 93 | assets.dummyFixtureAssetOutput[TEST_TARGET] 94 | } 95 | } 96 | ); 97 | 98 | const sourceInput = source[TEST_TARGET]; 99 | const sourceCode = 100 | typeof sourceInput == 'string' ? sourceInput : sourceInput['cjs']; 101 | 102 | fixtureOptions.initialFileContents[indexPath] = ` 103 | const { pluginTester } = require('${importSpecifier}'); 104 | const identifierReversePlugin = require('../plugin-identifier-reverse.js'); 105 | 106 | ${sourceCode} 107 | `; 108 | 109 | await withMockedFixture({ 110 | testIdentifier: TEST_IDENTIFIER, 111 | options: fixtureOptions, 112 | fn: async (context) => { 113 | if (!context.testResult) { 114 | throw new Error('must use node-import-test fixture'); 115 | } 116 | 117 | expectations(context); 118 | } 119 | }); 120 | }); 121 | } 122 | } 123 | } 124 | 125 | debug('finished registering tests'); 126 | debug(`registered a total of ${counter} tests!`); 127 | -------------------------------------------------------------------------------- /test/integration/test-config.ts: -------------------------------------------------------------------------------- 1 | // * Comment out elements of the below X_UNDER_TEST arrays to limit the tests 2 | // * that get run. Use test titles to determine how to manipulate these knobs. 3 | // * 4 | // * You can also use https://jestjs.io/docs/cli#--testnamepatternregex to match 5 | // * against test titles via the number prefixed to each title. Numeric prefixes 6 | // * are stable with respect to the settings configured below. That is: the 7 | // * numbers will only change when the configuration below changes. You can also 8 | // * match against test framework names (like `node:test`) and other settings. 9 | 10 | import browserslist from 'browserslist'; 11 | 12 | import { name as pkgName, version as pkgVersion } from '../../package.json'; 13 | import { withNodeTestInterop, withJasmineInterop } from './test-interop'; 14 | import { assets } from './assets'; 15 | 16 | import { 17 | dummyNpmPackageFixture, 18 | npmCopySelfFixture, 19 | nodeImportTestFixture, 20 | dummyDirectoriesFixture, 21 | dummyFilesFixture, 22 | type FixtureOptions, 23 | type FixtureContext 24 | } from '../setup'; 25 | 26 | import { 27 | expectErrorNoDescribe, 28 | expectErrorNoOnly, 29 | expectErrorNoSkip, 30 | expectErrorNoSnapshot, 31 | expectSuccess, 32 | expectSuccessAndOutput 33 | } from './test-expectations'; 34 | 35 | import type { ReadonlyDeep } from 'type-fest'; 36 | 37 | /* prettier-ignore */ 38 | export const IMPORT_SPECIFIERS_UNDER_TEST = ([ 39 | 'main', // ? import ... from 'babel-plugin-tester' (and CJS version) 40 | 'pure' // ? import ... from 'babel-plugin-tester/pure' (and CJS version) 41 | ] as const); 42 | 43 | /* prettier-ignore */ 44 | export const IMPORT_STYLES_UNDER_TEST = ([ 45 | 'modern', // ? import { pluginTester } from '...' (and CJS version) 46 | 'modern-default', // ? import { default: pluginTester } from '...' (and CJS version) 47 | 'default', // ? import pluginTester from '...' (and CJS version) 48 | 'dot-default' // ? const pluginTester = require('...').default 49 | ] as const); 50 | 51 | /* prettier-ignore */ 52 | export const BABEL_VERSIONS_UNDER_TEST = ([ 53 | // * [babel@version, ...otherPackages] 54 | ['@babel/core@7.11.6'], // ? Current minimum version 55 | ['@babel/core@latest'] // ? Latest version 56 | ]); 57 | 58 | // * [node@version, ...] 59 | export const NODE_VERSIONS_UNDER_TEST = browserslist('maintained node versions').map( 60 | (v) => v.split(' ').join('@') 61 | ); 62 | 63 | export const FRAMEWORKS_UNDER_TEST: FrameworksUnderTest = [ 64 | { 65 | frameworkPkg: 'jest@latest', 66 | frameworkArgs: ['jest'], 67 | tests: [ 68 | { source: assets.invocation, expectations: expectSuccessAndOutput }, 69 | { source: assets.invocationOnly, expectations: expectSuccess }, 70 | { source: assets.invocationSkip, expectations: expectSuccess }, 71 | { source: assets.invocationSnapshot, expectations: expectSuccess } 72 | ] 73 | }, 74 | { 75 | frameworkPkg: 'vitest@latest', 76 | frameworkArgs: ['vitest', 'run', '--globals'], 77 | tests: [ 78 | { 79 | source: assets.invocation, 80 | expectations: expectSuccessAndOutput 81 | }, 82 | { source: assets.invocationOnly, expectations: expectSuccess }, 83 | { source: assets.invocationSkip, expectations: expectSuccess }, 84 | { 85 | source: assets.invocationSnapshot, 86 | expectations: expectSuccess 87 | } 88 | ] 89 | }, 90 | { 91 | frameworkPkg: 'mocha@latest', 92 | frameworkArgs: ['mocha'], 93 | tests: [ 94 | { source: assets.invocation, expectations: expectSuccessAndOutput }, 95 | { source: assets.invocationOnly, expectations: expectSuccess }, 96 | { source: assets.invocationSkip, expectations: expectSuccess }, 97 | { source: assets.invocationSnapshot, expectations: expectErrorNoSnapshot } 98 | ] 99 | }, 100 | { 101 | frameworkPkg: 'jasmine@latest', 102 | frameworkArgs: ['jasmine'], 103 | tests: [ 104 | { source: assets.invocation, expectations: expectSuccessAndOutput }, 105 | { 106 | source: withJasmineInterop(assets.invocation), 107 | expectations: expectSuccessAndOutput 108 | }, 109 | { source: assets.invocationOnly, expectations: expectErrorNoOnly }, 110 | { 111 | source: withJasmineInterop(assets.invocationOnly), 112 | expectations: expectSuccess 113 | }, 114 | { source: assets.invocationSkip, expectations: expectErrorNoSkip }, 115 | { 116 | source: withJasmineInterop(assets.invocationSkip), 117 | expectations: expectSuccess 118 | }, 119 | { source: assets.invocationSnapshot, expectations: expectErrorNoSnapshot }, 120 | { 121 | source: withJasmineInterop(assets.invocationSnapshot), 122 | expectations: expectErrorNoSnapshot 123 | } 124 | ] 125 | }, 126 | { 127 | frameworkPkg: 'node:test', 128 | frameworkArgs: ['node'], 129 | tests: [ 130 | { source: assets.invocation, expectations: expectErrorNoDescribe }, 131 | { 132 | source: withNodeTestInterop(assets.invocation), 133 | expectations: expectSuccessAndOutput 134 | }, 135 | { source: assets.invocationOnly, expectations: expectErrorNoDescribe }, 136 | { source: withNodeTestInterop(assets.invocationOnly), expectations: expectSuccess }, 137 | { source: assets.invocationSkip, expectations: expectErrorNoDescribe }, 138 | { source: withNodeTestInterop(assets.invocationSkip), expectations: expectSuccess }, 139 | { source: assets.invocationSnapshot, expectations: expectErrorNoDescribe }, 140 | { 141 | source: withNodeTestInterop(assets.invocationSnapshot), 142 | expectations: expectErrorNoSnapshot 143 | } 144 | ] 145 | } 146 | ]; 147 | 148 | export const defaultFixtureOptions = { 149 | performCleanup: true, 150 | initialFileContents: { 151 | 'package.json': `{"name":"dummy-pkg","dependencies":{"${pkgName}":"${pkgVersion}"}}`, 152 | 'plugin-identifier-reverse.js': assets.pluginIdentifierReverse 153 | }, 154 | directoryPaths: ['fixtures/dummy-fixture-asset'], 155 | use: [ 156 | dummyNpmPackageFixture(), 157 | npmCopySelfFixture(), 158 | dummyDirectoriesFixture(), 159 | dummyFilesFixture(), 160 | nodeImportTestFixture() 161 | ] 162 | } as Partial & { 163 | initialFileContents: FixtureOptions['initialFileContents']; 164 | }; 165 | 166 | export type FrameworksUnderTest = ReadonlyDeep< 167 | { 168 | frameworkPkg: string; 169 | frameworkArgs: string[]; 170 | otherFrameworkPkgs?: string[]; 171 | tests: { 172 | source: Record< 173 | (typeof IMPORT_SPECIFIERS_UNDER_TEST)[number], 174 | string | { esm: string; cjs: string } 175 | >; 176 | expectations: (context: FixtureContext) => unknown; 177 | }[]; 178 | }[] 179 | >; 180 | -------------------------------------------------------------------------------- /test/integration/test-expectations.ts: -------------------------------------------------------------------------------- 1 | import stripAnsi from 'strip-ansi'; 2 | import { ErrorMessage } from '../../src/errors'; 3 | 4 | import type { FixtureContext } from '../setup'; 5 | 6 | const combineStdOutAndStdErr = (testResult: FixtureContext['testResult']) => { 7 | return stripAnsi(testResult?.stdout || '') + stripAnsi(testResult?.stderr || ''); 8 | }; 9 | 10 | export function expectSuccess(context: FixtureContext) { 11 | const output = combineStdOutAndStdErr(context.testResult); 12 | 13 | expect(output).toMatch(/\bpass|((?; 8 | 9 | for (const [key, sourceCode] of Object.entries(sourceObj)) { 10 | if (typeof sourceCode != 'string') { 11 | throw new TypeError('sanity check failed: expected string'); 12 | } 13 | 14 | const interop = ` 15 | globalThis.describe = describe; 16 | globalThis.it = it; 17 | globalThis.it.only = (...args) => it(args[0], { only: true }, args[1]); 18 | 19 | ${sourceCode} 20 | `; 21 | 22 | sourceObjWithInterop[key as keyof typeof sourceObj] = { 23 | esm: ` 24 | import { describe, it } from 'node:test'; 25 | 26 | ${interop} 27 | `, 28 | cjs: ` 29 | const { describe, it } = require('node:test'); 30 | 31 | ${interop} 32 | ` 33 | }; 34 | } 35 | 36 | return sourceObjWithInterop; 37 | } 38 | 39 | export function withJasmineInterop( 40 | sourceObj: FrameworksUnderTest[number]['tests'][number]['source'] 41 | ) { 42 | const sourceObjWithInterop = {} as Writable; 43 | 44 | for (const [key, sourceCode] of Object.entries(sourceObj)) { 45 | if (typeof sourceCode != 'string') { 46 | throw new TypeError('sanity check failed: expected string'); 47 | } 48 | 49 | sourceObjWithInterop[key as keyof typeof sourceObj] = ` 50 | globalThis.it.skip = globalThis.xit; 51 | globalThis.it.only = globalThis.fit; 52 | 53 | ${sourceCode} 54 | `; 55 | } 56 | 57 | return sourceObjWithInterop; 58 | } 59 | -------------------------------------------------------------------------------- /test/unit-formatters-prettier.test.ts: -------------------------------------------------------------------------------- 1 | import os from 'node:os'; 2 | import path from 'node:path'; 3 | 4 | import prettier from 'prettier'; 5 | 6 | import { prettierFormatter } from '../src/formatters/prettier'; 7 | 8 | import type { AnyFunction } from '@xunnamius/jest-types'; 9 | 10 | type SpiedFunction = jest.SpyInstance< 11 | ReturnType, 12 | Parameters 13 | >; 14 | 15 | let prettierSpy: SpiedFunction; 16 | 17 | beforeEach(() => { 18 | prettierSpy = jest.spyOn(prettier, 'format'); 19 | }); 20 | 21 | it('uses default prettier options when no user-supplied config is available', () => { 22 | expect.hasAssertions(); 23 | 24 | const result = prettierFormatter(` var a = 'hi' `, { cwd: os.tmpdir() }); 25 | expect(result).toBe('var a = "hi";\n'); 26 | }); 27 | 28 | it('uses user-supplied prettier config at project root if available (found starting at cwd)', () => { 29 | expect.hasAssertions(); 30 | 31 | const result = prettierFormatter(`var a = "hi";`); 32 | expect(result).toBe(`var a = 'hi';\n`); 33 | }); 34 | 35 | it('treats deprecated `filename` option as if it were `filepath`', () => { 36 | expect.hasAssertions(); 37 | 38 | const expectedFilename = path.join(__dirname, 'fake.js'); 39 | prettierFormatter(` var a = 'hi' `, { filename: expectedFilename }); 40 | 41 | expect(prettierSpy.mock.calls).toMatchObject([ 42 | [expect.any(String), expect.objectContaining({ filepath: expectedFilename })] 43 | ]); 44 | }); 45 | 46 | it('treats deprecated `config` option as if it were `prettierOptions`', () => { 47 | expect.hasAssertions(); 48 | 49 | const expectedConfig = { endOfLine: 'crlf' } as const; 50 | prettierFormatter(` var a = 'hi' `, { config: expectedConfig }); 51 | 52 | expect(prettierSpy.mock.calls).toMatchObject([ 53 | [expect.any(String), expect.objectContaining(expectedConfig)] 54 | ]); 55 | }); 56 | -------------------------------------------------------------------------------- /test/unit-index.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint jest/require-hook: ["error", { "allowedFunctionCalls": ["pluginTesterAsDefault","pluginTester"] }] */ 2 | 3 | import pluginTesterAsDefault, { 4 | prettierFormatter, 5 | unstringSnapshotSerializer, 6 | pluginTester, 7 | runPluginUnderTestHere, 8 | runPresetUnderTestHere 9 | } from '../src/index'; 10 | 11 | test('prettierFormatter is exported', () => { 12 | expect.hasAssertions(); 13 | expect(typeof prettierFormatter).toBe('function'); 14 | }); 15 | 16 | test('unstringSnapshotSerializer is exported', () => { 17 | expect.hasAssertions(); 18 | expect(unstringSnapshotSerializer).toHaveProperty('test'); 19 | expect(unstringSnapshotSerializer).toHaveProperty('print'); 20 | }); 21 | 22 | test('the default export and the named export point to the same function', () => { 23 | expect.hasAssertions(); 24 | expect(pluginTester).toBe(pluginTesterAsDefault); 25 | }); 26 | 27 | test('runPluginUnderTestHere is exported', () => { 28 | expect.hasAssertions(); 29 | expect(typeof runPluginUnderTestHere).toBe('symbol'); 30 | }); 31 | 32 | test('runPresetUnderTestHere is exported', () => { 33 | expect.hasAssertions(); 34 | expect(typeof runPresetUnderTestHere).toBe('symbol'); 35 | }); 36 | 37 | const uglyTest = `var output = paragraph + "one"+\n\n'paragraph' + \`\\two\``; 38 | 39 | pluginTesterAsDefault({ 40 | pluginName: 'captains-log', 41 | plugin: () => ({ name: 'captains-log', visitor: {} }), 42 | tests: [ 43 | // ? Test that prettierFormatter is the default `formatResult` function 44 | { code: uglyTest, output: prettierFormatter(uglyTest) }, 45 | // ? Test that unstringSnapshotSerializer is the active snapshot serializer 46 | // ! Requires manual inspection of snapshot 47 | { code: uglyTest, snapshot: true } 48 | ] 49 | }); 50 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["**/*", "**/.*"], 4 | "exclude": ["test/fixtures", "test/__fixtures__", "test/__snapshots__"] 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true, 5 | "alwaysStrict": true, 6 | "baseUrl": ".", 7 | "checkJs": false, 8 | "declaration": true, 9 | "esModuleInterop": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "incremental": true, 12 | "inlineSourceMap": true, 13 | "isolatedModules": true, 14 | "lib": ["ESNext"], 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "noEmit": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "paths": {}, 21 | "resolveJsonModule": true, 22 | "skipLibCheck": true, 23 | "strict": true, 24 | "target": "esnext" 25 | }, 26 | "exclude": ["node_modules"], 27 | "include": ["types/**/*", "src/**/*", "test/**/*"] 28 | } 29 | -------------------------------------------------------------------------------- /tsconfig.lint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["types/**/*", "src/**/*", "test/**/*"], 4 | "exclude": ["test/fixtures", "test/__fixtures__", "test/__snapshots__"] 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.types.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": false, 4 | "checkJs": false, 5 | "declaration": true, 6 | "emitDeclarationOnly": true, 7 | "isolatedModules": false, 8 | "noEmit": false, 9 | "outDir": "dist", 10 | "rootDir": "./src" 11 | }, 12 | "extends": "./tsconfig.json", 13 | "include": ["types/**/*", "src/**/*"] 14 | } 15 | -------------------------------------------------------------------------------- /types/unique-filename.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'unique-filename' { 2 | export default function ( 3 | directory: string, 4 | filePrefix?: string, 5 | uniqStr?: string 6 | ): string; 7 | } 8 | --------------------------------------------------------------------------------