{"id":13656622,"url":"https://github.com/babel-utils/babel-plugin-tester","last_synced_at":"2025-05-16T03:06:05.704Z","repository":{"id":50793825,"uuid":"91477903","full_name":"babel-utils/babel-plugin-tester","owner":"babel-utils","description":"🔌 Utilities for easy feature-complete testing of babel plugins and presets","archived":false,"fork":false,"pushed_at":"2024-06-05T16:25:05.000Z","size":3101,"stargazers_count":270,"open_issues_count":6,"forks_count":40,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-29T15:18:19.349Z","etag":null,"topics":["babel","jasmine","javascript","jest","mocha","node-test","testing","typescript"],"latest_commit_sha":null,"homepage":"http://npm.im/babel-plugin-tester","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/babel-utils.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-16T16:03:23.000Z","updated_at":"2024-08-23T00:17:00.000Z","dependencies_parsed_at":"2024-01-18T14:38:28.790Z","dependency_job_id":"64089cb3-b888-4ffd-a791-7f80e7d34b61","html_url":"https://github.com/babel-utils/babel-plugin-tester","commit_stats":{"total_commits":305,"total_committers":28,"mean_commits":"10.892857142857142","dds":"0.29508196721311475","last_synced_commit":"6ba536698834b206acae4d90f324e394a3a47989"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/babel-utils%2Fbabel-plugin-tester","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/babel-utils%2Fbabel-plugin-tester/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/babel-utils%2Fbabel-plugin-tester/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/babel-utils%2Fbabel-plugin-tester/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/babel-utils","download_url":"https://codeload.github.com/babel-utils/babel-plugin-tester/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254459088,"owners_count":22074605,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["babel","jasmine","javascript","jest","mocha","node-test","testing","typescript"],"created_at":"2024-08-02T05:00:26.113Z","updated_at":"2025-05-16T03:06:00.696Z","avatar_url":"https://github.com/babel-utils.png","language":"TypeScript","readme":"\u003c!-- symbiote-template-region-start 1 --\u003e\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n  \u003cimg width=\"300\" src=\"./logo.png\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003c!-- symbiote-template-region-end --\u003e\nUtilities for testing babel plugins 🧪\n\u003c!-- symbiote-template-region-start 2 --\u003e\n\u003c/p\u003e\n\n\u003chr /\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![Black Lives Matter!][x-badge-blm-image]][x-badge-blm-link]\n[![Last commit timestamp][x-badge-lastcommit-image]][x-badge-repo-link]\n[![Codecov][x-badge-codecov-image]][x-badge-codecov-link]\n[![Source license][x-badge-license-image]][x-badge-license-link]\n[![Uses Semantic Release!][x-badge-semanticrelease-image]][x-badge-semanticrelease-link]\n\n[![NPM version][x-badge-npm-image]][x-badge-npm-link]\n[![Monthly Downloads][x-badge-downloads-image]][x-badge-npm-link]\n\n\u003c/div\u003e\n\n\u003cbr /\u003e\n\n# babel-plugin-tester\n\n\u003c!-- symbiote-template-region-end --\u003e\n\nThis is a fairly simple abstraction to help you write tests for your babel\nplugin or preset. It was built to work with [Jest][1], but most of the\nfunctionality will work with [Mocha][2], [Jasmine][3], [`node:test`][4],\n[Vitest][5], and any other test runner that defines standard `describe` and `it`\nglobals with async support (see [appendix][6]).\n\nThis package is tested on both Windows and nix (Ubuntu) environments.\n\n\u003c!-- symbiote-template-region-start 3 --\u003e\n\n---\n\n\u003c!-- remark-ignore-start --\u003e\n\u003c!-- symbiote-template-region-end --\u003e\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Install](#install)\n  - [`babel-plugin-tester@11`](#babel-plugin-tester11)\n  - [`babel-plugin-tester@12`](#babel-plugin-tester12)\n- [Usage](#usage)\n  - [Import](#import)\n  - [Invoke](#invoke)\n  - [Execute](#execute)\n  - [Configure](#configure)\n- [Examples](#examples)\n  - [Simple Example](#simple-example)\n  - [Full Example](#full-example)\n  - [Fixtures Examples](#fixtures-examples)\n- [Appendix](#appendix)\n  - [Testing Framework Compatibility](#testing-framework-compatibility)\n  - [Using Babel for Configuration Loading](#using-babel-for-configuration-loading)\n  - [`pluginName` Inference Caveat](#pluginname-inference-caveat)\n  - [Custom Snapshot Serialization](#custom-snapshot-serialization)\n  - [Formatting Output with Prettier](#formatting-output-with-prettier)\n  - [Built-In Debugging Support](#built-in-debugging-support)\n  - [`TEST_ONLY`/`TEST_NUM_ONLY` and `TEST_SKIP`/`TEST_NUM_SKIP` Environment Variables](#test_onlytest_num_only-and-test_skiptest_num_skip-environment-variables)\n  - [`setup` and `teardown` Run Order](#setup-and-teardown-run-order)\n  - [Published Package Details](#published-package-details)\n  - [License](#license)\n- [Contributing and Support](#contributing-and-support)\n  - [Inspiration](#inspiration)\n  - [Contributors](#contributors)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- symbiote-template-region-start 4 --\u003e\n\u003c!-- remark-ignore-end --\u003e\n\n\u003cbr /\u003e\n\n## Install\n\n\u003c!-- symbiote-template-region-end --\u003e\n\nCurrently, babel-plugin-tester comes in two flavors:\n\n### `babel-plugin-tester@11`\n\n```shell\nnpm install --save-dev babel-plugin-tester\n# Alternatively:\n#npm install --save-dev babel-plugin-tester@11\n```\n\nThis version of babel-plugin-tester:\n\n- Has a minimum Node version of `18.19.0`.\n\n- Optionally works with `jest@\u003c=29` (as an optional peer dependency).\n\n- Works with `prettier@2` (as a dependency).\n\n### `babel-plugin-tester@12`\n\n```shell\nnpm install --save-dev babel-plugin-tester@12.0.0-canary.2\n# May require --force in some situations:\n#npm install --save-dev babel-plugin-tester@12.0.0-canary.2 jest-extended\n#npm install --save-dev --force jest@30.0.0-alpha.6\n```\n\n\u003e \\[!TIP]\n\u003e\n\u003e Check [the registry][7] for the latest canary version number.\n\nThis version of babel-plugin-tester:\n\n- Technically has a minimum Node version of `20.18.0`, but likely works with\n  `node@18`.\n\n- Optionally works with `jest@\u003e=30` (as an optional peer dependency).\n\n\u003e \\[!CAUTION]\n\u003e\n\u003e You may need `--force` (i.e. `npm install ... --force`) if your project\n\u003e depends on Jest ecosystem packages that don't yet recognize `jest@\u003e=30`, such\n\u003e as `jest-extended@\u003c=4.0.2`.\n\n- Works with `prettier@3` (as a dependency).\n\n- Is stable and fully tested (despite the \"canary\" and \"prerelease\" monikers)\n  but cannot be released until `jest@30` is released.\n\n## Usage\n\nTo use babel-plugin-tester:\n\n1. Import babel-plugin-tester into your test file.\n2. Invoke `pluginTester` in your test file.\n3. Execute your test file.\n\n### Import\n\nESM:\n\n```javascript\nimport { pluginTester } from 'babel-plugin-tester';\n```\n\nCJS:\n\n```javascript\nconst { pluginTester } = require('babel-plugin-tester');\n```\n\n### Invoke\n\n```javascript\n/* file: test/unit.test.js */\n\nimport { pluginTester } from 'babel-plugin-tester';\nimport yourPlugin from 'universe:your-plugin';\n\npluginTester({\n  plugin: yourPlugin,\n  tests: {\n    /* Your test objects */\n  }\n});\n```\n\n\u003e \\[!TIP]\n\u003e\n\u003e Note how `pluginTester` does not appear inside any `test`/`it` block nor\n\u003e within any [hook functions][8]. For advanced use cases, `pluginTester` may\n\u003e appear within one or more `describe` blocks, though this is discouraged.\n\n### Execute\n\nIn your terminal of choice:\n\n```shell\n# Prettier@3 requires --experimental-vm-modules for older Node versions\nNODE_OPTIONS='--no-warnings --experimental-vm-modules' npx jest\n```\n\n### Configure\n\nThis section lists the options you can pass to babel-plugin-tester. They are all\noptional with respect to the following:\n\n- When testing a preset, the [`preset`][9] option is required.\n- When testing a plugin, the [`plugin`][10] option is required.\n- You must test either a preset or a plugin.\n- You cannot use preset-specific options ([`preset`][9], [`presetName`][11],\n  [`presetOptions`][12]) and plugin-specific options ([`plugin`][10],\n  [`pluginName`][13], [`pluginOptions`][14]) at the same time.\n\n#### `plugin`\n\nThis is used to provide the babel plugin under test. For example:\n\n```javascript\n/* file: test/unit.test.js */\n\nimport { pluginTester } from 'babel-plugin-tester';\nimport identifierReversePlugin from 'universe:identifier-reverse-plugin';\n\npluginTester({\n  plugin: identifierReversePlugin,\n  tests: {\n    /* Your test objects */\n  }\n});\n\n/* file: src/identifier-reverse-plugin.js */\n\n// Normally you would import this from your plugin module\nfunction identifierReversePlugin() {\n  return {\n    name: 'identifier reverse',\n    visitor: {\n      Identifier(idPath) {\n        idPath.node.name = idPath.node.name.split('').reverse().join('');\n      }\n    }\n  };\n}\n```\n\n#### `pluginName`\n\nThis is used as the [describe block name][15] and in your [tests' names][16]. If\n`pluginName` can be inferred from the [`plugin`][10]'s [name][17], then it will\nbe and you do not need to provide this option. If it cannot be inferred for\nwhatever reason, `pluginName` defaults to `\"unknown plugin\"`.\n\nNote that there is a small [caveat][18] when relying on `pluginName` inference.\n\n#### `pluginOptions`\n\nThis is used to pass options into your plugin at transform time. If provided,\nthe object will be [`lodash.mergeWith`][lodash.mergewith]'d with each [test\nobject's `pluginOptions`][19]/[fixture's `pluginOptions`][20], with the latter\ntaking precedence. Note that arrays will be concatenated and explicitly\nundefined values will unset previously defined values during merging.\n\n#### `preset`\n\nThis is used to provide the babel preset under test. For example:\n\n```javascript\n/* file: cool-new-babel-preset.test.js */\n\nimport path from 'node:path';\nimport { pluginTester } from 'babel-plugin-tester';\nimport coolNewBabelPreset from './cool-new-babel-preset.js';\n\npluginTester({\n  preset: coolNewBabelPreset,\n  // A path to a directory containing your test fixtures\n  fixtures: path.join(__dirname, 'fixtures')\n});\n\n/* file: cool-new-babel-preset.js */\n\nfunction identifierReversePlugin() {\n  return {\n    name: 'identifier reverse',\n    visitor: {\n      Identifier(idPath) {\n        idPath.node.name = idPath.node.name.split('').reverse().join('');\n      }\n    }\n  };\n}\n\nfunction identifierAppendPlugin() {\n  return {\n    name: 'identifier append',\n    visitor: {\n      Identifier(idPath) {\n        idPath.node.name = `${idPath.node.name}_appended`;\n      }\n    }\n  };\n}\n\nexport function coolNewBabelPreset() {\n  return { plugins: [identifierReversePlugin, identifierAppendPlugin] };\n}\n```\n\n#### `presetName`\n\nThis is used as the [describe block name][15] and in your [tests' names][16].\nDefaults to `\"unknown preset\"`.\n\n#### `presetOptions`\n\nThis is used to pass options into your preset at transform time. If provided,\nthe object will be [`lodash.mergeWith`][lodash.mergewith]'d with each [test\nobject's `presetOptions`][21]/[fixture's `presetOptions`][22], with the latter\ntaking precedence. Note that arrays will be concatenated and explicitly\nundefined values will unset previously defined values during merging.\n\n#### `babel`\n\nThis is used to provide your own implementation of babel. This is particularly\nuseful if you want to use a different version of babel than what's required by\nthis package.\n\n#### `babelOptions`\n\nThis is used to configure babel. If provided, the object will be\n[`lodash.mergeWith`][lodash.mergewith]'d with the [defaults][23] and each [test\nobject's `babelOptions`][24]/[fixture's `babelOptions`][25], with the latter\ntaking precedence.\n\nBe aware that arrays will be concatenated and explicitly undefined values will\nunset previously defined values during merging.\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e For `babel-plugin-tester@\u003e=12`, [duplicate entries][26] in\n\u003e [`babelOptions.plugins`][27] and [`babelOptions.presets`][28] are reduced,\n\u003e with latter entries _completely overwriting_ any that came before. In other\n\u003e words: the last duplicate plugin or preset configuration wins. **They are not\n\u003e merged.** This makes it easy to provide an alternative one-off configuration\n\u003e for a plugin or preset that is also used elsewhere, such as a project's root\n\u003e `babel.config.js` file.\n\u003e\n\u003e Attempting the same with `babel-plugin-tester@\u003c12` will cause babel [to\n\u003e throw][26] since duplicate entries are technically not allowed.\n\nAlso note that [`babelOptions.babelrc`][29] and [`babelOptions.configFile`][30]\nare set to `false` by default, which disables automatic babel configuration\nloading. [This can be re-enabled if desired][31].\n\nTo simply reuse your project's [`babel.config.js`][32] or some other\nconfiguration file, set `babelOptions` like so:\n\n```javascript\n// file: /repos/my-project/tests/unit-plugin.test.ts\n\nimport path from 'node:path';\nimport { pluginTester } from 'babel-plugin-tester';\n\npluginTester({\n  plugin: yourPlugin,\n  // ...\n  babelOptions: require(path.join('..', 'babel.config.js')),\n  // ...\n  tests: {\n    /* Your test objects */\n  }\n});\n```\n\n##### Custom Plugin and Preset Run Order\n\nBy default, when you include a custom list of [plugins][33] or [presets][34] in\n`babelOptions`, the plugin or preset under test will always be the final plugin\nor preset to run.\n\nFor example, consider the `myPlugin` plugin:\n\n```javascript\nimport { pluginTester } from 'babel-plugin-tester';\n\npluginTester({\n  plugin: myPlugin,\n  pluginName: 'my-plugin',\n  babelOptions: {\n    plugins: [\n      ['@babel/plugin-syntax-decorators', { legacy: true }],\n      ['@babel/plugin-proposal-class-properties', { loose: true }]\n    ]\n  }\n});\n```\n\nBy default, `myPlugin` will be invoked _after_ @babel/plugin-syntax-decorators\nand @babel/plugin-proposal-class-properties (i.e. `myPlugin` is _appended_ by\ndefault).\n\nIt is possible to specify a custom ordering using the exported\n`runPluginUnderTestHere` symbol. For instance, to run `myPlugin` _after_\n@babel/plugin-syntax-decorators but _before_\n@babel/plugin-proposal-class-properties:\n\n```javascript\nimport { pluginTester, runPluginUnderTestHere } from 'babel-plugin-tester';\n\npluginTester({\n  plugin: myPlugin,\n  pluginName: 'my-plugin',\n  babelOptions: {\n    plugins: [\n      ['@babel/plugin-syntax-decorators', { legacy: true }],\n      runPluginUnderTestHere,\n      ['@babel/plugin-proposal-class-properties', { loose: true }]\n    ]\n  }\n});\n```\n\nOr to run `myPlugin` _before_ both @babel/plugin-syntax-decorators and\n@babel/plugin-proposal-class-properties:\n\n```javascript\nimport { pluginTester, runPluginUnderTestHere } from 'babel-plugin-tester';\n\npluginTester({\n  plugin: myPlugin,\n  pluginName: 'my-plugin',\n  babelOptions: {\n    plugins: [\n      runPluginUnderTestHere,\n      ['@babel/plugin-syntax-decorators', { legacy: true }],\n      ['@babel/plugin-proposal-class-properties', { loose: true }]\n    ]\n  }\n});\n```\n\nThe same can be done when testing presets. Note that `myPreset` is normally\n_prepended_ by default since, unlike plugins, [presets are run in reverse\norder][35]:\n\n```javascript\nimport { pluginTester, runPresetUnderTestHere } from 'babel-plugin-tester';\n\npluginTester({\n  preset: myPreset,\n  presetName: 'my-preset',\n  babelOptions: {\n    presets: [\n      '@babel/preset-typescript',\n      ['@babel/preset-react', { pragma: 'dom' }],\n      runPresetUnderTestHere\n    ]\n  }\n});\n```\n\nIn this example, `myPreset` will run first instead of last.\n\n#### `title`\n\nThis is used to specify a custom title for the two top-level [describe\nblocks][15], the first enclosing all [tests][36] (i.e. `describe(title, ...)`)\nand the second enclosing all [fixtures][37] (i.e.\n``describe(`${title} fixtures`, ...)``).\n\nExplicitly setting this option will override any defaults or inferred values.\nSet to `false` to prevent the creation of these enclosing describe blocks.\nOtherwise, the title defaults to using [`pluginName`][13]/[`presetName`][11].\n\n#### `filepath`\n\nThis is used to resolve relative paths provided by the [`fixtures`][37] option;\nthe test object properties [`codeFixture`][38], [`outputFixture`][39], and\n[`execFixture`][40]; and [during configuration resolution for prettier][41].\nThat is: if the aforesaid properties are not absolute paths, they will be\n[`path.join`][42]'d with the [directory name][43] of `filepath`.\n\n`filepath` is also passed to `formatResult` if a more specific path is not\navailable, and it is used as the default value for `babelOptions.filename` in\n[test objects][44].\n\nThis option defaults to the absolute path of the file that [invoked the\n`pluginTester` function][45].\n\n\u003e \\[!NOTE]\n\u003e\n\u003e For backwards compatibility reasons, `filepath` is synonymous with `filename`.\n\u003e They can be used interchangeably, though care must be taken not to confuse the\n\u003e babel-plugin-tester option `filename` with `babelOptions.filename`. They are\n\u003e NOT the same!\n\n#### `endOfLine`\n\nThis is used to control which line endings both the actual output from babel and\nthe expected output will be converted to. Defaults to `\"lf\"`.\n\n| Options      | Description                             |\n| ------------ | --------------------------------------- |\n| `\"lf\"`       | Use Unix-style line endings             |\n| `\"crlf\"`     | Use Windows-style line endings          |\n| `\"auto\"`     | Use the system default line endings     |\n| `\"preserve\"` | Use the line endings from the input     |\n| `false`      | Disable line ending conversion entirely |\n\n\u003e \\[!NOTE]\n\u003e\n\u003e When disabling line ending conversion, note that [Babel will always output\n\u003e LF][46] even if the input is CRLF.\n\n#### `setup`\n\nThis function will be run before every test runs, including fixtures. It can\nreturn a function which will be treated as a [`teardown`][47] function. It can\nalso return a promise. If that promise resolves to a function, that will be\ntreated as a [`teardown`][47] function.\n\nSee [here][48] for the complete run order.\n\n#### `teardown`\n\nThis function will be run after every test runs, including fixtures. You can\ndefine this via `teardown` or you can return it from the [`setup`][49] function.\nThis can likewise return a promise if it is asynchronous.\n\nThis function, if provided, will be run _after_ any teardown function returned\nby [`setup`][49]. See [here][48] for the complete run order.\n\n#### `formatResult`\n\nThis function is used to format all babel outputs, and defaults to a function\nthat invokes [prettier][50]. If a prettier configuration file is [found][51],\nthen that will be used. Otherwise, prettier will use its own default\nconfiguration.\n\nYou can also [override or entirely disable formatting][41].\n\n#### `snapshot`\n\nEquivalent to [`snapshot`][52] but applied globally across all [test\nobjects][44].\n\n#### `fixtureOutputName`\n\nEquivalent to [`fixtureOutputName`][53] but applied globally across all\n[fixtures][37].\n\n#### `fixtureOutputExt`\n\nEquivalent to [`fixtureOutputExt`][54] but applied globally across all\n[fixtures][37].\n\n#### `titleNumbering`\n\nDetermines which test titles are prefixed with a number when registering [test\nblocks][16] (e.g. `` `1. ${title}` ``, `` `2. ${title}` ``, etc). Defaults to\n`\"all\"`.\n\n| Options           | Description                                         |\n| ----------------- | --------------------------------------------------- |\n| `\"all\"`           | All test object and fixtures tests will be numbered |\n| `\"tests-only\"`    | Only test object tests will be numbered             |\n| `\"fixtures-only\"` | Only fixtures tests will be numbered                |\n| `false`           | Disable automatic numbering in titles entirely      |\n\n#### `restartTitleNumbering`\n\nNormally, multiple [invocations][45] of babel-plugin-tester in the same test\nfile will share the same [test title numbering][55]. For example:\n\n```javascript\n/* file: test/unit.test.js */\n\nimport { pluginTester } from 'babel-plugin-tester';\nimport yourPlugin from 'universe:your-plugin';\n\npluginTester({\n  plugin: yourPlugin,\n  tests: { 'test one': testOne, 'test two': testTwo }\n});\n\npluginTester({\n  plugin: yourPlugin,\n  tests: { 'test one': testOne, 'test x': testTwo }\n});\n\npluginTester({\n  plugin: yourPlugin,\n  tests: { 'test five': testOne }\n});\n```\n\nWill result in [test blocks][16] with names like:\n\n```text\n1. Test one\n2. Test two\n3. Test one\n4. Test x\n5. Test five\n```\n\nHowever, setting this option to `true` will restart the numbering:\n\n```javascript\n/* file: test/unit.test.js */\n\nimport { pluginTester } from 'babel-plugin-tester';\nimport yourPlugin from 'universe:your-plugin';\n\npluginTester({\n  plugin: yourPlugin,\n  tests: { 'test one': testOne, 'test two': testTwo }\n});\n\npluginTester({\n  plugin: yourPlugin,\n  restartTitleNumbering: true,\n  tests: { 'test one': testOne, 'test x': testTwo }\n});\n\npluginTester({\n  plugin: yourPlugin,\n  tests: { 'test five': testOne }\n});\n```\n\nWhich will result in [test blocks][16] with names like:\n\n```text\n1. Test one\n2. Test two\n1. Test one\n2. Test x\n3. Test five\n```\n\nThis option is `false` by default.\n\n#### `fixtures`\n\nThere are two ways to create tests: using the [`tests`][36] option to provide\none or more [test objects][44] or using the `fixtures` option described here.\nBoth can be used simultaneously.\n\nThe `fixtures` option must be a path to a directory with a structure similar to\nthe following:\n\n```text\nfixtures\n├── first-test         # test title will be: \"1. first test\"\n│   ├── code.js        # required\n│   └── output.js      # required (unless using the `throws` option)\n├── second-test        # test title will be: \"2. second test\"\n│   ├── .babelrc.js    # optional\n│   ├── options.json   # optional\n│   ├── code.ts        # required (other file extensions are allowed too)\n│   └── output.js      # required (unless using the `throws` option)\n└── nested\n    ├── options.json   # optional\n    ├── third-test     # test title will be: \"3. nested \u003e third test\"\n    │   ├── code.mjs   # required (other file extensions are allowed too)\n    │   ├── output.js  # required (unless using the `throws` option)\n    │   └── options.js # optional (overrides props in nested/options.json)\n    └── x-fourth-test  # test title will be: \"4. nested \u003e x fourth test\"\n        └── exec.js    # required (alternative to code/output structure)\n```\n\n\u003e \\[!TIP]\n\u003e\n\u003e `.babelrc`, `.babelrc.json`, `.babelrc.js`, `.babelrc.cjs`, and `.babelrc.mjs`\n\u003e config files in fixture directories are supported out-of-the-box.\n\nAssuming the `fixtures` directory is in the same directory as your test file,\nyou could use it with the following configuration:\n\n```javascript\npluginTester({\n  plugin,\n  fixtures: path.join(__dirname, 'fixtures')\n});\n```\n\n\u003e \\[!NOTE]\n\u003e\n\u003e If `fixtures` is not an absolute path, it will be [`path.join`][42]'d with the\n\u003e [directory name][43] of [`filepath`][56].\n\nAnd it would run four tests, one for each directory in `fixtures` containing a\nfile starting with \"code\" or \"exec\".\n\n##### `code.js`\n\nThis file's contents will be used as the source code input into babel at\ntransform time. Any file extension can be used, even a multi-part extension\n(e.g. `.test.js` in `code.test.js`) as long as the file name starts with\n`code.`; the [expected output file][57] will have the same file extension suffix\n(i.e. `.js` in `code.test.js`) as this file unless changed with the\n[`fixtureOutputExt`][54] option.\n\nAfter being transformed by babel, the resulting output will have whitespace\ntrimmed, line endings [converted][58], and then get [formatted by prettier][41].\n\nNote that this file cannot appear in the same directory as [`exec.js`][59]. If\nmore than one `code.*` file exists in a directory, the first one will be used\nand the rest will be silently ignored.\n\n##### `output.js`\n\nThis file, if provided, will have its contents compared with babel's output,\nwhich is [`code.js`][60] transformed by babel and [formatted with prettier][41].\nIf this file is missing and neither [`throws`][61] nor [`exec.js`][59] are being\nused, this file will be automatically generated from babel's output.\nAdditionally, the name and extension of this file can be changed with the\n[`fixtureOutputName`][53] and [`fixtureOutputExt`][54] options.\n\nBefore being compared to babel's output, this file's contents will have\nwhitespace trimmed and line endings [converted][58].\n\nNote that this file cannot appear in the same directory as [`exec.js`][59].\n\n##### `exec.js`\n\nThis file's contents will be used as the input into babel at transform time just\nlike the [`code.js`][60] file, except the output will be _evaluated_ in the\n[same _CJS_ context][62] as the test runner itself, meaning it supports features\nlike a/sync IIFEs, debugging breakpoints (!), and has access to mocked modules,\n`expect`, `require`, `__dirname` and `__filename` (derived from this file's\npath), and other globals/features provided by your test framework. However, the\ncontext does not support _`import`, top-level await, or any other ESM syntax_.\nHence, while any file extension can be used (e.g. `.ts`, `.vue`, `.jsx`), this\nfile will always be evaluated as CJS.\n\nThe test will always pass unless an exception is thrown (e.g. when an `expect()`\nfails).\n\nUse this to make advanced assertions on the output. For example, to test that\n[babel-plugin-proposal-throw-expressions][63] actually throws, your `exec.js`\nfile might contain:\n\n```javascript\nexpect(() =\u003e throw new Error('throw expression')).toThrow('throw expression');\n```\n\n\u003e \\[!CAUTION]\n\u003e\n\u003e Keep in mind that, despite sharing a global context, execution will occur in a\n\u003e [separate realm][64], which means native/intrinsic types will be different.\n\u003e This can lead to unexpectedly failing tests. For example:\n\u003e\n\u003e ```javascript\n\u003e expect(require(`${__dirname}/imported-file.json`)).toStrictEqual({\n\u003e   data: 'imported'\n\u003e });\n\u003e ```\n\u003e\n\u003e This may fail in some test frameworks with the message \"serializes to the same\n\u003e string\". This is because the former object's `Object` prototype comes from a\n\u003e different realm than the second object's `Object` prototype, meaning the two\n\u003e objects are not technically _strictly_ equal. However, something like the\n\u003e following, which creates two objects in the same realm, will pass:\n\u003e\n\u003e ```javascript\n\u003e expect(\n\u003e   Object.fromEntries(\n\u003e     Object.entries(require(`${__dirname}/imported-file.json`))\n\u003e   )\n\u003e ).toStrictEqual({ data: 'imported' });\n\u003e ```\n\u003e\n\u003e Or use `JSON.stringify` + `toBe` (or your testing framework's equivalent):\n\u003e\n\u003e ```javascript\n\u003e expect(JSON.stringify(require(`${__dirname}/imported-file.json`))).toBe(\n\u003e   JSON.stringify({ data: 'imported' })\n\u003e );\n\u003e ```\n\u003e\n\u003e Or use `isEqual` (or your testing framework's equivalent):\n\u003e\n\u003e ```javascript\n\u003e expect(require(`${__dirname}/imported-file.json`)).toEqual({\n\u003e   data: 'imported'\n\u003e });\n\u003e ```\n\nAfter being transformed by babel but before being evaluated, the babel output\nwill have whitespace trimmed, line endings [converted][58], and then get\n[formatted by prettier][41].\n\nNote that this file cannot appear in the same directory as [`code.js`][60] or\n[`output.js`][57]. If more than one `exec.*` file exists in a directory, the\nfirst one will be used and the rest will be silently ignored.\n\n##### `options.json` (Or `options.js`)\n\nFor each fixture, the contents of the entirely optional `options.json` file are\n[`lodash.mergeWith`][lodash.mergewith]'d with the options provided to\nbabel-plugin-tester, with the former taking precedence. Note that arrays will be\nconcatenated and explicitly undefined values will unset previously defined\nvalues during merging.\n\nFor added flexibility, `options.json` can be specified as `options.js` instead\nso long as a JSON object is exported via [`module.exports`][65]. If both files\nexist in the same directory, `options.js` will take precedence and\n`options.json` will be ignored entirely.\n\nFixtures support deeply nested directory structures as well as shared or \"root\"\n`options.json` files. For example, placing an `options.json` file in the\n`fixtures/nested` directory would make its contents the \"global configuration\"\nfor all fixtures under `fixtures/nested`. That is: each fixture would\n[`lodash.mergeWith`][lodash.mergewith] the options provided to\nbabel-plugin-tester, `fixtures/nested/options.json`, and the contents of their\nlocal `options.json` file as described above.\n\nWhat follows are the properties you may use if you provide an options file, all\nof which are optional:\n\n###### `babelOptions`\n\nThis is used to configure babel. Properties specified here override\n([`lodash.mergeWith`][lodash.mergewith]) those from the [`babelOptions`][66]\noption provided to babel-plugin-tester.\n\nNote that arrays will be concatenated, explicitly undefined values will unset\npreviously defined values, and (as of `babel-plugin-tester@\u003e=12`) duplicate\nplugin/preset configurations will override each other (last configuration wins)\nduring merging.\n\n###### `pluginOptions`\n\nThis is used to pass options into your plugin at transform time. Properties\nspecified here override ([`lodash.mergeWith`][lodash.mergewith]) those from the\n[`pluginOptions`][14] option provided to babel-plugin-tester. Note that arrays\nwill be concatenated and explicitly undefined values will unset previously\ndefined values during merging.\n\nUnlike with babel-plugin-tester's options, you can safely mix plugin-specific\nproperties (like `pluginOptions`) with preset-specific properties (like\n[`presetOptions`][22]) in your options files.\n\n###### `presetOptions`\n\nThis is used to pass options into your preset at transform time. Properties\nspecified here override ([`lodash.mergeWith`][lodash.mergewith]) those from the\n[`presetOptions`][12] option provided to babel-plugin-tester. Note that arrays\nwill be concatenated and explicitly undefined values will unset previously\ndefined values during merging.\n\nUnlike with babel-plugin-tester's options, you can safely mix plugin-specific\nproperties (like [`pluginOptions`][20]) with preset-specific properties (like\n`presetOptions`) in your options files.\n\n###### `title`\n\nIf provided, this will be used as the title of the test. Otherwise, the\ndirectory name will be used as the title by default (with spaces replacing\ndashes).\n\n###### `only`\n\nUse this to run only the specified fixture. Useful while developing to help\nfocus on a small number of fixtures. Can be used in multiple `options.json`\nfiles.\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e Requires [Jest][67], an equivalent interface (like [Vitest][5]), or a\n\u003e manually-defined `it` object exposing an appropriate [`only`][68] method.\n\n###### `skip`\n\nUse this to skip running the specified fixture. Useful for when you are working\non a feature that is not yet supported. Can be used in multiple `options.json`\nfiles.\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e Requires [Jest][67], an equivalent interface (like [Vitest][5]), or a\n\u003e manually-defined `it` object exposing an appropriate [`skip`][69] method.\n\n###### `throws`\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e When using certain values, this property must be used in `options.js` instead\n\u003e of `options.json`.\n\nUse this to assert that a particular `code.js` file should cause babel to throw\nan error during transformation. For example:\n\n```javascript\n{\n  // ...\n  throws: true,\n  throws: 'should have this exact message',\n  throws: /should pass this regex/,\n  throws: SyntaxError, // Should be an instance of this class\n  throws: err =\u003e {\n    if (err instanceof SyntaxError \u0026\u0026 /message/.test(err.message)) {\n      return true; // Test will fail if this function's return value !== true\n    }\n  },\n}\n```\n\n\u003e \\[!CAUTION]\n\u003e\n\u003e Be careful using `instanceof` [across realms][70] as it can lead to [strange\n\u003e behavior][71] with [frontend frames/windows][72] and with tools that rely on\n\u003e [Node's VM module][73] (like Jest).\n\nIf the value of `throws` is a class, that class must [be a subtype of\n`Error`][74] or the behavior of babel-plugin-tester is undefined.\n\nNote that this property cannot be present when using an [`exec.js`][59] or\n[`output.js`][57] file or when using the [`outputRaw`][75] option.\n\n\u003e \\[!NOTE]\n\u003e\n\u003e For backwards compatibility reasons, `throws` is synonymous with `error`. They\n\u003e can be used interchangeably, with `throws` taking precedence.\n\n###### `setup`\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e As it requires a function value, this property must be used in `options.js`\n\u003e instead of `options.json`.\n\nThis function will be run before a particular fixture's tests are run. It can\nreturn a function which will be treated as a [`teardown`][76] function. It can\nalso return a promise. If that promise resolves to a function, that will be\ntreated as a [`teardown`][76] function.\n\nThis function, if provided, will run _after_ any [`setup`][49] function provided\nas a babel-plugin-tester option. See [here][48] for the complete run order.\n\n###### `teardown`\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e As it requires a function value, this property must be used in `options.js`\n\u003e instead of `options.json`.\n\nThis function will be run after a fixture's tests finish running. You can define\nthis via `teardown` or you can return it from the [`setup`][77] function. This\ncan likewise return a promise if it is asynchronous.\n\nThis function, if provided, will be run _after_ any teardown function returned\nby the [`setup`][77] property, both of which will run _before_ any\n[`teardown`][47] function provided as a babel-plugin-tester option. See\n[here][48] for the complete run order.\n\n###### `formatResult`\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e As it requires a function value, this property must be used in `options.js`\n\u003e instead of `options.json`.\n\nThis function is used to format all babel outputs, and defaults to a function\nthat invokes [prettier][50]. If a prettier configuration file is [found][51],\nthen that will be used. Otherwise, prettier will use its own default\nconfiguration.\n\nYou can also [entirely disable formatting][41].\n\nThis will override the [`formatResult`][78] function provided to\nbabel-plugin-tester.\n\n###### `outputRaw`\n\n\u003e \\[!WARNING]\n\u003e\n\u003e This feature is only available in `babel-plugin-tester@\u003e=12`.\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e As it requires a function value, this property must be used in `options.js`\n\u003e instead of `options.json`.\n\nThis option is similar in intent to [`output.js`][57] except it tests against\nthe _entire [`BabelFileResult`][79] object_ returned by [babel's `transform`\nfunction][80] instead of only the `code` property of [`BabelFileResult`][79].\n\n`outputRaw` must be a function with the following signature:\n\n```typescript\noutputRaw: (output: BabelFileResult) =\u003e void\n```\n\nWhere the `output` parameter is an instance of [`BabelFileResult`][79]:\n\n```typescript\ninterface BabelFileResult {\n  ast?: Node | undefined;\n  code?: string | undefined;\n  ignored?: boolean | undefined;\n  map?: object | undefined;\n  metadata?: BabelFileMetadata | undefined;\n}\n```\n\nSo long as the `outputRaw` function does not throw, it will never cause the test\nto fail. On the other hand, if the `outputRaw` function throws, such as when\n`expect(output.metadata).toStrictEqual({ ... })` fails, the test will fail\nregardless of other options.\n\nThe `output` parameter is not trimmed, converted, stripped, or modified at all.\n\nNote that `outputRaw` does not _replace_ [`output.js`][57] etc, it only adds\nadditional (custom) expectations to your test. Further note that this option\n_can_ appear alongside any other [`fixtures`][37] option except [`throws`][81].\n\n###### `fixtureOutputName`\n\nUse this to provide your own fixture output file name. Defaults to `\"output\"`.\n\n###### `fixtureOutputExt`\n\nUse this to provide your own fixture output file extension. Including the\nleading period is optional; that is: if you want `output.jsx`,\n`fixtureOutputExt` can be set to either `\"jsx\"` or `\".jsx\"`. If omitted, the\n[input fixture][60]'s file extension will be used instead.\n\nThis is particularly useful if you are testing TypeScript input.\n\n#### `tests`\n\nThere are two ways to create tests: using the [`fixtures`][37] option that\nleverages the filesystem or using the `tests` option described here. Both can be\nused simultaneously.\n\nUsing the `tests` option, you can provide [test objects][44] describing your\nexpected transformations. You can provide `tests` as an object of test objects\nor an array of test objects. If you provide an object, the object's keys will be\nused as the default title of each test. If you provide an array, each test's\ndefault title will be derived from its index and\n[`pluginName`][13]/[`presetName`][11].\n\nSee [the example][82] for more details.\n\n##### Test Objects\n\nA minimal test object can be:\n\n1. A `string` representing [code][83].\n2. An `object` with a [`code`][83] property.\n\nWhat follows are the properties you may use if you provide an object, most of\nwhich are optional:\n\n###### `babelOptions`\n\nThis is used to configure babel. Properties specified here override\n([`lodash.mergeWith`][lodash.mergewith]) those from the [`babelOptions`][66]\noption provided to babel-plugin-tester.\n\nNote that arrays will be concatenated, explicitly undefined values will unset\npreviously defined values, and (as of `babel-plugin-tester@\u003e=12`) duplicate\nplugin/preset configurations will override each other (last configuration wins)\nduring merging.\n\n###### `pluginOptions`\n\nThis is used to pass options into your plugin at transform time. Properties\nspecified here override ([`lodash.mergeWith`][lodash.mergewith]) those from the\n[`pluginOptions`][14] option provided to babel-plugin-tester. Note that arrays\nwill be concatenated and explicitly undefined values will unset previously\ndefined values during merging.\n\nUnlike with babel-plugin-tester's options, you can safely mix plugin-specific\nproperties (like `pluginOptions`) with preset-specific properties (like\n[`presetOptions`][21]) in your test objects.\n\n###### `presetOptions`\n\nThis is used to pass options into your preset at transform time. Properties\nspecified here override ([`lodash.mergeWith`][lodash.mergewith]) those from the\n[`presetOptions`][12] option provided to babel-plugin-tester. Note that arrays\nwill be concatenated and explicitly undefined values will unset previously\ndefined values during merging.\n\nUnlike with babel-plugin-tester's options, you can safely mix plugin-specific\nproperties (like [`pluginOptions`][19]) with preset-specific properties (like\n`presetOptions`) in your test objects.\n\n###### `title`\n\nIf provided, this will be used as the title of the test. Otherwise, the title\nwill be determined from test object by default.\n\n###### `only`\n\nUse this to run only the specified test. Useful while developing to help focus\non a small number of tests. Can be used on multiple tests.\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e Requires [Jest][67], an equivalent interface (like [Vitest][5]), or a\n\u003e manually-defined `it` object exposing an appropriate [`only`][68] method.\n\n###### `skip`\n\nUse this to skip running the specified test. Useful for when you are working on\na feature that is not yet supported. Can be used on multiple tests.\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e Requires [Jest][67], an equivalent interface (like [Vitest][5]), or a\n\u003e manually-defined `it` object exposing an appropriate [`skip`][69] method.\n\n###### `throws`\n\nUse this to assert that a particular test object should cause babel to throw an\nerror during transformation. For example:\n\n```javascript\n{\n  // ...\n  throws: true,\n  throws: 'should have this exact message',\n  throws: /should pass this regex/,\n  throws: SyntaxError, // Should be an instance of this class\n  throws: err =\u003e {\n    if (err instanceof SyntaxError \u0026\u0026 /message/.test(err.message)) {\n      return true; // Test will fail if this function's return value !== true\n    }\n  },\n}\n```\n\n\u003e \\[!CAUTION]\n\u003e\n\u003e Be careful using `instanceof` [across realms][70] as it can lead to [strange\n\u003e behavior][71] with [frontend frames/windows][72] and with tools that rely on\n\u003e [Node's VM module][73] (like Jest).\n\nIf the value of `throws` is a class, that class must [be a subtype of\n`Error`][74] or the behavior of babel-plugin-tester is undefined.\n\nNote that this property cannot be present when using the [`output`][84],\n[`outputRaw`][85], [`outputFixture`][39], [`exec`][86], [`execFixture`][40], or\n[`snapshot`][52] properties.\n\n\u003e \\[!NOTE]\n\u003e\n\u003e For backwards compatibility reasons, `throws` is synonymous with `error`. They\n\u003e can be used interchangeably, with `throws` taking precedence.\n\n###### `setup`\n\nThis function will be run before a particular test is run. It can return a\nfunction which will be treated as a [`teardown`][87] function. It can also\nreturn a promise. If that promise resolves to a function, that will be treated\nas a [`teardown`][87] function.\n\nThis function, if provided, will run _after_ any [`setup`][49] function provided\nas a babel-plugin-tester option. See [here][48] for the complete run order.\n\n###### `teardown`\n\nThis function will be run after a test finishes running. You can define this via\n`teardown` or you can return it from the [`setup`][88] function. This can\nlikewise return a promise if it is asynchronous.\n\nThis function, if provided, will be run _after_ any teardown function returned\nby the [`setup`][88] property, both of which will run _before_ any\n[`teardown`][47] function provided as a babel-plugin-tester option. See\n[here][48] for the complete run order.\n\n###### `formatResult`\n\nThis function is used to format all babel outputs, and defaults to a function\nthat invokes [prettier][50]. If a prettier configuration file is [found][51],\nthen that will be used. Otherwise, prettier will use its own default\nconfiguration.\n\nYou can also [entirely disable formatting][41].\n\nThis will override the [`formatResult`][78] function provided to\nbabel-plugin-tester.\n\n###### `snapshot`\n\nIf you would prefer to take a snapshot of babel's output rather than compare it\nto something you provide manually, specify `snapshot: true`. This will cause\nbabel-plugin-tester to generate a snapshot containing both the [source code][83]\nand babel's output.\n\nDefaults to `false`.\n\nNote that this property cannot appear in the same test object as the\n[`output`][84], [`outputFixture`][39], [`exec`][86], [`execFixture`][40], or\n[`throws`][81] properties. However, it _can_ be used with [`outputRaw`][85].\n\n\u003e \\[!IMPORTANT]\n\u003e\n\u003e Requires [Jest][67], an [appropriate shim][89] or equivalent interface (like\n\u003e [Vitest][5]), or a manually-defined `expect` object exposing an appropriate\n\u003e [`toMatchSnapshot`][90] method.\n\n###### `code`\n\nThe code that you want babel to transform using your plugin or preset. This must\nbe provided unless you are using the [`codeFixture`][38] or [`exec`][86]\nproperties instead. If you do not provide the [`output`][84] or\n[`outputFixture`][39] properties, and [`snapshot`][52] is not truthy, then the\nassertion is that this code is unchanged by the transformation.\n\nBefore being transformed by babel, any indentation will be stripped as a\nconvenience for template literals. After being transformed, the resulting output\nwill have whitespace trimmed, line endings [converted][58], and then get\n[formatted by prettier][41].\n\nNote that this property cannot appear in the same test object as the\n[`codeFixture`][38], [`exec`][86], or [`execFixture`][40] properties.\n\n###### `output`\n\nThe value of this property will be compared with the output from [babel's\n`transform` function][80].\n\nBefore being compared to babel's output, this value will have whitespace\ntrimmed, line endings [converted][58], and any indentation stripped as a\nconvenience for template literals.\n\nNote that this property cannot appear in the same test object as the\n[`outputFixture`][39], [`exec`][86], [`execFixture`][40], [`throws`][81], or\n[`snapshot`][52] properties. However, it _can_ be used with [`outputRaw`][85].\n\n###### `outputRaw`\n\n\u003e \\[!WARNING]\n\u003e\n\u003e This feature is only available in `babel-plugin-tester@\u003e=12`.\n\nThis property is similar to [`output`][84] and related properties except it\ntests against the _entire [`BabelFileResult`][79] object_ returned by [babel's\n`transform` function][80] instead of only the `code` property of\n[`BabelFileResult`][79].\n\n`outputRaw` must be a function with the following signature:\n\n```typescript\noutputRaw: (output: BabelFileResult) =\u003e void\n```\n\nWhere the `output` parameter is an instance of [`BabelFileResult`][79]:\n\n```typescript\ninterface BabelFileResult {\n  ast?: Node | undefined;\n  code?: string | undefined;\n  ignored?: boolean | undefined;\n  map?: object | undefined;\n  metadata?: BabelFileMetadata | undefined;\n}\n```\n\nSo long as the `outputRaw` function does not throw, this property will never\ncause the test to fail. On the other hand, if the `outputRaw` function throws,\nsuch as when `expect(output.metadata).toStrictEqual({ ... })` fails, the test\nwill fail regardless of other properties.\n\nThe `output` parameter is not trimmed, converted, stripped, or modified at all.\n\nNote that `outputRaw` does not _replace_ [`output`][84] etc, it only adds\nadditional (custom) expectations to your test. Further note that `outputRaw`\n_can_ appear in the same test object as any other property except\n[`throws`][81].\n\n###### `exec`\n\nThe provided source will be transformed just like the [`code`][83] property,\nexcept the output will be _evaluated_ in the [same _CJS_ context][62] as the\ntest runner itself, meaning it supports features like a/sync IIFEs, debugging\nbreakpoints (!), and has access to mocked modules, `expect`, `require`,\n`__dirname` and `__filename` (derived from available path info and falling back\non [`filepath`][56]), and other globals/features provided by your test\nframework. However, the context does not support _`import`, top-level await, or\nany other ESM syntax_. Hence, while any file extension can be used (e.g. `.ts`,\n`.vue`, `.jsx`), this file will always be evaluated as CJS.\n\nThe test will always pass unless an exception is thrown (e.g. when an `expect()`\nfails).\n\nUse this to make advanced assertions on the output. For example, you can test\nthat [babel-plugin-proposal-throw-expressions][63] actually throws using the\nfollowing:\n\n```javascript\n{\n  // ...\n  exec: `\n    expect(() =\u003e throw new Error('throw expression')).toThrow('throw expression');\n  `;\n}\n```\n\n\u003e \\[!CAUTION]\n\u003e\n\u003e Keep in mind that, despite sharing a global context, execution will occur in a\n\u003e [separate realm][64], which means native/intrinsic types will be different.\n\u003e This can lead to unexpectedly failing tests. For example:\n\u003e\n\u003e ```javascript\n\u003e expect(require(`${__dirname}/imported-file.json`)).toStrictEqual({\n\u003e   data: 'imported'\n\u003e });\n\u003e ```\n\u003e\n\u003e This may fail in some test frameworks with the message \"serializes to the same\n\u003e string\". This is because the former object's `Object` prototype comes from a\n\u003e different realm than the second object's `Object` prototype, meaning the two\n\u003e objects are not technically _strictly_ equal. However, something like the\n\u003e following, which creates two objects in the same realm, will pass:\n\u003e\n\u003e ```javascript\n\u003e expect(\n\u003e   Object.fromEntries(\n\u003e     Object.entries(require(`${__dirname}/imported-file.json`))\n\u003e   )\n\u003e ).toStrictEqual({ data: 'imported' });\n\u003e ```\n\u003e\n\u003e Or use `JSON.stringify` + `toBe` (or your testing framework's equivalent):\n\u003e\n\u003e ```javascript\n\u003e expect(JSON.stringify(require(`${__dirname}/imported-file.json`))).toBe(\n\u003e   JSON.stringify({ data: 'imported' })\n\u003e );\n\u003e ```\n\u003e\n\u003e Or use `isEqual` (or your testing framework's equivalent):\n\u003e\n\u003e ```javascript\n\u003e expect(require(`${__dirname}/imported-file.json`)).toEqual({\n\u003e   data: 'imported'\n\u003e });\n\u003e ```\n\nAfter being transformed by babel but before being evaluated, the babel output\nwill have whitespace trimmed, line endings [converted][58], and then get\n[formatted by prettier][41].\n\nNote that this property cannot appear in the same test object as the\n[`execFixture`][40], [`code`][83], [`codeFixture`][38], [`output`][84],\n[`outputFixture`][39], [`throws`][81], or [`snapshot`][52] properties. However,\nit _can_ be used with [`outputRaw`][85].\n\n###### `codeFixture`\n\nIf you would rather put your [`code`][83] in a separate file, you can specify a\nfile path here instead. If it is an absolute path, then that's the file that\nwill be loaded. Otherwise, `codeFixture` will be [`path.join`][42]'d with the\n[directory name][43] of [`filepath`][56].\n\nAfter being transformed by babel, the resulting output will have whitespace\ntrimmed, line endings [converted][58], and then get [formatted by prettier][41].\n\nLike [`code`][83], this property cannot appear in the same test object as the\n[`exec`][86] or [`execFixture`][40] properties, nor the [`code`][83] property.\n\n\u003e \\[!TIP]\n\u003e\n\u003e If you find you are using this property more than a couple of times, consider\n\u003e using [`fixtures`][37] instead.\n\n\u003e \\[!NOTE]\n\u003e\n\u003e For backwards compatibility reasons, `codeFixture` is synonymous with\n\u003e `fixture`. They can be used interchangeably, though care must be taken not to\n\u003e confuse the test object property `fixture` with the babel-plugin-tester option\n\u003e [_`fixtures`_][37], the latter being plural.\n\n###### `outputFixture`\n\nIf you would rather put your [`output`][84] in a separate file, you can specify\na file path here instead. If it is an absolute path, then that's the file that\nwill be loaded. Otherwise, `outputFixture` will be [`path.join`][42]'d with the\n[directory name][43] of [`filepath`][56].\n\nBefore being compared to babel's output, this file's contents will have\nwhitespace trimmed and line endings [converted][58].\n\nLike [`output`][84], this property cannot appear in the same test object as the\n[`exec`][86], [`execFixture`][40], [`throws`][81], or [`snapshot`][52]\nproperties, nor the [`output`][84] property. However, it _can_ be used with\n[`outputRaw`][85].\n\n\u003e \\[!TIP]\n\u003e\n\u003e If you find you are using this property more than a couple of times, consider\n\u003e using [`fixtures`][37] instead.\n\n###### `execFixture`\n\nIf you would rather put your [`exec`][86] in a separate file, you can specify a\nfile path here instead. If it is an absolute path, then that's the file that\nwill be loaded. Otherwise, `execFixture` will be [`path.join`][42]'d with the\n[directory name][43] of [`filepath`][56].\n\nAfter being transformed by babel but before being evaluated, the babel output\nwill have whitespace trimmed, line endings [converted][58], and then get\n[formatted by prettier][41].\n\nLike [`exec`][86], this property cannot appear in the same test object as the\n[`code`][83], [`codeFixture`][38], [`output`][84], [`outputFixture`][39],\n[`throws`][81], or [`snapshot`][52] properties, nor the [`exec`][86] property.\nHowever, it _can_ be used with [`outputRaw`][85].\n\n\u003e \\[!TIP]\n\u003e\n\u003e If you find you are using this property more than a couple of times, consider\n\u003e using [`fixtures`][37] instead.\n\n## Examples\n\n### Simple Example\n\n```javascript\nimport { pluginTester } from 'babel-plugin-tester';\nimport identifierReversePlugin from '../identifier-reverse-plugin';\n\n// NOTE: you can use beforeAll, afterAll, beforeEach, and afterEach as usual,\n// but initial configuration tasks, like loading content from fixture files,\n// will complete *at the point the pluginTester function is called* which means\n// BEFORE beforeAll and other Jest hooks are run.\n\npluginTester({\n  plugin: identifierReversePlugin,\n  // Defaults to false, but with this line we set the default to true across\n  // *all* tests.\n  snapshot: true,\n  tests: [\n    {\n      code: \"'hello';\"\n      // Snapshot should show that prettier has changed the single quotes to\n      // double quotes (using prettier's default configuration).\n    },\n    {\n      // This test will pass if and only if code has not changed.\n      code: '\"hello\";'\n      // To prevent false negatives (like with reckless use of `npx jest -u`),\n      // snapshots of code that does not change are forbidden. Snapshots\n      // succeed only when babel output !== code input.\n      snapshot: false;\n    },\n    {\n      code: 'var hello = \"hi\";',\n      output: 'var olleh = \"hi\";',\n      // You can't take a snapshot and also manually specify an output string.\n      // It's either one or the other.\n      snapshot: false\n    },\n    // A valid test can be a test object or a simple string.\n    `\n      function sayHi(person) {\n        return 'Hello ' + person + '!'\n      }\n      console.log(sayHi('Jenny'))\n    `\n  ]\n});\n```\n\n### Full Example\n\n```javascript\nimport path from 'node:path';\nimport { pluginTester } from 'babel-plugin-tester';\nimport identifierReversePlugin from '../identifier-reverse-plugin';\n\npluginTester({\n  // One (and ONLY ONE) of the two following lines MUST be included.\n  plugin: identifierReversePlugin,\n  //preset: coolNewBabelPreset,\n\n  // Usually unnecessary if it is returned by the plugin. This will default to\n  // 'unknown plugin' if a name cannot otherwise be inferred.\n  pluginName: 'identifier reverse',\n  // Unlike with pluginName, there is no presetName inference. This will default\n  // to 'unknown preset' if a name is not provided.\n  //presetName: 'cool-new-babel-preset',\n\n  // Used to test specific plugin options.\n  pluginOptions: {\n    optionA: true\n  },\n  //presetOptions: {\n  //  optionB: false,\n  //}\n\n  // Defaults to the plugin name.\n  title: 'describe block title',\n\n  // Only useful if you are using fixtures, codeFixture, outputFixture, or\n  // execFixture options. Defaults to the absolute path of the file the\n  // pluginTester function was invoked from, which in this case  is equivalent\n  // to the following line:\n  filepath: __filename,\n\n  // These are the defaults that will be lodash.mergeWith'd with the provided\n  // babelOptions option.\n  babelOptions: {\n    parserOpts: {},\n    generatorOpts: {},\n    babelrc: false,\n    configFile: false\n  },\n\n  // Defaults to false but we're being explicit here: do not use snapshots\n  // across all tests. Note that snapshots are only guaranteed to work with\n  // Jest.\n  snapshot: false,\n\n  // Defaults to a function that formats with prettier.\n  formatResult: customFormatFunction,\n\n  // You can provide tests as an object:\n  tests: {\n    // The key is the title. The value is the code that is unchanged (because\n    // snapshot === false across all tests). Test title will be: \"1. does not\n    // change code with no identifiers\".\n    'does not change code with no identifiers': '\"hello\";',\n\n    // Test title will be: \"2. changes this code\".\n    'changes this code': {\n      // Input to the plugin.\n      code: 'var hello = \"hi\";',\n      // Expected output.\n      output: 'var olleh = \"hi\";'\n    }\n  },\n\n  // Alternatively, you can provide tests as an array:\n  tests: [\n    // Should be unchanged by the plugin (because snapshot === false across all\n    // tests). Test title will be: \"1. identifier reverse\".\n    '\"hello\";',\n    {\n      // Test title will be: \"2. identifier reverse\".\n      code: 'var hello = \"hi\";',\n      output: 'var olleh = \"hi\";'\n    },\n    {\n      // Test title will be: \"3. unchanged code\".\n      title: 'unchanged code',\n      // Because this is an absolute path, the filepath option above will not\n      // be used to resolve this path.\n      codeFixture: path.join(\n        __dirname,\n        '..',\n        'fixtures',\n        'codeFixture-unchanging.js'\n      )\n      // No output, outputFixture, or snapshot, so the assertion will be that\n      // the plugin does not change this code.\n    },\n    {\n      // Because these are not absolute paths, they will be joined with the\n      // directory of the filepath option provided above.\n      codeFixture: path.join('..', 'fixtures', 'codeFixture.js'),\n      // Because outputFixture is provided, the assertion will be that the\n      // plugin will change the contents of \"codeFixture.js\" to the contents of\n      // \"outputFixture.js\".\n      outputFixture: path.join('..', 'fixtures', 'outputFixture.js')\n    },\n    {\n      // As a convenience, this will have the indentation striped and it will\n      // be trimmed.\n      code: `\n        function sayHi(person) {\n          return 'Hello ' + person + '!';\n        }\n      `,\n      // This will take a Jest snapshot, overwriting the default/global\n      // settings (set above). The snapshot will contain both source code and\n      // the transformed output, making the snapshot file easier to understand.\n      snapshot: true\n    },\n    {\n      code: 'var hello = \"hi\";',\n      output: 'var olleh = \"hi\";',\n      // This can be used to overwrite pluginOptions (set above).\n      pluginOptions: {\n        optionA: false\n      }\n      // This can be used to overwrite presetOptions (set above).\n      //presetOptions: {\n      //  optionB: true\n      //}\n    },\n    {\n      title: 'unchanged code',\n      code: '\"no change\";',\n      setup() {\n        // Runs before this test.\n        return function teardown() {\n          // Runs after this tests.\n        };\n        // Can also return a promise.\n      },\n      teardown() {\n        // Runs after this test.\n        // Can return a promise.\n      }\n    },\n    {\n      // This source will be transformed just like the code property, except the\n      // produced code will be evaluated in the same CJS context as the test\n      // runner. This lets us make more advanced assertions on the output.\n      exec: `\n        const hello = \"hi\";\n        // The plugin will reverse ALL identifiers, even globals like \"expect\"!\n        tcepxe(hello)['toBe'](\"hi\");\n      `\n    }\n  ]\n});\n```\n\n### Fixtures Examples\n\nSee [`fixtures`][37] for an example directory layout or check out the use of\nbabel-plugin-tester fixtures in some of these other projects:\n\n\u003c!-- lint disable list-item-style --\u003e\n\n- [babel-plugin-transform-rewrite-imports][91]\n- [babel-plugin-explicit-exports-references][92]\n- [babel-plugin-transform-default-named-imports][93]\n\n\u003c!-- lint enable list-item-style --\u003e\n\u003c!-- symbiote-template-region-start 5 --\u003e\n\n## Appendix\n\n\u003c!-- symbiote-template-region-end --\u003e\n\nFurther documentation can be found under [`docs/`][x-repo-docs].\n\n### Testing Framework Compatibility\n\nThis package was originally tested on and built to work with [Jest][1], but it\nis also [tested][94] against [Vitest][5], [Mocha][2], [Jasmine][3], and\n[`node:test`][4]. See below for details.\n\n#### Jest\n\nAll babel-plugin-tester features work with Jest. No further action is necessary\n🚀\n\n#### Vitest\n\nAll babel-plugin-tester features work with Vitest, though Vitest does not\nprovide global APIs by default. You can either supply some interoperability code\n(see Jasmine or `node:test` below for an example) or run Vitest with the\n[`--globals` CLI option][95].\n\n#### Mocha\n\nMost babel-plugin-tester features work with Mocha, except Mocha does not\nnatively support snapshots.\n\n#### Jasmine\n\nMost babel-plugin-tester features work with Jasmine if you define the\nappropriate globals:\n\n```javascript\nimport { pluginTester } from 'babel-plugin-tester';\n\nglobalThis.it.skip = globalThis.xit;\nglobalThis.it.only = globalThis.fit;\n\npluginTester(...);\n```\n\nHowever, Jasmine does not natively support snapshots.\n\n#### `node:test`\n\nMost babel-plugin-tester features work with `node:test` if you define the\nappropriate globals:\n\n```javascript\nimport { describe, it } from 'node:test';\nimport { pluginTester } from 'babel-plugin-tester';\n\nglobalThis.describe = describe;\nglobalThis.it = it;\n// globalThis.it.skip = ... (weirdly, this is already defined)\nglobalThis.it.only = (...args) =\u003e it(args[0], { only: true }, args[1]);\n\npluginTester(...);\n```\n\nHowever, `node:test` does not natively support snapshots.\n\n#### Other Frameworks\n\nOther testing frameworks and test runners should also work so long as they\ndefine standard `describe` and `it` globals with async support, or appropriate\ninteroperability code is used like in the above Jasmine and `node:test`\nexamples.\n\n### Using Babel for Configuration Loading\n\n[`babelOptions.babelrc`][29] and [`babelOptions.configFile`][30] are set to\n`false` by default. This way, you can [manually import (or provide an object\nliteral)][66] the exact configuration you want to apply rather than relying on\nbabel's [somewhat complex configuration loading rules][96]. However, if your\nplugin, preset, or project relies on a complicated external setup to do its\nwork, and you do not mind the [default run order][97], you can leverage [babel's\nautomatic configuration loading][98] via the `babelOptions.babelrc` and/or\n`babelOptions.configFile` options.\n\n\u003e \\[!TIP]\n\u003e\n\u003e Fixtures provided via the [`fixtures`][37] option **do not** need to provide a\n\u003e separate `babelOptions.filename` since it will be set automatically. This\n\u003e section only applies to [test objects][44].\n\nWhen relying on `babelOptions.babelrc`, you must also provide a\n[`babelOptions.filename`][99] for each test object that does not include a\n[`codeFixture`][38] or [`execFixture`][40] property. For example:\n\n```javascript\npluginTester({\n  plugin,\n  tests: [\n    {\n      code: '\"blah\"',\n      // This configuration is set at the test level\n      babelOptions: {\n        babelrc: true,\n        filename: path.join(__dirname, 'some-file.js')\n      }\n    },\n    {\n      code: '\"hi\"',\n      // This configuration is set at the test level\n      babelOptions: {\n        babelrc: true,\n        filename: path.join(__dirname, 'some-other-file.js')\n      }\n    },\n    {\n      // babelOptions.filename will be set to the value of codeFixture for you\n      // unless you set it manually here at the test level\n      codeFixture: path.join(__dirname, 'fixtures', 'my-file.js')\n    },\n    {\n      // babelOptions.filename will be set to the value of execFixture for you\n      // unless you set it manually here at the test level\n      execFixture: path.join(__dirname, 'fixtures', 'my-script.js')\n    }\n  ]\n});\n```\n\nThis file does not actually have to exist either, so you can use whatever value\nyou want for `filename` as long as the `.babelrc` file is [resolved][100]\nproperly. Hence, the above example could be simplified further:\n\n```javascript\npluginTester({\n  plugin,\n  // This configuration is global: it applies to *all* tests by default!\n  babelOptions: {\n    babelrc: true,\n    // The value of filename does not have to point to a file that exists\n    filename: __filename\n  },\n  tests: [\n    '\"blah\"',\n    '\"hi\"',\n    {\n      // babelOptions.filename will be set to the value of codeFixture for you\n      // unless you set it manually here at the test level\n      codeFixture: path.join(__dirname, 'fixtures', 'my-file.js')\n    },\n    {\n      // babelOptions.filename will be set to the value of execFixture for you\n      // unless you set it manually here at the test level\n      execFixture: path.join(__dirname, 'fixtures', 'my-script.js')\n    }\n  ]\n});\n```\n\n### `pluginName` Inference Caveat\n\nInferring [`pluginName`][13] during testing requires invoking [the plugin][10]\n_at least twice_: once outside of babel to check for the plugin's name and then\nagain when run by babel. This is irrelevant to babel-plugin-tester (even if your\nplugin crashes when run outside of babel) and to the overwhelming majority of\nbabel plugins in existence. This only becomes a problem if your plugin is\n_aggressively stateful_, which is against the [babel handbook on plugin\ndesign][101].\n\nFor example, the following plugin which replaces an import specifier using a\nregular expression will exhibit strange behavior due to being invoked twice:\n\n```javascript\n/*  -*-*-  BAD CODE DO NOT USE  -*-*-  */\n\nlet source;\n// vvv When first invoked outside of babel, all passed arguments are mocks vvv\nfunction badNotGoodPlugin({ assertVersion, types: t }) {\n  // ^^^ Which means assertVersion is mocked and t is undefined ^^^\n  assertVersion(7);\n\n  // vvv So don't memoize `t` here (which among other things is poor design) vvv\n  if (!source) {\n    source = (value, original, replacement) =\u003e {\n      return t.stringLiteral(value.replace(original, replacement));\n    };\n  }\n\n  return {\n    name: 'bad-bad-not-good',\n    visitor: {\n      ImportDeclaration(path, state) {\n        path.node.source = source(\n          path.node.source.value,\n          state.opts.originalRegExp,\n          state.opts.replacementString\n        );\n      }\n    }\n  };\n}\n\npluginTester({\n  plugin: badNotGoodPlugin,\n  pluginOptions: { originalRegExp: /^y$/, replacementString: 'z' },\n  tests: [{ code: 'import { x } from \"y\";', output: 'import { x } from \"z\";' }]\n});\n\n// Result: error!\n// TypeError: Cannot read properties of undefined (reading 'stringLiteral')\n```\n\nIf you still want to use global state despite the handbook's advice, either\ninitialize global state within your visitor:\n\n```javascript\nlet source;\nfunction okayPlugin({ assertVersion, types: t }) {\n  assertVersion(7);\n\n  return {\n    name: 'okay',\n    visitor: {\n      Program: {\n        enter() {\n          // vvv Initialize global state in a safe place vvv\n          if (!source) {\n            source = (value, original, replacement) =\u003e {\n              return t.stringLiteral(value.replace(original, replacement));\n            };\n          }\n        }\n      },\n      ImportDeclaration(path, state) {\n        path.node.source = source(\n          path.node.source.value,\n          state.opts.originalRegExp,\n          state.opts.replacementString\n        );\n      }\n    }\n  };\n}\n\npluginTester({\n  plugin: okayPlugin,\n  pluginOptions: { originalRegExp: /^y$/, replacementString: 'z' },\n  tests: [{ code: 'import { x } from \"y\";', output: 'import { x } from \"z\";' }]\n});\n\n// Result: works!\n```\n\nOr do things the proper way and just use local state instead:\n\n```javascript\nfunction betterPlugin({ assertVersion, types: t }) {\n  assertVersion(7);\n\n  // vvv Use local state instead so t is memoized properly vvv\n  const source = (value, original, replacement) =\u003e {\n    return t.stringLiteral(value.replace(original, replacement));\n  };\n\n  return {\n    name: 'better',\n    visitor: {\n      ImportDeclaration(path, state) {\n        path.node.source = source(\n          path.node.source.value,\n          state.opts.originalRegExp,\n          state.opts.replacementString\n        );\n      }\n    }\n  };\n}\n\npluginTester({\n  plugin: betterPlugin,\n  pluginOptions: { originalRegExp: /^y$/, replacementString: 'z' },\n  tests: [{ code: 'import { x } from \"y\";', output: 'import { x } from \"z\";' }]\n});\n\n// Result: works!\n```\n\n### Custom Snapshot Serialization\n\nIf you are using Jest and snapshots, then the snapshot output could have a bunch\nof bothersome `\\\"` to escape quotes. This is because, when Jest serializes a\nstring, it will wrap everything in double quotes. This is not a huge deal, but\nit makes the snapshots harder to read, so we automatically add a snapshot\nserializer for you to remove those. Note that this serializer is added globally\nand thus will affect _all_ snapshots taken in the test file, even those outside\nof babel-plugin-tester.\n\nIf you would like to disable this feature, then use the \"pure\" import (also\ndisables formatting of babel output with prettier):\n\n```diff\n- import { pluginTester } from 'babel-plugin-tester'\n+ import { pluginTester } from 'babel-plugin-tester/pure'\n```\n\n\u003e It seems recent versions of Jest already ship with easier-to-read snapshots,\n\u003e making this serializer redundant. Therefore, the built-in custom serializer\n\u003e will likely be removed entirely in a future version of babel-plugin-tester.\n\n### Formatting Output with Prettier\n\nBy default, a [formatter][78] is used which formats all babel output with\n[prettier][50]. It will [look for][51] a prettier configuration file relative to\n[the file that's being tested][56] or the [current working directory][102]. If\nit cannot find one, then it uses the default configuration for prettier.\n\nThis makes your snapshots easier to read and your expectations easier to write,\nbut if you would like to disable this feature, you can either use the [`pure`\nimport][103] to disable automatic formatting (along with snapshot serialization)\nor you can override the `formatResult` option manually like so:\n\n```javascript\npluginTester({\n  // ...\n  formatResult: (r) =\u003e r\n  // ...\n});\n```\n\n### Built-In Debugging Support\n\nThis package uses [debug][104] under the hood. To view all possible debugging\noutput, including the results of all babel transformations, set the\n`DEBUG='babel-plugin-tester,babel-plugin-tester:*'` [environment variable][105]\nwhen running your tests.\n\nFor example:\n\n```bash\n# Those using Windows (but not WSL) have to set environment variable differently\nNODE_ENV='test' DEBUG='babel-plugin-tester,babel-plugin-tester:*' DEBUG_DEPTH='1' npx jest\n```\n\n#### Available Debug Namespaces\n\nThe following [debug namespaces][106] are available for activation:\n\n\u003c!-- lint disable list-item-style --\u003e\n\n- `babel-plugin-tester:index`\n- `babel-plugin-tester:formatter`\n- `babel-plugin-tester:serializer`\n- `babel-plugin-tester:tester`\n  - `babel-plugin-tester:tester:resolve-base`\n  - `babel-plugin-tester:tester:resolve-env`\n  - `babel-plugin-tester:tester:normalize`\n    - `babel-plugin-tester:tester:normalize:create-desc`\n    - `babel-plugin-tester:tester:normalize:create-fix`\n    - `babel-plugin-tester:tester:normalize:create-obj`\n  - `babel-plugin-tester:tester:register`\n  - `babel-plugin-tester:tester:wrapper`\n  - `babel-plugin-tester:tester:test`\n  - `babel-plugin-tester:tester:validate`\n  - `babel-plugin-tester:tester:read-opts`\n  - `babel-plugin-tester:tester:read-code`\n  - `babel-plugin-tester:tester:eol`\n  - `babel-plugin-tester:tester:finalize`\n    - `babel-plugin-tester:tester:finalize:order`\n    - `babel-plugin-tester:tester:finalize:duplicates`\n\n\u003c!-- lint enable list-item-style --\u003e\n\nThe `babel-plugin-tester:tester` namespace and its sub-namespaces each have an\nadditional `verbose` sub-namespace that can be activated or deactivated at will,\ne.g. `babel-plugin-tester:tester:verbose` and\n`babel-plugin-tester:tester:wrapper:verbose`.\n\nFor example, to view all debug output except verbose output:\n\n```bash\n# Those using Windows (but not WSL) have to set environment variable differently\nNODE_ENV='test' DEBUG='babel-plugin-tester,babel-plugin-tester:*,-*:verbose' npx jest\n```\n\n### `TEST_ONLY`/`TEST_NUM_ONLY` and `TEST_SKIP`/`TEST_NUM_SKIP` Environment Variables\n\nThe optional `TEST_ONLY` and `TEST_SKIP` environment variables are recognized by\nbabel-plugin-tester, allowing you to control which tests are run in an adhoc\nfashion without having to modify your test configuration code.\n\nThe values of these variables will be transformed into regular expressions via\n`RegExp(value, 'u')` and matched against each test/fixture title (not including\n[automatically assigned numbers][55] prefixed to titles). Tests with titles that\nmatch `TEST_ONLY` will be run while all others are skipped. On the other hand,\ntests with titles that match `TEST_SKIP` will be skipped while others are run.\n\nFor example, to skip the test titled \"this is the name of a failing unit test\":\n\n```bash\nTEST_SKIP='name of a failing' npx jest\n```\n\nGiven both `TEST_ONLY` and `TEST_SKIP`, tests matched by `TEST_SKIP` will\n_always_ be skipped, even if they are also matched by `TEST_ONLY`. These\nenvironment variables also override both the fixture-specific\n[`skip`][107]/[`only`][108] and test object [`skip`][109]/[`only`][110]\nproperties.\n\nIn addition to `TEST_ONLY` and `TEST_SKIP`, you can also target tests\nspecifically by their [automatically assigned number][55] using `TEST_NUM_ONLY`\nand `TEST_NUM_SKIP`. These environment variables function identically to their\ncounterparts except they accept one or more numbers separated by commas (spaces\naround commas are ignored) instead of regular expressions. Inclusive ranges\n(e.g. `4-9`) are also supported.\n\nFor example, the following will skip tests numbered 1, 3, 5, and 6-10\n(inclusive):\n\n```bash\n# Spaces around commas don't matter and sequential/final commas are ignored\nTEST_NUM_SKIP='5,1, 6-10,,  3,' npx jest\n```\n\n`TEST_NUM_ONLY` and `TEST_NUM_SKIP` are meaningless if [`titleNumbering`][55] is\n`false` or your tests are otherwise unnumbered, and may match multiple tests if\n[automatic numbering is restarted][111].\n\n### `setup` and `teardown` Run Order\n\nFor each test object and fixture test, setup and teardown functions are run in\nthe following order:\n\n1. [Base `setup`][49].\n2. [Test object `setup`][88] / [fixture `setup`][77].\n3. _Test object / fixture test is run_.\n4. Any function returned by test object `setup` / fixture `setup`.\n5. [Test object `teardown`][87] / [fixture `teardown`][76].\n6. Any function returned by base `setup`.\n7. [Base `teardown`][47].\n\n\u003c!-- symbiote-template-region-start 6 --\u003e\n\n### Published Package Details\n\nThis is a [CJS2 package][x-pkg-cjs-mojito] with statically-analyzable exports\nbuilt by Babel for use in Node.js versions that are not end-of-life. For\nTypeScript users, this package supports both `\"Node10\"` and `\"Node16\"` module\nresolution strategies.\n\n\u003c!-- symbiote-template-region-end --\u003e\n\u003c!-- TODO: optional additional details here --\u003e\n\u003c!-- symbiote-template-region-start 7 --\u003e\n\n\u003cdetails\u003e\u003csummary\u003eExpand details\u003c/summary\u003e\n\nThat means both CJS2 (via `require(...)`) and ESM (via `import { ... } from ...`\nor `await import(...)`) source will load this package from the same entry points\nwhen using Node. This has several benefits, the foremost being: less code\nshipped/smaller package size, avoiding [dual package\nhazard][x-pkg-dual-package-hazard] entirely, distributables are not\npacked/bundled/uglified, a drastically less complex build process, and CJS\nconsumers aren't shafted.\n\nEach entry point (i.e. `ENTRY`) in [`package.json`'s\n`exports[ENTRY]`][x-repo-package-json] object includes one or more [export\nconditions][x-pkg-exports-conditions]. These entries may or may not include: an\n[`exports[ENTRY].types`][x-pkg-exports-types-key] condition pointing to a type\ndeclaration file for TypeScript and IDEs, a\n[`exports[ENTRY].module`][x-pkg-exports-module-key] condition pointing to\n(usually ESM) source for Webpack/Rollup, a `exports[ENTRY].node` and/or\n`exports[ENTRY].default` condition pointing to (usually CJS2) source for Node.js\n`require`/`import` and for browsers and other environments, and [other\nconditions][x-pkg-exports-conditions] not enumerated here. Check the\n[package.json][x-repo-package-json] file to see which export conditions are\nsupported.\n\nNote that, regardless of the [`{ \"type\": \"...\" }`][x-pkg-type] specified in\n[`package.json`][x-repo-package-json], any JavaScript files written in ESM\nsyntax (including distributables) will always have the `.mjs` extension. Note\nalso that [`package.json`][x-repo-package-json] may include the\n[`sideEffects`][x-pkg-side-effects-key] key, which is almost always `false` for\noptimal [tree shaking][x-pkg-tree-shaking] where appropriate.\n\n\u003c!-- symbiote-template-region-end --\u003e\n\u003c!-- TODO: optional additional details here --\u003e\n\u003c!-- symbiote-template-region-start 8 --\u003e\n\n\u003c/details\u003e\n\n### License\n\n\u003c!-- symbiote-template-region-end --\u003e\n\nSee [LICENSE][x-repo-license].\n\n\u003c!-- symbiote-template-region-start 9 --\u003e\n\n## Contributing and Support\n\n**[New issues][x-repo-choose-new-issue] and [pull requests][x-repo-pr-compare]\nare always welcome and greatly appreciated! 🤩** Just as well, you can [star 🌟\nthis project][x-badge-repo-link] to let me know you found it useful! ✊🏿 Or [buy\nme a beer][x-repo-sponsor], I'd appreciate it. Thank you!\n\nSee [CONTRIBUTING.md][x-repo-contributing] and [SUPPORT.md][x-repo-support] for\nmore information.\n\n\u003c!-- symbiote-template-region-end --\u003e\n\n### Inspiration\n\nThe API was inspired by:\n\n- ESLint's [RuleTester][ruletester].\n- [@thejameskyle][112]'s [tweet][jamestweet].\n- Babel's own\n  [`@babel/helper-plugin-test-runner`][@babel/helper-plugin-test-runner].\n\n\u003c!-- symbiote-template-region-start 10 --\u003e\n\n### Contributors\n\n\u003c!-- symbiote-template-region-end --\u003e\n\u003c!-- symbiote-template-region-start root-package-only --\u003e\n\u003c!-- remark-ignore-start --\u003e\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n\n[![All Contributors](https://img.shields.io/badge/all_contributors-31-orange.svg?style=flat-square)](#contributors-)\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\u003c!-- remark-ignore-end --\u003e\n\nThanks goes to these wonderful people ([emoji\nkey][x-repo-all-contributors-emojis]):\n\n\u003c!-- remark-ignore-start --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://kentcdodds.com\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/1500684?v=3?s=100\" width=\"100px;\" alt=\"Kent C. Dodds\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eKent C. Dodds\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=kentcdodds\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=kentcdodds\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"#infra-kentcdodds\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=kentcdodds\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://xunn.io\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/656017?v=4?s=100\" width=\"100px;\" alt=\"Bernard\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBernard\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=Xunnamius\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=Xunnamius\" title=\"Tests\"\u003e⚠️\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=Xunnamius\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"#infra-Xunnamius\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/pulls?q=is%3Apr+reviewed-by%3AXunnamius\" title=\"Reviewed Pull Requests\"\u003e👀\u003c/a\u003e \u003ca href=\"#maintenance-Xunnamius\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://thejameskyle.com/\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/952783?v=3?s=100\" width=\"100px;\" alt=\"james kyle\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ejames kyle\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=jamiebuilds\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=jamiebuilds\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/pulls?q=is%3Apr+reviewed-by%3Ajamiebuilds\" title=\"Reviewed Pull Requests\"\u003e👀\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=jamiebuilds\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/bbohen\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/1894628?v=3?s=100\" width=\"100px;\" alt=\"Brad Bohen\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBrad Bohen\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/issues?q=author%3Abbohen\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://www.krwelch.com\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/1295580?v=3?s=100\" width=\"100px;\" alt=\"Kyle Welch\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eKyle Welch\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=kwelch\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=kwelch\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=kwelch\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/kontrollanten\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/6680299?v=4?s=100\" width=\"100px;\" alt=\"kontrollanten\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ekontrollanten\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=kontrollanten\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/rubennorte\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/117921?v=4?s=100\" width=\"100px;\" alt=\"Rubén Norte\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRubén Norte\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=rubennorte\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=rubennorte\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://andreneves.work\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/3869532?v=4?s=100\" width=\"100px;\" alt=\"André Neves\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAndré Neves\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=andrefgneves\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=andrefgneves\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/merceyz\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/3842800?v=4?s=100\" width=\"100px;\" alt=\"Kristoffer K.\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eKristoffer K.\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=merceyz\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=merceyz\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/lifeart\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/1360552?v=4?s=100\" width=\"100px;\" alt=\"Alex Kanunnikov\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAlex Kanunnikov\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=lifeart\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=lifeart\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://solverfox.dev\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/12292047?v=4?s=100\" width=\"100px;\" alt=\"Sebastian Silbermann\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eSebastian Silbermann\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=eps1lon\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://ololos.space/\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/3940079?v=4?s=100\" width=\"100px;\" alt=\"Andrey Los\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAndrey Los\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/issues?q=author%3ARIP21\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/charlesbodman\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/231894?v=4?s=100\" width=\"100px;\" alt=\"Charles Bodman\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eCharles Bodman\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=charlesbodman\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://michaeldeboey.be\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/6643991?v=4?s=100\" width=\"100px;\" alt=\"Michaël De Boey\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMichaël De Boey\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=MichaelDeBoey\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/yuyaryshev\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/18558421?v=4?s=100\" width=\"100px;\" alt=\"yuyaryshev\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eyuyaryshev\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=yuyaryshev\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/CzBuCHi\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/12444673?v=4?s=100\" width=\"100px;\" alt=\"Marek Buchar\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMarek Buchar\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=CzBuCHi\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=CzBuCHi\" title=\"Tests\"\u003e⚠️\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=CzBuCHi\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://twitter.com/_jayphelps\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/762949?v=4?s=100\" width=\"100px;\" alt=\"Jay Phelps\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJay Phelps\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/pulls?q=is%3Apr+reviewed-by%3Ajayphelps\" title=\"Reviewed Pull Requests\"\u003e👀\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://www.mathiassoeholm.com\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/1747242?v=4?s=100\" width=\"100px;\" alt=\"Mathias\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMathias\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=mathiassoeholm\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://go/moon\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/40330875?v=4?s=100\" width=\"100px;\" alt=\"joe moon\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ejoe moon\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=moon-stripe\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=moon-stripe\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://www.linkedin.com/in/layershifter/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/14183168?v=4?s=100\" width=\"100px;\" alt=\"Oleksandr Fediashov\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eOleksandr Fediashov\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/issues?q=author%3Alayershifter\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/Andarist\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/9800850?v=4?s=100\" width=\"100px;\" alt=\"Mateusz Burzyński\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMateusz Burzyński\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=Andarist\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/hulkish\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/139332?v=4?s=100\" width=\"100px;\" alt=\"Steven Hargrove\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eSteven Hargrove\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=hulkish\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=hulkish\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/alexrhogue\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/896170?v=4?s=100\" width=\"100px;\" alt=\"Alex R Hogue\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAlex R Hogue\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=alexrhogue\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/infctr\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/15550153?v=4?s=100\" width=\"100px;\" alt=\"Arthur Zahorski\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eArthur Zahorski\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=infctr\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://egoist.dev/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/8784712?v=4?s=100\" width=\"100px;\" alt=\"EGOIST\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eEGOIST\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#infra-egoist\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://ifiokjr.com/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/1160934?v=4?s=100\" width=\"100px;\" alt=\"Ifiok Jr.\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eIfiok Jr.\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#platform-ifiokjr\" title=\"Packaging/porting to new platform\"\u003e📦\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://jan.buschtoens.me/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/834636?v=4?s=100\" width=\"100px;\" alt=\"Jan Buschtöns\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJan Buschtöns\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=buschtoens\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/malbernaz\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/10574149?v=4?s=100\" width=\"100px;\" alt=\"Miguel Albernaz\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMiguel Albernaz\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=malbernaz\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#infra-malbernaz\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/peterlebrun\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/1267171?v=4?s=100\" width=\"100px;\" alt=\"peterlebrun\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003epeterlebrun\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/commits?author=peterlebrun\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/SimenB\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/1404810?v=4?s=100\" width=\"100px;\" alt=\"Simen Bekkhus\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eSimen Bekkhus\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/babel-utils/babel-plugin-tester/issues?q=author%3ASimenB\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/ling1726\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/20744592?v=4?s=100\" width=\"100px;\" alt=\"ling1726\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eling1726\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#ideas-ling1726\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\u003c!-- remark-ignore-end --\u003e\n\nThis project follows the [all-contributors][x-repo-all-contributors]\nspecification. Contributions of any kind welcome!\n\n\u003c!-- symbiote-template-region-end --\u003e\n\u003c!-- symbiote-template-region-start workspace-package-only --\u003e\n\u003c!-- (section elided by symbiote) --\u003e\n\u003c!-- symbiote-template-region-end --\u003e\n\n[@babel/helper-plugin-test-runner]:\n  https://github.com/babel/babel/tree/master/packages/babel-helper-plugin-test-runner\n[jamestweet]: https://twitter.com/thejameskyle/status/864359438819262465\n[lodash.mergewith]: https://lodash.com/docs/4.17.4#mergeWith\n[ruletester]:\n  http://eslint.org/docs/developer-guide/working-with-rules#rule-unit-tests\n[x-badge-blm-image]: https://xunn.at/badge-blm 'Join the movement!'\n[x-badge-blm-link]: https://xunn.at/donate-blm\n[x-badge-codecov-image]:\n  https://img.shields.io/codecov/c/github/babel-utils/babel-plugin-tester/main?style=flat-square\u0026token=HWRIOBAAPW\u0026flag=package.main_root\n  'Is this package well-tested?'\n[x-badge-codecov-link]: https://codecov.io/gh/babel-utils/babel-plugin-tester\n[x-badge-downloads-image]:\n  https://img.shields.io/npm/dm/babel-plugin-tester?style=flat-square\n  'Number of times this package has been downloaded per month'\n[x-badge-lastcommit-image]:\n  https://img.shields.io/github/last-commit/babel-utils/babel-plugin-tester?style=flat-square\n  'Latest commit timestamp'\n[x-badge-license-image]:\n  https://img.shields.io/npm/l/babel-plugin-tester?style=flat-square\n  \"This package's source license\"\n[x-badge-license-link]:\n  https://github.com/babel-utils/babel-plugin-tester/blob/main/LICENSE\n[x-badge-npm-image]:\n  https://xunn.at/npm-pkg-version/babel-plugin-tester\n  'Install this package using npm or yarn!'\n[x-badge-npm-link]: https://npmtrends.com/babel-plugin-tester\n[x-badge-repo-link]: https://github.com/babel-utils/babel-plugin-tester\n[x-badge-semanticrelease-image]:\n  https://xunn.at/badge-semantic-release\n  'This repo practices continuous integration and deployment!'\n[x-badge-semanticrelease-link]:\n  https://github.com/semantic-release/semantic-release\n[x-pkg-cjs-mojito]:\n  https://dev.to/jakobjingleheimer/configuring-commonjs-es-modules-for-nodejs-12ed#publish-only-a-cjs-distribution-with-property-exports\n[x-pkg-dual-package-hazard]:\n  https://nodejs.org/api/packages.html#dual-package-hazard\n[x-pkg-exports-conditions]:\n  https://webpack.js.org/guides/package-exports#reference-syntax\n[x-pkg-exports-module-key]:\n  https://webpack.js.org/guides/package-exports#providing-commonjs-and-esm-version-stateless\n[x-pkg-exports-types-key]:\n  https://devblogs.microsoft.com/typescript/announcing-typescript-4-5-beta#packagejson-exports-imports-and-self-referencing\n[x-pkg-side-effects-key]:\n  https://webpack.js.org/guides/tree-shaking#mark-the-file-as-side-effect-free\n[x-pkg-tree-shaking]: https://webpack.js.org/guides/tree-shaking\n[x-pkg-type]:\n  https://github.com/nodejs/node/blob/8d8e06a345043bec787e904edc9a2f5c5e9c275f/doc/api/packages.md#type\n[x-repo-all-contributors]: https://github.com/all-contributors/all-contributors\n[x-repo-all-contributors-emojis]: https://allcontributors.org/docs/en/emoji-key\n[x-repo-choose-new-issue]:\n  https://github.com/babel-utils/babel-plugin-tester/issues/new/choose\n[x-repo-contributing]: /CONTRIBUTING.md\n[x-repo-docs]: docs\n[x-repo-license]: ./LICENSE\n[x-repo-package-json]: package.json\n[x-repo-pr-compare]: https://github.com/babel-utils/babel-plugin-tester/compare\n[x-repo-sponsor]: https://github.com/sponsors/Xunnamius\n[x-repo-support]: /.github/SUPPORT.md\n[1]: https://jestjs.io\n[2]: https://mochajs.org\n[3]: https://jasmine.github.io\n[4]: https://nodejs.org/api/test.html#test-runner\n[5]: https://vitest.dev\n[6]: #testing-framework-compatibility\n[7]: https://www.npmjs.com/package/babel-plugin-tester?activeTab=versions\n[8]: https://jestjs.io/docs/setup-teardown#one-time-setup\n[9]: #preset\n[10]: #plugin\n[11]: #presetname\n[12]: #presetoptions\n[13]: #pluginname\n[14]: #pluginoptions\n[15]: https://jestjs.io/docs/api#describename-fn\n[16]: https://jestjs.io/docs/api#testname-fn-timeout\n[17]:\n  https://github.com/DefinitelyTyped/DefinitelyTyped/blob/2b229cce80b334f673f1b26895007e9eca786366/types/babel-core/index.d.ts#L25\n[18]: #pluginname-inference-caveat\n[19]: #pluginoptions-2\n[20]: #pluginoptions-1\n[21]: #presetoptions-2\n[22]: #presetoptions-1\n[23]:\n  https://github.com/babel-utils/babel-plugin-tester/blob/1b413417de0f8f07764ee31e6131cee3e16f1265/src/plugin-tester.ts#L24-L31\n[24]: #babeloptions-2\n[25]: #babeloptions-1\n[26]:\n  https://stackoverflow.com/questions/52798987/babel-7-fails-with-single-plugin-saying-duplicate-plugin-preset-detected\n[27]: https://babeljs.io/docs/options#plugins\n[28]: https://babeljs.io/docs/options#presets\n[29]: https://babeljs.io/docs/en/options#babelrc\n[30]: https://babeljs.io/docs/en/options#configfile\n[31]: #using-babel-for-configuration-loading\n[32]: https://babeljs.io/docs/en/configuration\n[33]: https://babeljs.io/docs/en/options#plugins\n[34]: https://babeljs.io/docs/en/presets\n[35]: https://babeljs.io/docs/en/presets#preset-ordering\n[36]: #tests\n[37]: #fixtures\n[38]: #codefixture\n[39]: #outputfixture\n[40]: #execfixture\n[41]: #formatting-output-with-prettier\n[42]: https://nodejs.org/api/path.html#pathjoinpaths\n[43]: https://nodejs.org/api/path.html#pathdirnamepath\n[44]: #test-objects\n[45]: #invoke\n[46]: https://github.com/babel/babel/issues/8921\n[47]: #teardown\n[48]: #setup-and-teardown-run-order\n[49]: #setup\n[50]: https://prettier.io\n[51]: https://prettier.io/docs/en/configuration.html\n[52]: #snapshot-1\n[53]: #fixtureoutputname-1\n[54]: #fixtureoutputext-1\n[55]: #titlenumbering\n[56]: #filepath\n[57]: #outputjs\n[58]: #endofline\n[59]: #execjs\n[60]: #codejs\n[61]: #throws\n[62]: https://nodejs.org/api/vm.html#vmruninthiscontextcode-options\n[63]: https://babeljs.io/docs/en/babel-plugin-proposal-throw-expressions\n[64]: https://weizman.github.io/page-what-is-a-realm-in-js\n[65]: https://nodejs.org/api/modules.html#moduleexports\n[66]: #babeloptions\n[67]: https://jestjs.io/docs/snapshot-testing\n[68]: https://jestjs.io/docs/api#testonlyname-fn-timeout\n[69]: https://jestjs.io/docs/api#testskipname-fn\n[70]:\n  https://github.com/nodejs/node/blob/a03529d82858ed225f40837f14db71851ad5d885/lib/internal/util.js#L97-L99\n[71]: https://github.com/facebook/jest/issues/2549\n[72]:\n  https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-instanceof-array.md\n[73]: https://nodejs.org/api/vm.html#vm-executing-javascript\n[74]: https://stackoverflow.com/a/32750746/1367414\n[75]: #outputraw\n[76]: #teardown-1\n[77]: #setup-1\n[78]: #formatresult\n[79]:\n  https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/babel-core/index.d.ts#L191-L197\n[80]: https://babeljs.io/docs/babel-core#transform\n[81]: #throws-1\n[82]: #full-example\n[83]: #code\n[84]: #output\n[85]: #outputraw-1\n[86]: #exec\n[87]: #teardown-2\n[88]: #setup-2\n[89]: https://www.npmjs.com/package/jest-snapshot\n[90]: https://jestjs.io/docs/expect#tomatchsnapshotpropertymatchers-hint\n[91]:\n  https://github.com/Xunnamius/babel-plugin-transform-rewrite-imports/blob/main/test/unit-index.test.ts\n[92]:\n  https://github.com/Xunnamius/babel-plugin-explicit-exports-references/blob/main/test/unit-index.test.ts\n[93]:\n  https://github.com/Xunnamius/babel-plugin-transform-default-named-imports/blob/main/test/unit-index.test.ts\n[94]: ./test/integration/integration-node-smoke.test.ts\n[95]: https://vitest.dev/config#globals\n[96]: https://babeljs.io/docs/en/options#config-loading-options\n[97]: #custom-plugin-and-preset-run-order\n[98]: https://babeljs.io/docs/en/config-files\n[99]: https://babeljs.io/docs/en/options#filename\n[100]: https://babeljs.io/docs/en/config-files#file-relative-configuration\n[101]:\n  https://github.com/jamiebuilds/babel-handbook/blob/c6828415127f27fedcc51299e98eaf47b3e26b5f/translations/en/plugin-handbook.md#state\n[102]: https://nodejs.org/api/process.html#processcwd\n[103]: #custom-snapshot-serialization\n[104]: https://npm.im/debug\n[105]: https://www.npmjs.com/package/debug#environment-variables\n[106]: https://www.npmjs.com/package/debug#namespace-colors\n[107]: #skip\n[108]: #only\n[109]: #skip-1\n[110]: #only-1\n[111]: #restarttitlenumbering\n[112]: https://github.com/jamiebuilds\n","funding_links":["https://github.com/sponsors/Xunnamius"],"categories":["JavaScript","TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbabel-utils%2Fbabel-plugin-tester","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbabel-utils%2Fbabel-plugin-tester","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbabel-utils%2Fbabel-plugin-tester/lists"}