Skip to content

Commit 744d4f6

Browse files
authored
feat: support providing aliases for @jest/globals package (#1543)
1 parent 8f59e2b commit 744d4f6

File tree

3 files changed

+220
-3
lines changed

3 files changed

+220
-3
lines changed

README.md

+21
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,27 @@ You can tell this plugin about any global Jests you have aliased using the
8787
}
8888
```
8989

90+
#### Aliased `@jest/globals`
91+
92+
You can tell this plugin to treat a different package as the source of Jest
93+
globals using the `globalPackage` setting:
94+
95+
```json
96+
{
97+
"settings": {
98+
"jest": {
99+
"globalPackage": "bun:test"
100+
}
101+
}
102+
}
103+
```
104+
105+
> [!WARNING]
106+
>
107+
> While this can be used to apply rules when using alternative testing libraries
108+
> and frameworks like `bun`, `vitest` and `node`, there's no guarantee the
109+
> semantics this plugin assumes will hold outside of Jest
110+
90111
### Running rules only on test-related files
91112

92113
The rules provided by this plugin assume that the files they are checking are

src/rules/utils/__tests__/parseJestFnCall.test.ts

+192
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,198 @@ ruleTester.run('global aliases', rule, {
737737
],
738738
});
739739

740+
ruleTester.run('global package source', rule, {
741+
valid: [
742+
{
743+
code: dedent`
744+
import { expect } from 'bun:test'
745+
746+
expect(x).toBe(y);
747+
`,
748+
parserOptions: { sourceType: 'module' },
749+
settings: { jest: { globalPackage: '@jest/globals' } },
750+
},
751+
{
752+
code: dedent`
753+
const { it } = require('@jest/globals');
754+
755+
it('is not considered a test function', () => {});
756+
`,
757+
parserOptions: { sourceType: 'script' },
758+
settings: { jest: { globalPackage: 'bun:test' } },
759+
},
760+
{
761+
code: dedent`
762+
const { fn: it } = require('bun:test');
763+
764+
it('is not considered a test function', () => {});
765+
`,
766+
parserOptions: { sourceType: 'script' },
767+
settings: { jest: { globalPackage: 'bun:test' } },
768+
},
769+
{
770+
code: dedent`
771+
import { it } from '@jest/globals';
772+
773+
it('is not considered a test function', () => {});
774+
`,
775+
parserOptions: { sourceType: 'module' },
776+
settings: { jest: { globalPackage: 'bun:test' } },
777+
},
778+
{
779+
code: dedent`
780+
import { fn as it } from 'bun:test';
781+
782+
it('is not considered a test function', () => {});
783+
`,
784+
parserOptions: { sourceType: 'module' },
785+
settings: { jest: { globalPackage: 'bun:test' } },
786+
},
787+
],
788+
invalid: [
789+
{
790+
code: 'expect(x).toBe(y);',
791+
parserOptions: { sourceType: 'script' },
792+
errors: [
793+
{
794+
messageId: 'details' as const,
795+
data: expectedParsedJestFnCallResultData({
796+
name: 'expect',
797+
type: 'expect',
798+
head: {
799+
original: null,
800+
local: 'expect',
801+
type: 'global',
802+
node: 'expect',
803+
},
804+
members: ['toBe'],
805+
}),
806+
column: 1,
807+
line: 1,
808+
},
809+
],
810+
settings: { jest: { globalPackage: 'bun:test' } },
811+
},
812+
{
813+
code: dedent`
814+
import { describe, expect, it } from 'bun:test'
815+
816+
describe('some tests', () => {
817+
it('ensures something', () => {
818+
expect.assertions();
819+
});
820+
});
821+
`,
822+
parserOptions: { sourceType: 'module' },
823+
errors: [
824+
{
825+
messageId: 'details' as const,
826+
data: expectedParsedJestFnCallResultData({
827+
name: 'describe',
828+
type: 'describe',
829+
head: {
830+
original: 'describe',
831+
local: 'describe',
832+
type: 'import',
833+
node: 'describe',
834+
},
835+
members: [],
836+
}),
837+
column: 1,
838+
line: 3,
839+
},
840+
{
841+
messageId: 'details' as const,
842+
data: expectedParsedJestFnCallResultData({
843+
name: 'it',
844+
type: 'test',
845+
head: {
846+
original: 'it',
847+
local: 'it',
848+
type: 'import',
849+
node: 'it',
850+
},
851+
members: [],
852+
}),
853+
column: 3,
854+
line: 4,
855+
},
856+
{
857+
messageId: 'details' as const,
858+
data: expectedParsedJestFnCallResultData({
859+
name: 'expect',
860+
type: 'expect',
861+
head: {
862+
original: 'expect',
863+
local: 'expect',
864+
type: 'import',
865+
node: 'expect',
866+
},
867+
members: ['assertions'],
868+
}),
869+
column: 5,
870+
line: 5,
871+
},
872+
],
873+
settings: { jest: { globalPackage: 'bun:test' } },
874+
},
875+
{
876+
code: dedent`
877+
import { expect } from 'bun:test'
878+
879+
expect(x).not.toBe(y);
880+
`,
881+
parserOptions: { sourceType: 'module' },
882+
errors: [
883+
{
884+
messageId: 'details' as const,
885+
data: expectedParsedJestFnCallResultData({
886+
name: 'expect',
887+
type: 'expect',
888+
head: {
889+
original: 'expect',
890+
local: 'expect',
891+
type: 'import',
892+
node: 'expect',
893+
},
894+
members: ['not', 'toBe'],
895+
}),
896+
column: 1,
897+
line: 3,
898+
},
899+
],
900+
settings: { jest: { globalPackage: 'bun:test' } },
901+
},
902+
{
903+
code: 'context("when there is an error", () => {})',
904+
errors: [
905+
{
906+
messageId: 'details' as const,
907+
data: expectedParsedJestFnCallResultData({
908+
name: 'describe',
909+
type: 'describe',
910+
head: {
911+
original: 'describe',
912+
local: 'context',
913+
type: 'global',
914+
node: 'context',
915+
},
916+
members: [],
917+
}),
918+
column: 1,
919+
line: 1,
920+
},
921+
],
922+
settings: {
923+
jest: {
924+
globalPackage: 'bun:test',
925+
globalAliases: { describe: ['context'] },
926+
},
927+
},
928+
},
929+
],
930+
});
931+
740932
ruleTester.run('typescript', rule, {
741933
valid: [
742934
{

src/rules/utils/parseJestFnCall.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ const ValidJestFnCallChains = [
188188
interface SharedConfigurationSettings {
189189
jest?: {
190190
globalAliases?: Record<string, string[]>;
191+
globalPackage?: string;
191192
version?: number | string;
192193
};
193194
}
@@ -584,9 +585,12 @@ const resolveToJestFn = (
584585
}
585586

586587
if (maybeImport) {
587-
// the identifier is imported from @jest/globals,
588-
// so return the original import name
589-
if (maybeImport.source === '@jest/globals') {
588+
const globalPackage =
589+
(context.settings as SharedConfigurationSettings).jest?.globalPackage ??
590+
'@jest/globals';
591+
592+
// the identifier is imported from our global package so return the original import name
593+
if (maybeImport.source === globalPackage) {
590594
return {
591595
original: maybeImport.imported,
592596
local: maybeImport.local,

0 commit comments

Comments
 (0)