@vitest/eslint-plugin 1.1.16 → 1.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -23,7 +23,7 @@ function _interopNamespaceCompat(e) {
23
23
  const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
24
24
  const ts__default = /*#__PURE__*/_interopDefaultCompat(ts);
25
25
 
26
- const version = "1.1.15";
26
+ const version = "1.1.17";
27
27
 
28
28
  function createEslintRule(rule) {
29
29
  const createRule = utils.ESLintUtils.RuleCreator(
@@ -228,7 +228,7 @@ const parseVitestFnCallWithReasonInner = (node, context) => {
228
228
  return null;
229
229
  const name = resolved.original ?? resolved.local;
230
230
  const links = [name, ...rest.map(getAccessorValue)];
231
- if (name !== "vi" && name !== "expect" && name !== "expectTypeOf" && !ValidVitestFnCallChains.has(links.join(".")))
231
+ if (resolved.type !== "testContext" && name !== "vi" && name !== "expect" && name !== "expectTypeOf" && !ValidVitestFnCallChains.has(links.join(".")))
232
232
  return null;
233
233
  const parsedVitestFnCall = {
234
234
  name,
@@ -271,6 +271,12 @@ const resolveVitestFn = (context, node, identifier) => {
271
271
  const maybeImport = resolveScope(scope, identifier);
272
272
  if (maybeImport === "local")
273
273
  return null;
274
+ if (maybeImport === "testContext")
275
+ return {
276
+ local: identifier,
277
+ original: null,
278
+ type: "testContext"
279
+ };
274
280
  if (maybeImport) {
275
281
  if (maybeImport.source === "vitest") {
276
282
  return {
@@ -300,6 +306,16 @@ const resolveScope = (scope, identifier) => {
300
306
  const ref = currentScope.set.get(identifier);
301
307
  if (ref && ref.defs.length > 0) {
302
308
  const def = ref.defs[ref.defs.length - 1];
309
+ const objectParam = isFunction(def.node) ? def.node.params.find((params) => params.type === utils.AST_NODE_TYPES.ObjectPattern) : void 0;
310
+ if (objectParam) {
311
+ const property = objectParam.properties.find((property2) => property2.type === utils.AST_NODE_TYPES.Property);
312
+ const key = property?.key.type === utils.AST_NODE_TYPES.Identifier ? property.key : void 0;
313
+ if (key?.name === identifier)
314
+ return "testContext";
315
+ }
316
+ const namedParam = isFunction(def.node) ? def.node.params.find((params) => params.type === utils.AST_NODE_TYPES.Identifier) : void 0;
317
+ if (namedParam)
318
+ return "testContext";
303
319
  const importDetails = describePossibleImportDef(def);
304
320
  if (importDetails?.local === identifier)
305
321
  return importDetails;
@@ -3681,8 +3697,12 @@ const requireLocalTestContextForConcurrentSnapshots = createEslintRule({
3681
3697
  create(context) {
3682
3698
  return {
3683
3699
  CallExpression(node) {
3684
- const isNotAnAssertion = !isTypeOfVitestFnCall(node, context, ["expect"]);
3685
- if (isNotAnAssertion)
3700
+ const vitestFnCall = parseVitestFnCall(node, context);
3701
+ if (vitestFnCall === null)
3702
+ return;
3703
+ if (vitestFnCall.type !== "expect")
3704
+ return;
3705
+ if (vitestFnCall.type === "expect" && vitestFnCall.head.type === "testContext")
3686
3706
  return;
3687
3707
  const isNotASnapshotAssertion = ![
3688
3708
  "toMatchSnapshot",
@@ -4071,6 +4091,7 @@ const preferExpectAssertions = createEslintRule({
4071
4091
  let hasExpectInCallBack = false;
4072
4092
  let hasExpectInLoop = false;
4073
4093
  let hasExpectAssertAsFirstStatement = false;
4094
+ let testContextName = null;
4074
4095
  let inTestCaseCall = false;
4075
4096
  let inForLoop = false;
4076
4097
  const shouldCheckFunction = (testFunction) => {
@@ -4144,6 +4165,9 @@ const preferExpectAssertions = createEslintRule({
4144
4165
  inTestCaseCall = true;
4145
4166
  return;
4146
4167
  }
4168
+ if (vitestFnCall?.head.type === "testContext" && vitestFnCall.members[0].type === utils.AST_NODE_TYPES.Identifier && vitestFnCall.members[0].name === "expect") {
4169
+ testContextName = `${vitestFnCall.head.local}`;
4170
+ }
4147
4171
  if (vitestFnCall?.type === "expect" && inTestCaseCall) {
4148
4172
  if (expressionDepth === 1 && isFirstStatement(node) && vitestFnCall.head.node.parent?.type === utils.AST_NODE_TYPES.MemberExpression && vitestFnCall.members.length === 1 && ["assertions", "hasAssertions"].includes(getAccessorValue(vitestFnCall.members[0]))) {
4149
4173
  checkExpectHasAssertions(vitestFnCall, node);
@@ -4162,12 +4186,6 @@ const preferExpectAssertions = createEslintRule({
4162
4186
  if (node.arguments.length < 2)
4163
4187
  return;
4164
4188
  const [, secondArg] = node.arguments;
4165
- if (secondArg?.type === utils.AST_NODE_TYPES.ArrowFunctionExpression && secondArg.params.length) {
4166
- if (secondArg?.params[0].type === utils.AST_NODE_TYPES.ObjectPattern) {
4167
- if (secondArg.params[0].properties[0].type === utils.AST_NODE_TYPES.Property && secondArg.params[0].properties[0].key.type === utils.AST_NODE_TYPES.Identifier && secondArg.params[0].properties[0].key.name === "expect")
4168
- return;
4169
- }
4170
- }
4171
4189
  if (!isFunction(secondArg) || !shouldCheckFunction(secondArg))
4172
4190
  return;
4173
4191
  hasExpectInLoop = false;
@@ -4178,9 +4196,10 @@ const preferExpectAssertions = createEslintRule({
4178
4196
  }
4179
4197
  const suggestions = [];
4180
4198
  if (secondArg.body.type === utils.AST_NODE_TYPES.BlockStatement) {
4199
+ const prefix = testContextName ? `${testContextName}.` : "";
4181
4200
  suggestions.push(
4182
- ["suggestAddingHasAssertions", "expect.hasAssertions();"],
4183
- ["suggestAddingAssertions", "expect.assertions();"]
4201
+ ["suggestAddingHasAssertions", `${prefix}expect.hasAssertions();`],
4202
+ ["suggestAddingAssertions", `${prefix}expect.assertions();`]
4184
4203
  );
4185
4204
  }
4186
4205
  context.report({
@@ -4998,6 +5017,8 @@ const plugin = {
4998
5017
  test: "writable",
4999
5018
  describe: "writable",
5000
5019
  it: "writable",
5020
+ expectTypeOf: "writable",
5021
+ assertType: "writable",
5001
5022
  expect: "writable",
5002
5023
  assert: "writable",
5003
5024
  vitest: "writable",
@@ -5005,7 +5026,9 @@ const plugin = {
5005
5026
  beforeAll: "writable",
5006
5027
  afterAll: "writable",
5007
5028
  beforeEach: "writable",
5008
- afterEach: "writable"
5029
+ afterEach: "writable",
5030
+ onTestFailed: "writable",
5031
+ onTestFinished: "writable"
5009
5032
  }
5010
5033
  }
5011
5034
  }
@@ -5017,6 +5040,8 @@ const plugin = {
5017
5040
  test: true,
5018
5041
  describe: true,
5019
5042
  it: true,
5043
+ expectTypeOf: true,
5044
+ assertType: true,
5020
5045
  expect: true,
5021
5046
  assert: true,
5022
5047
  vitest: true,
@@ -5024,7 +5049,9 @@ const plugin = {
5024
5049
  beforeAll: true,
5025
5050
  afterAll: true,
5026
5051
  beforeEach: true,
5027
- afterEach: true
5052
+ afterEach: true,
5053
+ onTestFailed: true,
5054
+ onTestFinished: true
5028
5055
  }
5029
5056
  }
5030
5057
  }
package/dist/index.d.cts CHANGED
@@ -170,6 +170,8 @@ declare const plugin: {
170
170
  test: "writable";
171
171
  describe: "writable";
172
172
  it: "writable";
173
+ expectTypeOf: "writable";
174
+ assertType: "writable";
173
175
  expect: "writable";
174
176
  assert: "writable";
175
177
  vitest: "writable";
@@ -178,6 +180,8 @@ declare const plugin: {
178
180
  afterAll: "writable";
179
181
  beforeEach: "writable";
180
182
  afterEach: "writable";
183
+ onTestFailed: "writable";
184
+ onTestFinished: "writable";
181
185
  };
182
186
  };
183
187
  };
@@ -189,6 +193,8 @@ declare const plugin: {
189
193
  test: true;
190
194
  describe: true;
191
195
  it: true;
196
+ expectTypeOf: true;
197
+ assertType: true;
192
198
  expect: true;
193
199
  assert: true;
194
200
  vitest: true;
@@ -197,6 +203,8 @@ declare const plugin: {
197
203
  afterAll: true;
198
204
  beforeEach: true;
199
205
  afterEach: true;
206
+ onTestFailed: true;
207
+ onTestFinished: true;
200
208
  };
201
209
  };
202
210
  };
package/dist/index.d.mts CHANGED
@@ -170,6 +170,8 @@ declare const plugin: {
170
170
  test: "writable";
171
171
  describe: "writable";
172
172
  it: "writable";
173
+ expectTypeOf: "writable";
174
+ assertType: "writable";
173
175
  expect: "writable";
174
176
  assert: "writable";
175
177
  vitest: "writable";
@@ -178,6 +180,8 @@ declare const plugin: {
178
180
  afterAll: "writable";
179
181
  beforeEach: "writable";
180
182
  afterEach: "writable";
183
+ onTestFailed: "writable";
184
+ onTestFinished: "writable";
181
185
  };
182
186
  };
183
187
  };
@@ -189,6 +193,8 @@ declare const plugin: {
189
193
  test: true;
190
194
  describe: true;
191
195
  it: true;
196
+ expectTypeOf: true;
197
+ assertType: true;
192
198
  expect: true;
193
199
  assert: true;
194
200
  vitest: true;
@@ -197,6 +203,8 @@ declare const plugin: {
197
203
  afterAll: true;
198
204
  beforeEach: true;
199
205
  afterEach: true;
206
+ onTestFailed: true;
207
+ onTestFinished: true;
200
208
  };
201
209
  };
202
210
  };
package/dist/index.d.ts CHANGED
@@ -170,6 +170,8 @@ declare const plugin: {
170
170
  test: "writable";
171
171
  describe: "writable";
172
172
  it: "writable";
173
+ expectTypeOf: "writable";
174
+ assertType: "writable";
173
175
  expect: "writable";
174
176
  assert: "writable";
175
177
  vitest: "writable";
@@ -178,6 +180,8 @@ declare const plugin: {
178
180
  afterAll: "writable";
179
181
  beforeEach: "writable";
180
182
  afterEach: "writable";
183
+ onTestFailed: "writable";
184
+ onTestFinished: "writable";
181
185
  };
182
186
  };
183
187
  };
@@ -189,6 +193,8 @@ declare const plugin: {
189
193
  test: true;
190
194
  describe: true;
191
195
  it: true;
196
+ expectTypeOf: true;
197
+ assertType: true;
192
198
  expect: true;
193
199
  assert: true;
194
200
  vitest: true;
@@ -197,6 +203,8 @@ declare const plugin: {
197
203
  afterAll: true;
198
204
  beforeEach: true;
199
205
  afterEach: true;
206
+ onTestFailed: true;
207
+ onTestFinished: true;
200
208
  };
201
209
  };
202
210
  };
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import { isAbsolute, posix } from 'node:path';
4
4
  import ts from 'typescript';
5
5
  import { createRequire } from 'node:module';
6
6
 
7
- const version = "1.1.15";
7
+ const version = "1.1.17";
8
8
 
9
9
  function createEslintRule(rule) {
10
10
  const createRule = ESLintUtils.RuleCreator(
@@ -209,7 +209,7 @@ const parseVitestFnCallWithReasonInner = (node, context) => {
209
209
  return null;
210
210
  const name = resolved.original ?? resolved.local;
211
211
  const links = [name, ...rest.map(getAccessorValue)];
212
- if (name !== "vi" && name !== "expect" && name !== "expectTypeOf" && !ValidVitestFnCallChains.has(links.join(".")))
212
+ if (resolved.type !== "testContext" && name !== "vi" && name !== "expect" && name !== "expectTypeOf" && !ValidVitestFnCallChains.has(links.join(".")))
213
213
  return null;
214
214
  const parsedVitestFnCall = {
215
215
  name,
@@ -252,6 +252,12 @@ const resolveVitestFn = (context, node, identifier) => {
252
252
  const maybeImport = resolveScope(scope, identifier);
253
253
  if (maybeImport === "local")
254
254
  return null;
255
+ if (maybeImport === "testContext")
256
+ return {
257
+ local: identifier,
258
+ original: null,
259
+ type: "testContext"
260
+ };
255
261
  if (maybeImport) {
256
262
  if (maybeImport.source === "vitest") {
257
263
  return {
@@ -281,6 +287,16 @@ const resolveScope = (scope, identifier) => {
281
287
  const ref = currentScope.set.get(identifier);
282
288
  if (ref && ref.defs.length > 0) {
283
289
  const def = ref.defs[ref.defs.length - 1];
290
+ const objectParam = isFunction(def.node) ? def.node.params.find((params) => params.type === AST_NODE_TYPES.ObjectPattern) : void 0;
291
+ if (objectParam) {
292
+ const property = objectParam.properties.find((property2) => property2.type === AST_NODE_TYPES.Property);
293
+ const key = property?.key.type === AST_NODE_TYPES.Identifier ? property.key : void 0;
294
+ if (key?.name === identifier)
295
+ return "testContext";
296
+ }
297
+ const namedParam = isFunction(def.node) ? def.node.params.find((params) => params.type === AST_NODE_TYPES.Identifier) : void 0;
298
+ if (namedParam)
299
+ return "testContext";
284
300
  const importDetails = describePossibleImportDef(def);
285
301
  if (importDetails?.local === identifier)
286
302
  return importDetails;
@@ -3662,8 +3678,12 @@ const requireLocalTestContextForConcurrentSnapshots = createEslintRule({
3662
3678
  create(context) {
3663
3679
  return {
3664
3680
  CallExpression(node) {
3665
- const isNotAnAssertion = !isTypeOfVitestFnCall(node, context, ["expect"]);
3666
- if (isNotAnAssertion)
3681
+ const vitestFnCall = parseVitestFnCall(node, context);
3682
+ if (vitestFnCall === null)
3683
+ return;
3684
+ if (vitestFnCall.type !== "expect")
3685
+ return;
3686
+ if (vitestFnCall.type === "expect" && vitestFnCall.head.type === "testContext")
3667
3687
  return;
3668
3688
  const isNotASnapshotAssertion = ![
3669
3689
  "toMatchSnapshot",
@@ -4052,6 +4072,7 @@ const preferExpectAssertions = createEslintRule({
4052
4072
  let hasExpectInCallBack = false;
4053
4073
  let hasExpectInLoop = false;
4054
4074
  let hasExpectAssertAsFirstStatement = false;
4075
+ let testContextName = null;
4055
4076
  let inTestCaseCall = false;
4056
4077
  let inForLoop = false;
4057
4078
  const shouldCheckFunction = (testFunction) => {
@@ -4125,6 +4146,9 @@ const preferExpectAssertions = createEslintRule({
4125
4146
  inTestCaseCall = true;
4126
4147
  return;
4127
4148
  }
4149
+ if (vitestFnCall?.head.type === "testContext" && vitestFnCall.members[0].type === AST_NODE_TYPES.Identifier && vitestFnCall.members[0].name === "expect") {
4150
+ testContextName = `${vitestFnCall.head.local}`;
4151
+ }
4128
4152
  if (vitestFnCall?.type === "expect" && inTestCaseCall) {
4129
4153
  if (expressionDepth === 1 && isFirstStatement(node) && vitestFnCall.head.node.parent?.type === AST_NODE_TYPES.MemberExpression && vitestFnCall.members.length === 1 && ["assertions", "hasAssertions"].includes(getAccessorValue(vitestFnCall.members[0]))) {
4130
4154
  checkExpectHasAssertions(vitestFnCall, node);
@@ -4143,12 +4167,6 @@ const preferExpectAssertions = createEslintRule({
4143
4167
  if (node.arguments.length < 2)
4144
4168
  return;
4145
4169
  const [, secondArg] = node.arguments;
4146
- if (secondArg?.type === AST_NODE_TYPES.ArrowFunctionExpression && secondArg.params.length) {
4147
- if (secondArg?.params[0].type === AST_NODE_TYPES.ObjectPattern) {
4148
- if (secondArg.params[0].properties[0].type === AST_NODE_TYPES.Property && secondArg.params[0].properties[0].key.type === AST_NODE_TYPES.Identifier && secondArg.params[0].properties[0].key.name === "expect")
4149
- return;
4150
- }
4151
- }
4152
4170
  if (!isFunction(secondArg) || !shouldCheckFunction(secondArg))
4153
4171
  return;
4154
4172
  hasExpectInLoop = false;
@@ -4159,9 +4177,10 @@ const preferExpectAssertions = createEslintRule({
4159
4177
  }
4160
4178
  const suggestions = [];
4161
4179
  if (secondArg.body.type === AST_NODE_TYPES.BlockStatement) {
4180
+ const prefix = testContextName ? `${testContextName}.` : "";
4162
4181
  suggestions.push(
4163
- ["suggestAddingHasAssertions", "expect.hasAssertions();"],
4164
- ["suggestAddingAssertions", "expect.assertions();"]
4182
+ ["suggestAddingHasAssertions", `${prefix}expect.hasAssertions();`],
4183
+ ["suggestAddingAssertions", `${prefix}expect.assertions();`]
4165
4184
  );
4166
4185
  }
4167
4186
  context.report({
@@ -4979,6 +4998,8 @@ const plugin = {
4979
4998
  test: "writable",
4980
4999
  describe: "writable",
4981
5000
  it: "writable",
5001
+ expectTypeOf: "writable",
5002
+ assertType: "writable",
4982
5003
  expect: "writable",
4983
5004
  assert: "writable",
4984
5005
  vitest: "writable",
@@ -4986,7 +5007,9 @@ const plugin = {
4986
5007
  beforeAll: "writable",
4987
5008
  afterAll: "writable",
4988
5009
  beforeEach: "writable",
4989
- afterEach: "writable"
5010
+ afterEach: "writable",
5011
+ onTestFailed: "writable",
5012
+ onTestFinished: "writable"
4990
5013
  }
4991
5014
  }
4992
5015
  }
@@ -4998,6 +5021,8 @@ const plugin = {
4998
5021
  test: true,
4999
5022
  describe: true,
5000
5023
  it: true,
5024
+ expectTypeOf: true,
5025
+ assertType: true,
5001
5026
  expect: true,
5002
5027
  assert: true,
5003
5028
  vitest: true,
@@ -5005,7 +5030,9 @@ const plugin = {
5005
5030
  beforeAll: true,
5006
5031
  afterAll: true,
5007
5032
  beforeEach: true,
5008
- afterEach: true
5033
+ afterEach: true,
5034
+ onTestFailed: true,
5035
+ onTestFinished: true
5009
5036
  }
5010
5037
  }
5011
5038
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitest/eslint-plugin",
3
- "version": "1.1.16",
3
+ "version": "1.1.18",
4
4
  "license": "MIT",
5
5
  "description": "Eslint plugin for vitest",
6
6
  "repository": "vitest-dev/eslint-plugin-vitest",