You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
9 lines
124 KiB
JavaScript
9 lines
124 KiB
JavaScript
import{ESLintUtils as ae,AST_NODE_TYPES as i,AST_TOKEN_TYPES as Rt}from"@typescript-eslint/utils";import j from"typescript";import{isAbsolute as Ws,posix as Hs}from"node:path";import{createRequire as Nt}from"node:module";import{DefinitionType as Bt}from"@typescript-eslint/scope-manager";const Vs="1.3.20",f=ae.RuleCreator(e=>`https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/${e}.md`),Ks=(e,s)=>e&&s?`${e}.${s}`:null,S=e=>e.type===i.FunctionExpression||e.type===i.ArrowFunctionExpression;function O(e){if(C(e))return y(e);switch(e.type){case i.TaggedTemplateExpression:return O(e.tag);case i.MemberExpression:return Ks(O(e.object),O(e.property));case i.NewExpression:case i.CallExpression:return O(e.callee)}return null}const C=(e,s)=>N(e,s)||B(e,s),N=(e,s)=>e.type===i.Identifier&&(s===void 0||e.name===s),Gs=(e,s)=>e.type===i.TemplateLiteral&&e.quasis.length===1&&(s===void 0||e.quasis[0].value.raw===s),Xs=(e,s)=>e.type===i.Literal&&typeof e.value=="string"&&(s===void 0||e.value===s),B=(e,s)=>Xs(e,s)||Gs(e,s),y=e=>e.type===i.Identifier?e.name:W(e),W=e=>e?.type===i.TemplateLiteral?e.quasis[0].value.raw:e?.value,X=(e,s,t)=>e.replaceText(s,s.type===i.Identifier?t:`'${t}'`),Lt=(e,s,t,r)=>{const n=t.arguments[r],o=t.arguments[t.arguments.length-1],{sourceCode:a}=s;let c=a.getTokenAfter(o);return c.value===","&&(c=a.getTokenAfter(c)),e.removeRange([n.range[0],c.range[0]])},zs=(e,s)=>y(e.matcher)==="toBeInstanceOf"&&e.args.length===1&&C(e.args[0],s);var _=(e=>(e.vi="vi",e.vitest="vitest",e))(_||{}),H=(e=>(e.describe="describe",e.fdescribe="fdescribe",e.xdescribe="xdescribe",e))(H||{}),A=(e=>(e.fit="fit",e.it="it",e.test="test",e.xit="xit",e.xtest="xtest",e.bench="bench",e))(A||{}),Ft=(e=>(e.beforeAll="beforeAll",e.beforeEach="beforeEach",e.afterAll="afterAll",e.afterEach="afterEach",e))(Ft||{}),R=(e=>(e.to="to",e.have="have",e.not="not",e.rejects="rejects",e.resolves="resolves",e.returns="returns",e.branded="branded",e.asserts="asserts",e.constructorParameters="constructorParameters",e.parameters="parameters",e.thisParameter="thisParameter",e.guards="guards",e.instance="instance",e.items="items",e))(R||{}),L=(e=>(e.toBe="toBe",e.toEqual="toEqual",e.toStrictEqual="toStrictEqual",e))(L||{});function Pt(e){return e.getCallSignatures().length>0?!0:e.getSymbol()?.getDeclarations()?.some(s=>j.isArrowFunction(s)||j.isClassDeclaration(s)||j.isClassExpression(s)||j.isFunctionDeclaration(s)||j.isFunctionExpression(s)||j.isMethodDeclaration(s)||j.isFunctionTypeNode(s))??!1}const Ys=new Set(["beforeEach","beforeAll","afterEach","afterAll","it","it.skip","it.only","it.concurrent","it.sequential","it.todo","it.fails","it.extend","it.skipIf","it.runIf","it.each","it.skip.only","it.skip.concurrent","it.skip.sequential","it.skip.todo","it.skip.fails","it.only.skip","it.only.concurrent","it.only.sequential","it.only.todo","it.only.fails","it.concurrent.skip","it.concurrent.only","it.concurrent.sequential","it.concurrent.todo","it.concurrent.fails","it.sequential.skip","it.sequential.only","it.sequential.concurrent","it.sequential.todo","it.sequential.fails","it.todo.skip","it.todo.only","it.todo.concurrent","it.todo.sequential","it.todo.fails","it.fails.skip","it.fails.only","it.fails.concurrent","it.fails.sequential","it.fails.todo","it.extend.skip","it.extend.only","it.extend.concurrent","it.extend.sequential","it.extend.todo","it.extend.fails","it.skipIf.skip","it.skipIf.only","it.skipIf.concurrent","it.skipIf.sequential","it.skipIf.todo","it.skipIf.fails","it.runIf.skip","it.runIf.only","it.runIf.concurrent","it.runIf.sequential","it.runIf.todo","it.runIf.fails","it.skip.each","it.only.each","it.concurrent.each","it.sequential.each","it.todo.each","it.fails.each","it.extend.skipIf","it.extend.runIf","it.extend.each","it.skipIf.each","it.runIf.each","it.skip.only.concurrent","it.skip.only.sequential","it.skip.only.todo","it.skip.only.fails","it.skip.concurrent.only","it.skip.concurrent.sequential","it.skip.concurrent.todo","it.skip.concurrent.fails","it.skip.sequential.only","it.skip.sequential.concurrent","it.skip.sequential.todo","it.skip.sequential.fails","it.skip.todo.only","it.skip.todo.concurrent","it.skip.todo.sequential","it.skip.todo.fails","it.skip.fails.only","it.skip.fails.concurrent","it.skip.fails.sequential","it.skip.fails.todo","it.only.skip.concurrent","it.only.skip.sequential","it.only.skip.todo","it.only.skip.fails","it.only.concurrent.skip","it.only.concurrent.sequential","it.only.concurrent.todo","it.only.concurrent.fails","it.only.sequential.skip","it.only.sequential.concurrent","it.only.sequential.todo","it.only.sequential.fails","it.only.todo.skip","it.only.todo.concurrent","it.only.todo.sequential","it.only.todo.fails","it.only.fails.skip","it.only.fails.concurrent","it.only.fails.sequential","it.only.fails.todo","it.concurrent.skip.only","it.concurrent.skip.sequential","it.concurrent.skip.todo","it.concurrent.skip.fails","it.concurrent.only.skip","it.concurrent.only.sequential","it.concurrent.only.todo","it.concurrent.only.fails","it.concurrent.sequential.skip","it.concurrent.sequential.only","it.concurrent.sequential.todo","it.concurrent.sequential.fails","it.concurrent.todo.skip","it.concurrent.todo.only","it.concurrent.todo.sequential","it.concurrent.todo.fails","it.concurrent.fails.skip","it.concurrent.fails.only","it.concurrent.fails.sequential","it.concurrent.fails.todo","it.sequential.skip.only","it.sequential.skip.concurrent","it.sequential.skip.todo","it.sequential.skip.fails","it.sequential.only.skip","it.sequential.only.concurrent","it.sequential.only.todo","it.sequential.only.fails","it.sequential.concurrent.skip","it.sequential.concurrent.only","it.sequential.concurrent.todo","it.sequential.concurrent.fails","it.sequential.todo.skip","it.sequential.todo.only","it.sequential.todo.concurrent","it.sequential.todo.fails","it.sequential.fails.skip","it.sequential.fails.only","it.sequential.fails.concurrent","it.sequential.fails.todo","it.todo.skip.only","it.todo.skip.concurrent","it.todo.skip.sequential","it.todo.skip.fails","it.todo.only.skip","it.todo.only.concurrent","it.todo.only.sequential","it.todo.only.fails","it.todo.concurrent.skip","it.todo.concurrent.only","it.todo.concurrent.sequential","it.todo.concurrent.fails","it.todo.sequential.skip","it.todo.sequential.only","it.todo.sequential.concurrent","it.todo.sequential.fails","it.todo.fails.skip","it.todo.fails.only","it.todo.fails.concurrent","it.todo.fails.sequential","it.fails.skip.only","it.fails.skip.concurrent","it.fails.skip.sequential","it.fails.skip.todo","it.fails.only.skip","it.fails.only.concurrent","it.fails.only.sequential","it.fails.only.todo","it.fails.concurrent.skip","it.fails.concurrent.only","it.fails.concurrent.sequential","it.fails.concurrent.todo","it.fails.sequential.skip","it.fails.sequential.only","it.fails.sequential.concurrent","it.fails.sequential.todo","it.fails.todo.skip","it.fails.todo.only","it.fails.todo.concurrent","it.fails.todo.sequential","it.extend.skip.only","it.extend.skip.concurrent","it.extend.skip.sequential","it.extend.skip.todo","it.extend.skip.fails","it.extend.only.skip","it.extend.only.concurrent","it.extend.only.sequential","it.extend.only.todo","it.extend.only.fails","it.extend.concurrent.skip","it.extend.concurrent.only","it.extend.concurrent.sequential","it.extend.concurrent.todo","it.extend.concurrent.fails","it.extend.sequential.skip","it.extend.sequential.only","it.extend.sequential.concurrent","it.extend.sequential.todo","it.extend.sequential.fails","it.extend.todo.skip","it.extend.todo.only","it.extend.todo.concurrent","it.extend.todo.sequential","it.extend.todo.fails","it.extend.fails.skip","it.extend.fails.only","it.extend.fails.concurrent","it.extend.fails.sequential","it.extend.fails.todo","it.skipIf.skip.only","it.skipIf.skip.concurrent","it.skipIf.skip.sequential","it.skipIf.skip.todo","it.skipIf.skip.fails","it.skipIf.only.skip","it.skipIf.only.concurrent","it.skipIf.only.sequential","it.skipIf.only.todo","it.skipIf.only.fails","it.skipIf.concurrent.skip","it.skipIf.concurrent.only","it.skipIf.concurrent.sequential","it.skipIf.concurrent.todo","it.skipIf.concurrent.fails","it.skipIf.sequential.skip","it.skipIf.sequential.only","it.skipIf.sequential.concurrent","it.skipIf.sequential.todo","it.skipIf.sequential.fails","it.skipIf.todo.skip","it.skipIf.todo.only","it.skipIf.todo.concurrent","it.skipIf.todo.sequential","it.skipIf.todo.fails","it.skipIf.fails.skip","it.skipIf.fails.only","it.skipIf.fails.concurrent","it.skipIf.fails.sequential","it.skipIf.fails.todo","it.runIf.skip.only","it.runIf.skip.concurrent","it.runIf.skip.sequential","it.runIf.skip.todo","it.runIf.skip.fails","it.runIf.only.skip","it.runIf.only.concurrent","it.runIf.only.sequential","it.runIf.only.todo","it.runIf.only.fails","it.runIf.concurrent.skip","it.runIf.concurrent.only","it.runIf.concurrent.sequential","it.runIf.concurrent.todo","it.runIf.concurrent.fails","it.runIf.sequential.skip","it.runIf.sequential.only","it.runIf.sequential.concurrent","it.runIf.sequential.todo","it.runIf.sequential.fails","it.runIf.todo.skip","it.runIf.todo.only","it.runIf.todo.concurrent","it.runIf.todo.sequential","it.runIf.todo.fails","it.runIf.fails.skip","it.runIf.fails.only","it.runIf.fails.concurrent","it.runIf.fails.sequential","it.runIf.fails.todo","it.skip.only.each","it.skip.concurrent.each","it.skip.sequential.each","it.skip.todo.each","it.skip.fails.each","it.only.skip.each","it.only.concurrent.each","it.only.sequential.each","it.only.todo.each","it.only.fails.each","it.concurrent.skip.each","it.concurrent.only.each","it.concurrent.sequential.each","it.concurrent.todo.each","it.concurrent.fails.each","it.sequential.skip.each","it.sequential.only.each","it.sequential.concurrent.each","it.sequential.todo.each","it.sequential.fails.each","it.todo.skip.each","it.todo.only.each","it.todo.concurrent.each","it.todo.sequential.each","it.todo.fails.each","it.fails.skip.each","it.fails.only.each","it.fails.concurrent.each","it.fails.sequential.each","it.fails.todo.each","it.extend.skipIf.skip","it.extend.skipIf.only","it.extend.skipIf.concurrent","it.extend.skipIf.sequential","it.extend.skipIf.todo","it.extend.skipIf.fails","it.extend.runIf.skip","it.extend.runIf.only","it.extend.runIf.concurrent","it.extend.runIf.sequential","it.extend.runIf.todo","it.extend.runIf.fails","it.extend.skip.each","it.extend.only.each","it.extend.concurrent.each","it.extend.sequential.each","it.extend.todo.each","it.extend.fails.each","it.skipIf.skip.each","it.skipIf.only.each","it.skipIf.concurrent.each","it.skipIf.sequential.each","it.skipIf.todo.each","it.skipIf.fails.each","it.runIf.skip.each","it.runIf.only.each","it.runIf.concurrent.each","it.runIf.sequential.each","it.runIf.todo.each","it.runIf.fails.each","it.extend.skipIf.each","it.extend.runIf.each","test","test.skip","test.only","test.concurrent","test.sequential","test.todo","test.fails","test.extend","test.skipIf","test.runIf","test.each","test.skip.only","test.skip.concurrent","test.skip.sequential","test.skip.todo","test.skip.fails","test.only.skip","test.only.concurrent","test.only.sequential","test.only.todo","test.only.fails","test.concurrent.skip","test.concurrent.only","test.concurrent.sequential","test.concurrent.todo","test.concurrent.fails","test.sequential.skip","test.sequential.only","test.sequential.concurrent","test.sequential.todo","test.sequential.fails","test.todo.skip","test.todo.only","test.todo.concurrent","test.todo.sequential","test.todo.fails","test.fails.skip","test.fails.only","test.fails.concurrent","test.fails.sequential","test.fails.todo","test.extend.skip","test.extend.only","test.extend.concurrent","test.extend.sequential","test.extend.todo","test.extend.fails","test.skipIf.skip","test.skipIf.only","test.skipIf.concurrent","test.skipIf.sequential","test.skipIf.todo","test.skipIf.fails","test.runIf.skip","test.runIf.only","test.runIf.concurrent","test.runIf.sequential","test.runIf.todo","test.runIf.fails","test.skip.each","test.only.each","test.concurrent.each","test.sequential.each","test.todo.each","test.fails.each","test.extend.skipIf","test.extend.runIf","test.extend.each","test.skipIf.each","test.runIf.each","test.skip.only.concurrent","test.skip.only.sequential","test.skip.only.todo","test.skip.only.fails","test.skip.concurrent.only","test.skip.concurrent.sequential","test.skip.concurrent.todo","test.skip.concurrent.fails","test.skip.sequential.only","test.skip.sequential.concurrent","test.skip.sequential.todo","test.skip.sequential.fails","test.skip.todo.only","test.skip.todo.concurrent","test.skip.todo.sequential","test.skip.todo.fails","test.skip.fails.only","test.skip.fails.concurrent","test.skip.fails.sequential","test.skip.fails.todo","test.only.skip.concurrent","test.only.skip.sequential","test.only.skip.todo","test.only.skip.fails","test.only.concurrent.skip","test.only.concurrent.sequential","test.only.concurrent.todo","test.only.concurrent.fails","test.only.sequential.skip","test.only.sequential.concurrent","test.only.sequential.todo","test.only.sequential.fails","test.only.todo.skip","test.only.todo.concurrent","test.only.todo.sequential","test.only.todo.fails","test.only.fails.skip","test.only.fails.concurrent","test.only.fails.sequential","test.only.fails.todo","test.concurrent.skip.only","test.concurrent.skip.sequential","test.concurrent.skip.todo","test.concurrent.skip.fails","test.concurrent.only.skip","test.concurrent.only.sequential","test.concurrent.only.todo","test.concurrent.only.fails","test.concurrent.sequential.skip","test.concurrent.sequential.only","test.concurrent.sequential.todo","test.concurrent.sequential.fails","test.concurrent.todo.skip","test.concurrent.todo.only","test.concurrent.todo.sequential","test.concurrent.todo.fails","test.concurrent.fails.skip","test.concurrent.fails.only","test.concurrent.fails.sequential","test.concurrent.fails.todo","test.sequential.skip.only","test.sequential.skip.concurrent","test.sequential.skip.todo","test.sequential.skip.fails","test.sequential.only.skip","test.sequential.only.concurrent","test.sequential.only.todo","test.sequential.only.fails","test.sequential.concurrent.skip","test.sequential.concurrent.only","test.sequential.concurrent.todo","test.sequential.concurrent.fails","test.sequential.todo.skip","test.sequential.todo.only","test.sequential.todo.concurrent","test.sequential.todo.fails","test.sequential.fails.skip","test.sequential.fails.only","test.sequential.fails.concurrent","test.sequential.fails.todo","test.todo.skip.only","test.todo.skip.concurrent","test.todo.skip.sequential","test.todo.skip.fails","test.todo.only.skip","test.todo.only.concurrent","test.todo.only.sequential","test.todo.only.fails","test.todo.concurrent.skip","test.todo.concurrent.only","test.todo.concurrent.sequential","test.todo.concurrent.fails","test.todo.sequential.skip","test.todo.sequential.only","test.todo.sequential.concurrent","test.todo.sequential.fails","test.todo.fails.skip","test.todo.fails.only","test.todo.fails.concurrent","test.todo.fails.sequential","test.fails.skip.only","test.fails.skip.concurrent","test.fails.skip.sequential","test.fails.skip.todo","test.fails.only.skip","test.fails.only.concurrent","test.fails.only.sequential","test.fails.only.todo","test.fails.concurrent.skip","test.fails.concurrent.only","test.fails.concurrent.sequential","test.fails.concurrent.todo","test.fails.sequential.skip","test.fails.sequential.only","test.fails.sequential.concurrent","test.fails.sequential.todo","test.fails.todo.skip","test.fails.todo.only","test.fails.todo.concurrent","test.fails.todo.sequential","test.extend.skip.only","test.extend.skip.concurrent","test.extend.skip.sequential","test.extend.skip.todo","test.extend.skip.fails","test.extend.only.skip","test.extend.only.concurrent","test.extend.only.sequential","test.extend.only.todo","test.extend.only.fails","test.extend.concurrent.skip","test.extend.concurrent.only","test.extend.concurrent.sequential","test.extend.concurrent.todo","test.extend.concurrent.fails","test.extend.sequential.skip","test.extend.sequential.only","test.extend.sequential.concurrent","test.extend.sequential.todo","test.extend.sequential.fails","test.extend.todo.skip","test.extend.todo.only","test.extend.todo.concurrent","test.extend.todo.sequential","test.extend.todo.fails","test.extend.fails.skip","test.extend.fails.only","test.extend.fails.concurrent","test.extend.fails.sequential","test.extend.fails.todo","test.skipIf.skip.only","test.skipIf.skip.concurrent","test.skipIf.skip.sequential","test.skipIf.skip.todo","test.skipIf.skip.fails","test.skipIf.only.skip","test.skipIf.only.concurrent","test.skipIf.only.sequential","test.skipIf.only.todo","test.skipIf.only.fails","test.skipIf.concurrent.skip","test.skipIf.concurrent.only","test.skipIf.concurrent.sequential","test.skipIf.concurrent.todo","test.skipIf.concurrent.fails","test.skipIf.sequential.skip","test.skipIf.sequential.only","test.skipIf.sequential.concurrent","test.skipIf.sequential.todo","test.skipIf.sequential.fails","test.skipIf.todo.skip","test.skipIf.todo.only","test.skipIf.todo.concurrent","test.skipIf.todo.sequential","test.skipIf.todo.fails","test.skipIf.fails.skip","test.skipIf.fails.only","test.skipIf.fails.concurrent","test.skipIf.fails.sequential","test.skipIf.fails.todo","test.runIf.skip.only","test.runIf.skip.concurrent","test.runIf.skip.sequential","test.runIf.skip.todo","test.runIf.skip.fails","test.runIf.only.skip","test.runIf.only.concurrent","test.runIf.only.sequential","test.runIf.only.todo","test.runIf.only.fails","test.runIf.concurrent.skip","test.runIf.concurrent.only","test.runIf.concurrent.sequential","test.runIf.concurrent.todo","test.runIf.concurrent.fails","test.runIf.sequential.skip","test.runIf.sequential.only","test.runIf.sequential.concurrent","test.runIf.sequential.todo","test.runIf.sequential.fails","test.runIf.todo.skip","test.runIf.todo.only","test.runIf.todo.concurrent","test.runIf.todo.sequential","test.runIf.todo.fails","test.runIf.fails.skip","test.runIf.fails.only","test.runIf.fails.concurrent","test.runIf.fails.sequential","test.runIf.fails.todo","test.skip.only.each","test.skip.concurrent.each","test.skip.sequential.each","test.skip.todo.each","test.skip.fails.each","test.only.skip.each","test.only.concurrent.each","test.only.sequential.each","test.only.todo.each","test.only.fails.each","test.concurrent.skip.each","test.concurrent.only.each","test.concurrent.sequential.each","test.concurrent.todo.each","test.concurrent.fails.each","test.sequential.skip.each","test.sequential.only.each","test.sequential.concurrent.each","test.sequential.todo.each","test.sequential.fails.each","test.todo.skip.each","test.todo.only.each","test.todo.concurrent.each","test.todo.sequential.each","test.todo.fails.each","test.fails.skip.each","test.fails.only.each","test.fails.concurrent.each","test.fails.sequential.each","test.fails.todo.each","test.extend.skipIf.skip","test.extend.skipIf.only","test.extend.skipIf.concurrent","test.extend.skipIf.sequential","test.extend.skipIf.todo","test.extend.skipIf.fails","test.extend.runIf.skip","test.extend.runIf.only","test.extend.runIf.concurrent","test.extend.runIf.sequential","test.extend.runIf.todo","test.extend.runIf.fails","test.extend.skip.each","test.extend.only.each","test.extend.concurrent.each","test.extend.sequential.each","test.extend.todo.each","test.extend.fails.each","test.skipIf.skip.each","test.skipIf.only.each","test.skipIf.concurrent.each","test.skipIf.sequential.each","test.skipIf.todo.each","test.skipIf.fails.each","test.runIf.skip.each","test.runIf.only.each","test.runIf.concurrent.each","test.runIf.sequential.each","test.runIf.todo.each","test.runIf.fails.each","test.extend.skipIf.each","test.extend.runIf.each","bench","bench.skip","bench.only","bench.todo","bench.skipIf","bench.runIf","bench.skip.only","bench.skip.todo","bench.only.skip","bench.only.todo","bench.todo.skip","bench.todo.only","bench.skipIf.skip","bench.skipIf.only","bench.skipIf.todo","bench.runIf.skip","bench.runIf.only","bench.runIf.todo","bench.skip.only.todo","bench.skip.todo.only","bench.only.skip.todo","bench.only.todo.skip","bench.todo.skip.only","bench.todo.only.skip","bench.skipIf.skip.only","bench.skipIf.skip.todo","bench.skipIf.only.skip","bench.skipIf.only.todo","bench.skipIf.todo.skip","bench.skipIf.todo.only","bench.runIf.skip.only","bench.runIf.skip.todo","bench.runIf.only.skip","bench.runIf.only.todo","bench.runIf.todo.skip","bench.runIf.todo.only","describe","describe.skip","describe.only","describe.concurrent","describe.sequential","describe.shuffle","describe.todo","describe.skipIf","describe.runIf","describe.each","describe.skip.only","describe.skip.concurrent","describe.skip.sequential","describe.skip.shuffle","describe.skip.todo","describe.only.skip","describe.only.concurrent","describe.only.sequential","describe.only.shuffle","describe.only.todo","describe.concurrent.skip","describe.concurrent.only","describe.concurrent.sequential","describe.concurrent.shuffle","describe.concurrent.todo","describe.sequential.skip","describe.sequential.only","describe.sequential.concurrent","describe.sequential.shuffle","describe.sequential.todo","describe.shuffle.skip","describe.shuffle.only","describe.shuffle.concurrent","describe.shuffle.sequential","describe.shuffle.todo","describe.todo.skip","describe.todo.only","describe.todo.concurrent","describe.todo.sequential","describe.todo.shuffle","describe.skipIf.skip","describe.skipIf.only","describe.skipIf.concurrent","describe.skipIf.sequential","describe.skipIf.shuffle","describe.skipIf.todo","describe.runIf.skip","describe.runIf.only","describe.runIf.concurrent","describe.runIf.sequential","describe.runIf.shuffle","describe.runIf.todo","describe.skip.each","describe.only.each","describe.concurrent.each","describe.sequential.each","describe.shuffle.each","describe.todo.each","describe.skipIf.each","describe.runIf.each","describe.skip.only.concurrent","describe.skip.only.sequential","describe.skip.only.shuffle","describe.skip.only.todo","describe.skip.concurrent.only","describe.skip.concurrent.sequential","describe.skip.concurrent.shuffle","describe.skip.concurrent.todo","describe.skip.sequential.only","describe.skip.sequential.concurrent","describe.skip.sequential.shuffle","describe.skip.sequential.todo","describe.skip.shuffle.only","describe.skip.shuffle.concurrent","describe.skip.shuffle.sequential","describe.skip.shuffle.todo","describe.skip.todo.only","describe.skip.todo.concurrent","describe.skip.todo.sequential","describe.skip.todo.shuffle","describe.only.skip.concurrent","describe.only.skip.sequential","describe.only.skip.shuffle","describe.only.skip.todo","describe.only.concurrent.skip","describe.only.concurrent.sequential","describe.only.concurrent.shuffle","describe.only.concurrent.todo","describe.only.sequential.skip","describe.only.sequential.concurrent","describe.only.sequential.shuffle","describe.only.sequential.todo","describe.only.shuffle.skip","describe.only.shuffle.concurrent","describe.only.shuffle.sequential","describe.only.shuffle.todo","describe.only.todo.skip","describe.only.todo.concurrent","describe.only.todo.sequential","describe.only.todo.shuffle","describe.concurrent.skip.only","describe.concurrent.skip.sequential","describe.concurrent.skip.shuffle","describe.concurrent.skip.todo","describe.concurrent.only.skip","describe.concurrent.only.sequential","describe.concurrent.only.shuffle","describe.concurrent.only.todo","describe.concurrent.sequential.skip","describe.concurrent.sequential.only","describe.concurrent.sequential.shuffle","describe.concurrent.sequential.todo","describe.concurrent.shuffle.skip","describe.concurrent.shuffle.only","describe.concurrent.shuffle.sequential","describe.concurrent.shuffle.todo","describe.concurrent.todo.skip","describe.concurrent.todo.only","describe.concurrent.todo.sequential","describe.concurrent.todo.shuffle","describe.sequential.skip.only","describe.sequential.skip.concurrent","describe.sequential.skip.shuffle","describe.sequential.skip.todo","describe.sequential.only.skip","describe.sequential.only.concurrent","describe.sequential.only.shuffle","describe.sequential.only.todo","describe.sequential.concurrent.skip","describe.sequential.concurrent.only","describe.sequential.concurrent.shuffle","describe.sequential.concurrent.todo","describe.sequential.shuffle.skip","describe.sequential.shuffle.only","describe.sequential.shuffle.concurrent","describe.sequential.shuffle.todo","describe.sequential.todo.skip","describe.sequential.todo.only","describe.sequential.todo.concurrent","describe.sequential.todo.shuffle","describe.shuffle.skip.only","describe.shuffle.skip.concurrent","describe.shuffle.skip.sequential","describe.shuffle.skip.todo","describe.shuffle.only.skip","describe.shuffle.only.concurrent","describe.shuffle.only.sequential","describe.shuffle.only.todo","describe.shuffle.concurrent.skip","describe.shuffle.concurrent.only","describe.shuffle.concurrent.sequential","describe.shuffle.concurrent.todo","describe.shuffle.sequential.skip","describe.shuffle.sequential.only","describe.shuffle.sequential.concurrent","describe.shuffle.sequential.todo","describe.shuffle.todo.skip","describe.shuffle.todo.only","describe.shuffle.todo.concurrent","describe.shuffle.todo.sequential","describe.todo.skip.only","describe.todo.skip.concurrent","describe.todo.skip.sequential","describe.todo.skip.shuffle","describe.todo.only.skip","describe.todo.only.concurrent","describe.todo.only.sequential","describe.todo.only.shuffle","describe.todo.concurrent.skip","describe.todo.concurrent.only","describe.todo.concurrent.sequential","describe.todo.concurrent.shuffle","describe.todo.sequential.skip","describe.todo.sequential.only","describe.todo.sequential.concurrent","describe.todo.sequential.shuffle","describe.todo.shuffle.skip","describe.todo.shuffle.only","describe.todo.shuffle.concurrent","describe.todo.shuffle.sequential","describe.skipIf.skip.only","describe.skipIf.skip.concurrent","describe.skipIf.skip.sequential","describe.skipIf.skip.shuffle","describe.skipIf.skip.todo","describe.skipIf.only.skip","describe.skipIf.only.concurrent","describe.skipIf.only.sequential","describe.skipIf.only.shuffle","describe.skipIf.only.todo","describe.skipIf.concurrent.skip","describe.skipIf.concurrent.only","describe.skipIf.concurrent.sequential","describe.skipIf.concurrent.shuffle","describe.skipIf.concurrent.todo","describe.skipIf.sequential.skip","describe.skipIf.sequential.only","describe.skipIf.sequential.concurrent","describe.skipIf.sequential.shuffle","describe.skipIf.sequential.todo","describe.skipIf.shuffle.skip","describe.skipIf.shuffle.only","describe.skipIf.shuffle.concurrent","describe.skipIf.shuffle.sequential","describe.skipIf.shuffle.todo","describe.skipIf.todo.skip","describe.skipIf.todo.only","describe.skipIf.todo.concurrent","describe.skipIf.todo.sequential","describe.skipIf.todo.shuffle","describe.runIf.skip.only","describe.runIf.skip.concurrent","describe.runIf.skip.sequential","describe.runIf.skip.shuffle","describe.runIf.skip.todo","describe.runIf.only.skip","describe.runIf.only.concurrent","describe.runIf.only.sequential","describe.runIf.only.shuffle","describe.runIf.only.todo","describe.runIf.concurrent.skip","describe.runIf.concurrent.only","describe.runIf.concurrent.sequential","describe.runIf.concurrent.shuffle","describe.runIf.concurrent.todo","describe.runIf.sequential.skip","describe.runIf.sequential.only","describe.runIf.sequential.concurrent","describe.runIf.sequential.shuffle","describe.runIf.sequential.todo","describe.runIf.shuffle.skip","describe.runIf.shuffle.only","describe.runIf.shuffle.concurrent","describe.runIf.shuffle.sequential","describe.runIf.shuffle.todo","describe.runIf.todo.skip","describe.runIf.todo.only","describe.runIf.todo.concurrent","describe.runIf.todo.sequential","describe.runIf.todo.shuffle","describe.skip.only.each","describe.skip.concurrent.each","describe.skip.sequential.each","describe.skip.shuffle.each","describe.skip.todo.each","describe.only.skip.each","describe.only.concurrent.each","describe.only.sequential.each","describe.only.shuffle.each","describe.only.todo.each","describe.concurrent.skip.each","describe.concurrent.only.each","describe.concurrent.sequential.each","describe.concurrent.shuffle.each","describe.concurrent.todo.each","describe.sequential.skip.each","describe.sequential.only.each","describe.sequential.concurrent.each","describe.sequential.shuffle.each","describe.sequential.todo.each","describe.shuffle.skip.each","describe.shuffle.only.each","describe.shuffle.concurrent.each","describe.shuffle.sequential.each","describe.shuffle.todo.each","describe.todo.skip.each","describe.todo.only.each","describe.todo.concurrent.each","describe.todo.sequential.each","describe.todo.shuffle.each","describe.skipIf.skip.each","describe.skipIf.only.each","describe.skipIf.concurrent.each","describe.skipIf.sequential.each","describe.skipIf.shuffle.each","describe.skipIf.todo.each","describe.runIf.skip.each","describe.runIf.only.each","describe.runIf.concurrent.each","describe.runIf.sequential.each","describe.runIf.shuffle.each","describe.runIf.todo.each","suite","suite.skip","suite.only","suite.concurrent","suite.sequential","suite.shuffle","suite.todo","suite.skipIf","suite.runIf","suite.each","suite.skip.only","suite.skip.concurrent","suite.skip.sequential","suite.skip.shuffle","suite.skip.todo","suite.only.skip","suite.only.concurrent","suite.only.sequential","suite.only.shuffle","suite.only.todo","suite.concurrent.skip","suite.concurrent.only","suite.concurrent.sequential","suite.concurrent.shuffle","suite.concurrent.todo","suite.sequential.skip","suite.sequential.only","suite.sequential.concurrent","suite.sequential.shuffle","suite.sequential.todo","suite.shuffle.skip","suite.shuffle.only","suite.shuffle.concurrent","suite.shuffle.sequential","suite.shuffle.todo","suite.todo.skip","suite.todo.only","suite.todo.concurrent","suite.todo.sequential","suite.todo.shuffle","suite.skipIf.skip","suite.skipIf.only","suite.skipIf.concurrent","suite.skipIf.sequential","suite.skipIf.shuffle","suite.skipIf.todo","suite.runIf.skip","suite.runIf.only","suite.runIf.concurrent","suite.runIf.sequential","suite.runIf.shuffle","suite.runIf.todo","suite.skip.each","suite.only.each","suite.concurrent.each","suite.sequential.each","suite.shuffle.each","suite.todo.each","suite.skipIf.each","suite.runIf.each","suite.skip.only.concurrent","suite.skip.only.sequential","suite.skip.only.shuffle","suite.skip.only.todo","suite.skip.concurrent.only","suite.skip.concurrent.sequential","suite.skip.concurrent.shuffle","suite.skip.concurrent.todo","suite.skip.sequential.only","suite.skip.sequential.concurrent","suite.skip.sequential.shuffle","suite.skip.sequential.todo","suite.skip.shuffle.only","suite.skip.shuffle.concurrent","suite.skip.shuffle.sequential","suite.skip.shuffle.todo","suite.skip.todo.only","suite.skip.todo.concurrent","suite.skip.todo.sequential","suite.skip.todo.shuffle","suite.only.skip.concurrent","suite.only.skip.sequential","suite.only.skip.shuffle","suite.only.skip.todo","suite.only.concurrent.skip","suite.only.concurrent.sequential","suite.only.concurrent.shuffle","suite.only.concurrent.todo","suite.only.sequential.skip","suite.only.sequential.concurrent","suite.only.sequential.shuffle","suite.only.sequential.todo","suite.only.shuffle.skip","suite.only.shuffle.concurrent","suite.only.shuffle.sequential","suite.only.shuffle.todo","suite.only.todo.skip","suite.only.todo.concurrent","suite.only.todo.sequential","suite.only.todo.shuffle","suite.concurrent.skip.only","suite.concurrent.skip.sequential","suite.concurrent.skip.shuffle","suite.concurrent.skip.todo","suite.concurrent.only.skip","suite.concurrent.only.sequential","suite.concurrent.only.shuffle","suite.concurrent.only.todo","suite.concurrent.sequential.skip","suite.concurrent.sequential.only","suite.concurrent.sequential.shuffle","suite.concurrent.sequential.todo","suite.concurrent.shuffle.skip","suite.concurrent.shuffle.only","suite.concurrent.shuffle.sequential","suite.concurrent.shuffle.todo","suite.concurrent.todo.skip","suite.concurrent.todo.only","suite.concurrent.todo.sequential","suite.concurrent.todo.shuffle","suite.sequential.skip.only","suite.sequential.skip.concurrent","suite.sequential.skip.shuffle","suite.sequential.skip.todo","suite.sequential.only.skip","suite.sequential.only.concurrent","suite.sequential.only.shuffle","suite.sequential.only.todo","suite.sequential.concurrent.skip","suite.sequential.concurrent.only","suite.sequential.concurrent.shuffle","suite.sequential.concurrent.todo","suite.sequential.shuffle.skip","suite.sequential.shuffle.only","suite.sequential.shuffle.concurrent","suite.sequential.shuffle.todo","suite.sequential.todo.skip","suite.sequential.todo.only","suite.sequential.todo.concurrent","suite.sequential.todo.shuffle","suite.shuffle.skip.only","suite.shuffle.skip.concurrent","suite.shuffle.skip.sequential","suite.shuffle.skip.todo","suite.shuffle.only.skip","suite.shuffle.only.concurrent","suite.shuffle.only.sequential","suite.shuffle.only.todo","suite.shuffle.concurrent.skip","suite.shuffle.concurrent.only","suite.shuffle.concurrent.sequential","suite.shuffle.concurrent.todo","suite.shuffle.sequential.skip","suite.shuffle.sequential.only","suite.shuffle.sequential.concurrent","suite.shuffle.sequential.todo","suite.shuffle.todo.skip","suite.shuffle.todo.only","suite.shuffle.todo.concurrent","suite.shuffle.todo.sequential","suite.todo.skip.only","suite.todo.skip.concurrent","suite.todo.skip.sequential","suite.todo.skip.shuffle","suite.todo.only.skip","suite.todo.only.concurrent","suite.todo.only.sequential","suite.todo.only.shuffle","suite.todo.concurrent.skip","suite.todo.concurrent.only","suite.todo.concurrent.sequential","suite.todo.concurrent.shuffle","suite.todo.sequential.skip","suite.todo.sequential.only","suite.todo.sequential.concurrent","suite.todo.sequential.shuffle","suite.todo.shuffle.skip","suite.todo.shuffle.only","suite.todo.shuffle.concurrent","suite.todo.shuffle.sequential","suite.skipIf.skip.only","suite.skipIf.skip.concurrent","suite.skipIf.skip.sequential","suite.skipIf.skip.shuffle","suite.skipIf.skip.todo","suite.skipIf.only.skip","suite.skipIf.only.concurrent","suite.skipIf.only.sequential","suite.skipIf.only.shuffle","suite.skipIf.only.todo","suite.skipIf.concurrent.skip","suite.skipIf.concurrent.only","suite.skipIf.concurrent.sequential","suite.skipIf.concurrent.shuffle","suite.skipIf.concurrent.todo","suite.skipIf.sequential.skip","suite.skipIf.sequential.only","suite.skipIf.sequential.concurrent","suite.skipIf.sequential.shuffle","suite.skipIf.sequential.todo","suite.skipIf.shuffle.skip","suite.skipIf.shuffle.only","suite.skipIf.shuffle.concurrent","suite.skipIf.shuffle.sequential","suite.skipIf.shuffle.todo","suite.skipIf.todo.skip","suite.skipIf.todo.only","suite.skipIf.todo.concurrent","suite.skipIf.todo.sequential","suite.skipIf.todo.shuffle","suite.runIf.skip.only","suite.runIf.skip.concurrent","suite.runIf.skip.sequential","suite.runIf.skip.shuffle","suite.runIf.skip.todo","suite.runIf.only.skip","suite.runIf.only.concurrent","suite.runIf.only.sequential","suite.runIf.only.shuffle","suite.runIf.only.todo","suite.runIf.concurrent.skip","suite.runIf.concurrent.only","suite.runIf.concurrent.sequential","suite.runIf.concurrent.shuffle","suite.runIf.concurrent.todo","suite.runIf.sequential.skip","suite.runIf.sequential.only","suite.runIf.sequential.concurrent","suite.runIf.sequential.shuffle","suite.runIf.sequential.todo","suite.runIf.shuffle.skip","suite.runIf.shuffle.only","suite.runIf.shuffle.concurrent","suite.runIf.shuffle.sequential","suite.runIf.shuffle.todo","suite.runIf.todo.skip","suite.runIf.todo.only","suite.runIf.todo.concurrent","suite.runIf.todo.sequential","suite.runIf.todo.shuffle","suite.skip.only.each","suite.skip.concurrent.each","suite.skip.sequential.each","suite.skip.shuffle.each","suite.skip.todo.each","suite.only.skip.each","suite.only.concurrent.each","suite.only.sequential.each","suite.only.shuffle.each","suite.only.todo.each","suite.concurrent.skip.each","suite.concurrent.only.each","suite.concurrent.sequential.each","suite.concurrent.shuffle.each","suite.concurrent.todo.each","suite.sequential.skip.each","suite.sequential.only.each","suite.sequential.concurrent.each","suite.sequential.shuffle.each","suite.sequential.todo.each","suite.shuffle.skip.each","suite.shuffle.only.each","suite.shuffle.concurrent.each","suite.shuffle.sequential.each","suite.shuffle.todo.each","suite.todo.skip.each","suite.todo.only.each","suite.todo.concurrent.each","suite.todo.sequential.each","suite.todo.shuffle.each","suite.skipIf.skip.each","suite.skipIf.only.each","suite.skipIf.concurrent.each","suite.skipIf.sequential.each","suite.skipIf.shuffle.each","suite.skipIf.todo.each","suite.runIf.skip.each","suite.runIf.only.each","suite.runIf.concurrent.each","suite.runIf.sequential.each","suite.runIf.shuffle.each","suite.runIf.todo.each","xtest","xtest.each","xit","xit.each","fit","xdescribe","xdescribe.each","fdescribe"]);function ce(e,s){return e.sourceCode.getScope?e.sourceCode.getScope(s):e.getScope()}function Js(e,s){let t=ce(e,s);for(;t;){if(t.type==="module")return t;t=t.upper}return t}const w=(e,s,t)=>{const r=g(e,s);return r!==null&&t.includes(r.type)},g=(e,s)=>{const t=jt(e,s);return typeof t=="string"?null:t},Ut=new WeakMap,jt=(e,s)=>{let t=Ut.get(e);return t||(t=tn(e,s),Ut.set(e,t),t)},Qs=e=>e==="expect"?"expect":e==="expectTypeOf"?"expectTypeOf":e==="vi"?"vi":e==="vitest"?"vitest":H.hasOwnProperty(e)?"describe":A.hasOwnProperty(e)?"test":Ft.hasOwnProperty(e)?"hook":"unknown",Zs=e=>{const s=[];for(const t of e){if(t.parent?.type===i.MemberExpression&&t.parent.parent?.type===i.CallExpression)return{matcher:t,args:t.parent.parent.arguments,modifiers:s};const r=y(t);if(s.length===0){if(!R.hasOwnProperty(r))return"modifier-unknown"}else if(s.length===1){if(r!==R.not&&r!=R.have)return"modifier-unknown";const n=y(s[0]);if(n!==R.resolves&&n!==R.rejects&&n!==R.to)return"modifier-unknown"}else return"modifier-unknown";s.push(t)}return"matcher-not-found"},en=(e,s)=>{const t=Zs(e.members);return typeof t=="string"?t:{...e,type:s,...t}},_t=e=>{let s=e,{parent:t}=e;for(;t;){if(t.type===i.CallExpression){s=t,t=t.parent;continue}if(t.type!==i.MemberExpression)break;t=t.parent}return s},tn=(e,s)=>{const t=V(e);if(!t?.length)return null;const[r,...n]=t,o=y(t[t.length-1]);if(o==="each"&&e.callee.type!==i.CallExpression&&e.callee.type!==i.TaggedTemplateExpression||e.callee.type===i.TaggedTemplateExpression&&o!=="each")return null;const a=nn(s,e,y(r));if(!a)return null;const c=a.original??a.local,l=[c,...n.map(y)];if(a.type!=="testContext"&&c!=="vi"&&c!=="vitest"&&c!=="expect"&&c!=="expectTypeOf"&&!Ys.has(l.join(".")))return null;const u={name:c,head:{...a,node:r},members:n},p=Qs(c);if(p==="expect"||p==="expectTypeOf"){const d=en(u,p);return typeof d=="string"&&_t(e)!==e?null:d==="matcher-not-found"&&e.parent?.type===i.MemberExpression?"matcher-not-called":d}return t.slice(0,t.length-1).some(d=>d.parent?.type!==i.MemberExpression)||e.parent?.type===i.CallExpression||e.parent?.type===i.MemberExpression?null:{...u,type:p}},sn=(e,s)=>e&&s?[...e,...s]:null;function V(e){if(C(e))return[e];switch(e.type){case i.TaggedTemplateExpression:return V(e.tag);case i.MemberExpression:return sn(V(e.object),V(e.property));case i.CallExpression:return V(e.callee)}return null}const nn=(e,s,t)=>{const r=ce(e,s),n=Dt(r,t);return n==="local"?null:n==="testContext"?{local:t,original:null,type:"testContext"}:n?n.source==="vitest"?{original:n.imported,local:n.local,type:"import"}:null:{original:rn(t,e),local:t,type:"global"}},rn=(e,s)=>{const t=s.settings.vitest?.globalAliases??{},r=Object.entries(t).find(([n,o])=>o.includes(e));return r?r[0]:null},on=({parent:e})=>e?.type===i.CallExpression&&e.callee.type===i.Identifier&&A.hasOwnProperty(e.callee.name),Dt=(e,s)=>{let t=e;for(;t!==null;){const r=t.set.get(s);if(r&&r.defs.length>0){const n=r.defs[r.defs.length-1],o=S(n.node)?n.node.params.find(l=>l.type===i.ObjectPattern):void 0;if(o){const l=o.properties.find(u=>u.type===i.Property);if((l?.key.type===i.Identifier?l.key:void 0)?.name===s)return"testContext"}if(n.node.type===i.VariableDeclarator&&n.node.id.type===i.Identifier&&A.hasOwnProperty(n.node.id.name)&&n.node.init?.type===i.CallExpression&&n.node.init.callee.type===i.MemberExpression&&N(n.node.init.callee.property,"extend"))return"testContext";const a=S(n.node)?n.node.params.find(l=>l.type===i.Identifier):void 0;if(a&&on(a.parent))return"testContext";const c=ln(n);return c?.local===s?c:"local"}t=t.upper}return null},an=e=>e.type===i.AwaitExpression?e.argument.type===i.ImportExpression?e.argument.source:null:e.type===i.CallExpression&&N(e.callee,"require")?e.arguments[0]??null:null,cn=e=>e.parent.type===i.TSImportEqualsDeclaration||e.node.type!==i.ImportSpecifier||e.node.imported.type!=i.Identifier||e.parent.importKind==="type"?null:{source:e.parent.source.value,imported:e.node.imported.name,local:e.node.local.name},ln=e=>e.type==="Variable"?un(e):e.type==="ImportBinding"?cn(e):null,un=e=>{if(!e.node.init)return null;const s=an(e.node.init);return!s||!B(s)||e.name.parent?.type!==i.Property||!C(e.name.parent.key)?null:{source:W(s),imported:y(e.name.parent.key),local:e.name.name}},le=(e,s)=>e.reduce((t,{references:r})=>t.concat(r.map(({identifier:n})=>n.parent).filter(n=>n?.type===i.CallExpression&&w(n,s,["test"]))),[]),P=e=>{const[s]=e.args;return s.type===i.SpreadElement?s:ue(s)},pn=e=>e.type===i.TSAsExpression||e.type===i.TSTypeAssertion,ue=e=>pn(e)?ue(e.expression):e,pe="prefer-lowercase-title",dn=e=>e.arguments[0]&&B(e.arguments[0]),fn=e=>{const s=[];return e.includes(H.describe)&&s.push(...Object.keys(H)),e.includes(A.test)&&s.push(...Object.keys(A).filter(t=>t.endsWith(A.test))),e.includes(A.it)&&s.push(...Object.keys(A).filter(t=>t.endsWith(A.it))),s},mn=f({name:pe,meta:{type:"problem",docs:{description:"enforce lowercase titles",recommended:!1},fixable:"code",messages:{lowerCaseTitle:"`{{ method }}`s should begin with lowercase",fullyLowerCaseTitle:"`{{ method }}`s should be lowercase"},schema:[{type:"object",properties:{ignore:{type:"array",items:{type:"string",enum:[H.describe,A.test,A.it]}},allowedPrefixes:{type:"array",items:{type:"string"},additionalItems:!1},ignoreTopLevelDescribe:{type:"boolean",default:!1},lowercaseFirstCharacterOnly:{type:"boolean",default:!0}},additionalProperties:!1}]},defaultOptions:[{ignore:[],allowedPrefixes:[],ignoreTopLevelDescribe:!1,lowercaseFirstCharacterOnly:!0}],create:(e,[{ignore:s=[],allowedPrefixes:t=[],ignoreTopLevelDescribe:r=!1,lowercaseFirstCharacterOnly:n=!1}])=>{const o=fn(s);let a=0;return{CallExpression(c){const l=g(c,e);if(!l||!dn)return;if(l?.type==="describe"){if(a++,r&&a===1)return}else if(l?.type!=="test")return;const[u]=c.arguments,p=W(u);if(typeof p!="string"||t.some(x=>p.startsWith(x)))return;const d=p.charAt(0);o.includes(l.name)||n&&(!d||d===d.toLowerCase())||!n&&p===p.toLowerCase()||e.report({messageId:n?"lowerCaseTitle":"fullyLowerCaseTitle",node:c.arguments[0],data:{method:l.name},fix:x=>{const m=W(u),I=[u.range[0]+1,u.range[1]-1],h=n?m.substring(0,1).toLowerCase()+m.substring(1):m.toLowerCase();return[x.replaceTextRange(I,h)]}})},"CallExpression:exit"(c){w(c,e,["describe"])&&a--}}}}),de="max-nested-describe",yn=f({name:de,meta:{type:"problem",docs:{description:"require describe block to be less than set max value or default value",recommended:!1},schema:[{type:"object",properties:{max:{type:"number"}},additionalProperties:!1}],messages:{maxNestedDescribe:"Nested describe block should be less than set max value"}},defaultOptions:[{max:5}],create(e,[{max:s}]){const t=[];function r(o){o.parent?.type==="CallExpression"&&(o.parent.callee.type!=="Identifier"||o.parent.callee.name!=="describe"||(t.push(0),t.length>s&&e.report({node:o.parent,messageId:"maxNestedDescribe"})))}function n(o){o.parent?.type==="CallExpression"&&(o.parent.callee.type!=="Identifier"||o.parent.callee.name!=="describe"||t.pop())}return{FunctionExpression:r,"FunctionExpression:exit":n,ArrowFunctionExpression:r,"ArrowFunctionExpression:exit":n}}}),z="no-identical-title",Wt=()=>({describeTitles:[],testTitles:[]}),hn=f({name:z,meta:{type:"problem",docs:{description:"disallow identical titles",recommended:!1},fixable:"code",schema:[],messages:{multipleTestTitle:"Test is used multiple times in the same describe(suite) block",multipleDescribeTitle:"Describe is used multiple times in the same describe(suite) block"}},defaultOptions:[],create(e){const s=[Wt()];return{CallExpression(t){const r=s[s.length-1],n=g(t,e);if(!n||((n.name==="describe"||n.name==="suite")&&s.push(Wt()),n.members.find(c=>C(c,"each"))))return;const[o]=t.arguments;if(!o||!B(o))return;const a=W(o);n.type==="test"&&(r?.testTitles.includes(a)&&e.report({node:t,messageId:"multipleTestTitle"}),r?.testTitles.push(a)),n.type==="describe"&&(r?.describeTitles.includes(a)&&e.report({node:t,messageId:"multipleDescribeTitle"}),r?.describeTitles.push(a))},"CallExpression:exit"(t){w(t,e,["describe"])&&s.pop()}}}}),fe="no-focused-tests",me=e=>e.type==="Identifier"&&["it","test","describe"].includes(e.name),ye=e=>e.type==="Identifier"&&e.name==="only",gn=f({name:fe,meta:{type:"problem",docs:{description:"disallow focused tests",recommended:!1},fixable:"code",schema:[{type:"object",properties:{fixable:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{noFocusedTests:"Focused tests are not allowed"}},defaultOptions:[{fixable:!0}],create:(e,s)=>{const t=s[0].fixable;return{ExpressionStatement(r){if(r.expression.type==="CallExpression"){const{callee:n}=r.expression;if(n.type==="MemberExpression"&&me(n.object)&&ye(n.property)&&e.report({node:n.property,messageId:"noFocusedTests",fix:o=>t?o.removeRange([n.property.range[0]-1,n.property.range[1]]):null}),n.type==="TaggedTemplateExpression"){const o=n.tag.type==="MemberExpression"?n.tag.object:null;if(!o)return;o.type==="MemberExpression"&&me(o.object)&&ye(o.property)&&e.report({node:o.property,messageId:"noFocusedTests",fix:a=>t?a.removeRange([o.property.range[0]-1,o.property.range[1]]):null})}}},CallExpression(r){if(r.callee.type==="CallExpression"){const{callee:n}=r.callee;if(n.type==="MemberExpression"&&n.object.type==="MemberExpression"&&me(n.object.object)&&ye(n.object.property)&&n.property.type==="Identifier"&&n.property.name==="each"){const o=n.object.property;e.report({node:n.object.property,messageId:"noFocusedTests",fix:a=>t?a.removeRange([o.range[0]-1,o.range[1]]):null})}}}}}}),he="no-conditional-tests",kn=f({name:he,meta:{type:"problem",docs:{description:"disallow conditional tests",recommended:!1},schema:[],messages:{noConditionalTests:"Avoid using if conditions in a test"}},defaultOptions:[],create(e){return{Identifier:function(s){["test","it","describe"].includes(s.name)&&s.parent?.parent?.parent?.parent?.type==="IfStatement"&&e.report({node:s,messageId:"noConditionalTests"})}}}}),bn={typecheck:!1};function Y(e){const s=typeof e.vitest!="object"||e.vitest===null?{}:e.vitest;return{...bn,...s}}const J="expect-expect",xn=f({name:J,meta:{type:"suggestion",docs:{description:"enforce having expectation in test body",recommended:!1},schema:[{type:"object",properties:{assertFunctionNames:{type:"array",items:{type:"string"}},additionalTestBlockFunctions:{type:"array",items:{type:"string"}}},additionalProperties:!1}],messages:{noAssertions:"Test has no assertions"}},defaultOptions:[{assertFunctionNames:["expect","assert"],additionalTestBlockFunctions:[]}],create(e,[{assertFunctionNames:s=["expect"],additionalTestBlockFunctions:t=[]}]){const r=[];Y(e.settings).typecheck&&s.push("expectTypeOf","assertType");const n=s.map(In);function o(a){for(const c of a){const l=c.type===i.CallExpression?r.indexOf(c):-1;if(c.type===i.FunctionDeclaration){const u=e.sourceCode.getDeclaredVariables(c),p=le(u,e);o(p)}if(l!==-1){r.splice(l,1);break}}}return{CallExpression(a){if(a.callee.type===i.Identifier&&a.callee.name==="bench"||a?.callee?.type===i.MemberExpression&&a.callee.property.type===i.Identifier&&a.callee.property.name==="extend"||a?.callee?.type===i.MemberExpression&&a.callee.property.type===i.Identifier&&a.callee.property.name==="skip")return;const c=O(a)??"";if(w(a,e,["test"])||t.includes(c)){if(a.callee.type===i.MemberExpression&&C(a.callee.property,"todo"))return;r.push(a)}else n.some(l=>l.test(c))&&o(e.sourceCode.getAncestors(a))},"Program:exit"(){r.forEach(a=>{e.report({node:a.callee,messageId:"noAssertions"})})}}}});function In(e){const s=e.split(".").map(t=>t==="**"?"[_a-z\\d\\.]*":t.replace(/\*/gu,"[a-z\\d]*"));return new RegExp(`^${s.join("\\.")}(\\.|$)`,"ui")}const ge="hoisted-apis-on-top",En=["mock","hoisted","unmock"],qn=f({name:ge,meta:{hasSuggestions:!0,type:"suggestion",docs:{description:"enforce hoisted APIs to be on top of the file"},messages:{hoistedApisOnTop:"Hoisted API is used in a runtime location in this file, but it is actually executed before this file is loaded.",suggestMoveHoistedApiToTop:"Move this hoisted API to the top of the file to better reflect its behavior.",suggestReplaceMockWithDoMock:"Replace 'vi.mock()' with 'vi.doMock()', which is not hoisted."},schema:[]},defaultOptions:[],create(e){let s=null;const t=[];return{ImportDeclaration(r){r.parent.type===i.Program&&(s=r.range[1])},CallExpression(r){if(r.callee.type!==i.MemberExpression)return;const{object:n,property:o}=r.callee;if(n.type!==i.Identifier||n.name!=="vi"||o.type!==i.Identifier)return;const a=o.name;if(En.includes(a)){if(a==="hoisted"){let c=r.parent;if(c?.type===i.AwaitExpression&&(c=c.parent),c?.type===i.VariableDeclarator&&(c=c.parent),(c?.type===i.ExpressionStatement||c?.type===i.VariableDeclaration)&&c.parent?.type===i.Program)return}else if(r.parent?.type===i.ExpressionStatement&&r.parent.parent?.type===i.Program)return;t.push(r)}},"Program:exit"(){for(const r of t){const n=[];n.push({messageId:"suggestMoveHoistedApiToTop",*fix(a){r.parent.type===i.ExpressionStatement?yield a.remove(r):yield a.replaceText(r,"undefined"),s!=null?yield a.insertTextAfterRange([s,s],`
|
|
`+e.sourceCode.getText(r)+";"):yield a.insertTextAfterRange([0,0],e.sourceCode.getText(r)+`;
|
|
`)}});const o=r.callee.property;o.name==="mock"&&n.push({messageId:"suggestReplaceMockWithDoMock",fix(a){return a.replaceText(o,"doMock")}}),e.report({node:r,messageId:"hoistedApisOnTop",suggest:n})}}}}}),ke="consistent-test-it",Ht=(e,s,t)=>r=>[r.replaceText(e.type===i.MemberExpression?e.object:e,Tn(s,t))];function Tn(e,s){return e===A.fit?"test.only":e.startsWith("f")||e.startsWith("x")?e.charAt(0)+s:s}function be(e){return e===A.test?A.it:A.test}const wn=f({name:ke,meta:{type:"suggestion",fixable:"code",docs:{description:"enforce using test or it but not both",recommended:!1},messages:{consistentMethod:"Prefer using {{ testFnKeyWork }} instead of {{ oppositeTestKeyword }}",consistentMethodWithinDescribe:"Prefer using {{ testKeywordWithinDescribe }} instead of {{ oppositeTestKeyword }} within describe"},schema:[{type:"object",properties:{fn:{type:"string",enum:[A.test,A.it]},withinDescribe:{type:"string",enum:[A.test,A.it]}},additionalProperties:!1}]},defaultOptions:[{}],create(e,s){const{fn:t,withinDescribe:r}=s[0],n=t||A.test,o=r||t||A.it,a=n===o?n:void 0;let c=0;return{ImportDeclaration(l){if(a==null||l.source.type!=="Literal"||l.source.value!=="vitest")return;const u=be(a);for(const p of l.specifiers)p.type==="ImportSpecifier"&&p.imported.type==="Identifier"&&p.local.name===p.imported.name&&p.local.name===u&&e.report({node:p,data:{testFnKeyWork:n,oppositeTestKeyword:u},messageId:"consistentMethod",fix:d=>{const x=l.specifiers.filter(m=>m.local.name!==u);if(x.length>0){const m=x.map(h=>h.local.name).join(", "),I=l.specifiers.at(-1)?.range;return I?d.replaceTextRange([l.specifiers[0].range[0],I[1]],m):null}return d.replaceText(p.local,a)}})},CallExpression(l){if(l.callee.type===i.Identifier&&l.callee.name==="bench")return;const u=g(l,e);if(!u)return;if(u.type==="describe"){c++;return}const p=l.callee.type===i.TaggedTemplateExpression?l.callee.tag:l.callee.type===i.CallExpression?l.callee.callee:l.callee;if(u.type==="test"&&c===0&&!u.name.endsWith(n)){const d=be(n);e.report({node:l.callee,data:{testFnKeyWork:n,oppositeTestKeyword:d},messageId:"consistentMethod",fix:Ht(p,u.name,n)})}else if(u.type==="test"&&c>0&&!u.name.endsWith(o)){const d=be(o);e.report({messageId:"consistentMethodWithinDescribe",node:l.callee,data:{testKeywordWithinDescribe:o,oppositeTestKeyword:d},fix:Ht(p,u.name,o)})}},"CallExpression:exit"(l){w(l,e,["describe"])&&c--}}}}),xe="consistent-vitest-vi",An=e=>e===_.vi?_.vitest:_.vi,vn=f({name:xe,meta:{type:"suggestion",fixable:"code",docs:{description:"enforce using vitest or vi but not both",recommended:!1},messages:{consistentUtil:"Prefer using {{ utilKeyword }} instead of {{ oppositeUtilKeyword }}"},schema:[{type:"object",properties:{fn:{type:"string",enum:[_.vi,_.vitest],default:_.vi}},additionalProperties:!1}]},defaultOptions:[{fn:_.vi}],create(e,s){const t=s[0].fn,r=An(t);return{ImportDeclaration(n){if(!(n.source.type!==i.Literal||n.source.value!=="vitest"))for(const o of n.specifiers)o.type===i.ImportSpecifier&&o.imported.type===i.Identifier&&o.local.name===o.imported.name&&o.imported.name===r&&e.report({node:o,messageId:"consistentUtil",data:{utilKeyword:t,oppositeUtilKeyword:r},fix:a=>{const c=n.specifiers.filter(l=>l.local.name!==r);if(c.length>0){const l=c.map(p=>p.local.name).join(", "),u=n.specifiers.at(-1)?.range;return u?a.replaceTextRange([n.specifiers[0].range[0],u[1]],l):null}return a.replaceText(o.local,t)}})},CallExpression(n){if(g(n,e)?.type!==r)return;const o=n.callee.type===i.MemberExpression?n.callee.object:n.callee;e.report({node:o,data:{utilKeyword:t,oppositeUtilKeyword:r},messageId:"consistentUtil",fix:a=>a.replaceText(o,t)})}}}}),Ie="prefer-to-be",Cn=e=>e.type===i.Literal&&e.value===null,Mn=e=>Cn(P(e)),Vt=(e,s)=>N(P(e),s),Sn=e=>Math.floor(e)!==Math.ceil(e),$n=e=>{let s=P(e);return s.type===i.Literal&&typeof s.value=="number"&&Sn(s.value)?!1:(s.type===i.UnaryExpression&&s.operator==="-"&&(s=s.argument),s.type===i.Literal?!("regex"in s):s.type===i.TemplateLiteral)},K=(e,s,t,r,n)=>{e.report({messageId:`useToBe${s}`,fix(o){const a=[X(o,t.matcher,`toBe${s}`)];return t.args?.length&&s!==""&&a.push(Lt(o,e,r,0)),n&&a.push(o.removeRange([n.range[0]-1,n.range[1]])),a},node:t.matcher})},On=f({name:Ie,meta:{type:"suggestion",docs:{description:"enforce using toBe()",recommended:!1},schema:[],fixable:"code",messages:{useToBe:"Use `toBe` instead",useToBeUndefined:"Use `toBeUndefined()` instead",useToBeDefined:"Use `toBeDefined()` instead",useToBeNull:"Use `toBeNull()` instead",useToBeNaN:"Use `toBeNaN()` instead"}},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect")return;const r=y(t.matcher),n=t.modifiers.find(o=>y(o)==="not");if(n&&["toBeUndefined","toBeDefined"].includes(r)){K(e,r==="toBeDefined"?"Undefined":"Defined",t,s,n);return}if(!(!L.hasOwnProperty(r)||t.args.length===0)){if(Mn(t)){K(e,"Null",t,s);return}if(Vt(t,"undefined")){K(e,n?"Defined":"Undefined",t,s);return}if(Vt(t,"NaN")){K(e,"NaN",t,s);return}$n(t)&&r!==L.toBe&&K(e,"",t,s)}}}}}),Ee="no-hooks",Rn=f({name:Ee,meta:{type:"suggestion",docs:{description:"disallow setup and teardown hooks",recommended:!1},schema:[{type:"object",properties:{allow:{type:"array",contains:["beforeAll","beforeEach","afterAll","afterEach"]}},additionalProperties:!1}],messages:{unexpectedHook:"Unexpected '{{ hookName }}' hook"}},defaultOptions:[{allow:[]}],create(e,[{allow:s=[]}]){return{CallExpression(t){const r=g(t,e);r?.type==="hook"&&!s.includes(r.name)&&e.report({node:t,messageId:"unexpectedHook",data:{hookName:r.name}})}}}}),qe="no-restricted-vi-methods",Nn=f({name:qe,meta:{type:"suggestion",docs:{description:"disallow specific `vi.` methods",recommended:!1},schema:[{type:"object",additionalProperties:{type:["string","null"]}}],messages:{restrictedViMethod:"Use of `{{ restriction }}` is disallowed",restrictedViMethodWithMessage:"{{ message }}"}},defaultOptions:[{}],create(e,[s]){return{CallExpression(t){const r=g(t,e);if(r?.type!=="vi"||r.members.length===0)return;const n=y(r.members[0]);if(n in s){const o=s[n];e.report({messageId:o?"restrictedViMethodWithMessage":"restrictedViMethod",data:{message:o,restriction:n},loc:{start:r.members[0].loc.start,end:r.members[r.members.length-1].loc.end}})}}}}}),Te="consistent-test-filename",Kt=/.*\.test\.[tj]sx?$/,Gt=/.*\.(test|spec)\.[tj]sx?$/,Bn=f({name:Te,meta:{type:"problem",docs:{recommended:!1,requiresTypeChecking:!1,description:"require test file pattern"},messages:{consistentTestFilename:"Use test file name pattern {{ pattern }}"},schema:[{type:"object",additionalProperties:!1,properties:{pattern:{type:"string",format:"regex",default:Kt.source},allTestPattern:{type:"string",format:"regex",default:Gt.source}}}]},defaultOptions:[{pattern:Kt,allTestPattern:Gt}],create:(e,s)=>{const{pattern:t,allTestPattern:r}=s[0],n=typeof t=="string"?new RegExp(t):t,o=typeof r=="string"?new RegExp(r):r,{filename:a}=e;return o.test(a)?{Program:c=>{n.test(a)||e.report({node:c,messageId:"consistentTestFilename",data:{pattern:n.source}})}}:{}}}),we="max-expects",Ln=f({name:we,meta:{docs:{requiresTypeChecking:!1,recommended:!1,description:"enforce a maximum number of expect per test"},messages:{maxExpect:"Too many assertion calls ({{ count }}) - maximum allowed is {{ max }}"},type:"suggestion",schema:[{type:"object",properties:{max:{type:"number"}},additionalProperties:!1}]},defaultOptions:[{max:5}],create(e,[{max:s}]){let t=0;const r=n=>{(n.parent?.type!==i.CallExpression||w(n.parent,e,["test"]))&&(t=0)};return{FunctionExpression:r,"FunctionExpression:exit":r,ArrowFunctionExpression:r,"ArrowFunctionExpression:exit":r,CallExpression(n){const o=g(n,e);o?.type!=="expect"||o.head.node.parent?.type===i.MemberExpression||(t+=1,t>s&&e.report({node:n,messageId:"maxExpect",data:{count:t,max:s}}))}}}}),Ae="no-alias-methods",Fn=f({name:Ae,meta:{docs:{description:"disallow alias methods",requiresTypeChecking:!1,recommended:!1},messages:{noAliasMethods:"Replace {{ alias }}() with its canonical name {{ canonical }}()"},type:"suggestion",fixable:"code",schema:[]},defaultOptions:[],create(e){const s={toBeCalled:"toHaveBeenCalled",toBeCalledTimes:"toHaveBeenCalledTimes",toBeCalledWith:"toHaveBeenCalledWith",lastCalledWith:"toHaveBeenLastCalledWith",nthCalledWith:"toHaveBeenNthCalledWith",toReturn:"toHaveReturned",toReturnTimes:"toHaveReturnedTimes",toReturnWith:"toHaveReturnedWith",lastReturnedWith:"toHaveLastReturnedWith",nthReturnedWith:"toHaveNthReturnedWith",toThrowError:"toThrow"};return{CallExpression(t){const r=g(t,e);if(r?.type!=="expect")return;const{matcher:n}=r,o=y(n);if(o in s){const a=s[o];e.report({messageId:"noAliasMethods",data:{alias:o,canonical:a},node:n,fix:c=>[X(c,n,a)]})}}}}}),Q="no-commented-out-tests";function Pn(e){return/^\s*[xf]?(test|it|describe)(\.\w+|\[['"]\w+['"]\])?\s*\(/mu.test(e.value)}const Un=f({name:Q,meta:{docs:{description:"disallow commented out tests",requiresTypeChecking:!1,recommended:!1},messages:{noCommentedOutTests:"Remove commented out tests - you may want to use `skip` or `only` instead"},schema:[],type:"suggestion"},defaultOptions:[],create(e){const{sourceCode:s}=e;function t(r){Pn(r)&&e.report({messageId:"noCommentedOutTests",node:r})}return{Program(){s.getAllComments().forEach(t)}}}}),ve="no-conditional-expect",Xt=e=>e.callee.type===i.MemberExpression&&C(e.callee.property,"catch"),jn=f({name:ve,meta:{type:"problem",docs:{description:"disallow conditional expects",requiresTypeChecking:!1,recommended:!1},messages:{noConditionalExpect:"Avoid calling `expect` inside conditional statements"},schema:[]},defaultOptions:[],create(e){let s=0,t=!1,r=!1;const n=()=>t&&s++,o=()=>t&&s--;return{FunctionDeclaration(a){const c=e.sourceCode.getDeclaredVariables(a);le(c,e).length>0&&(t=!0)},CallExpression(a){const{type:c}=g(a,e)??{};c==="test"&&(t=!0),Xt(a)&&(r=!0),t&&c==="expect"&&s>0&&e.report({messageId:"noConditionalExpect",node:a}),r&&c==="expect"&&e.report({messageId:"noConditionalExpect",node:a})},"CallExpression:exit"(a){w(a,e,["test"])&&(t=!1),Xt(a)&&(r=!1)},CatchClause:n,"CatchClause:exit":o,IfStatement:n,"IfStatement:exit":o,SwitchStatement:n,"SwitchStatement:exit":o,ConditionalExpression:n,"ConditionalExpression:exit":o,LogicalExpression:n,"LogicalExpression:exit":o}}}),Z="no-import-node-test",_n=f({name:Z,meta:{docs:{description:"disallow importing `node:test`",recommended:!1},type:"suggestion",messages:{noImportNodeTest:"Import from `vitest` instead of `node:test`"},fixable:"code",schema:[]},defaultOptions:[],create(e){return{ImportDeclaration(s){s.source.value==="node:test"&&e.report({messageId:"noImportNodeTest",node:s,fix:t=>t.replaceText(s.source,s.source.raw.replace("node:test","vitest"))})}}}}),Ce=new Set(["suite","test","chai","describe","it","expectTypeOf","assertType","expect","assert","vitest","vi","beforeAll","afterAll","beforeEach","afterEach","onTestFailed","onTestFinished"]),zt=e=>e.source.value==="vitest",Me=e=>e.type===i.ImportSpecifier&&e.imported.type===i.Identifier&&Ce.has(e.imported.name),Se=e=>e.type===i.Property&&e.key.type===i.Identifier&&Ce.has(e.key.name),Dn=e=>e.callee.type===i.Identifier&&Ce.has(e.callee.name),$e=e=>{if(e?.type!==i.CallExpression||e.callee.type!==i.Identifier||e.callee.name!=="require")return!1;const s=e.arguments;return s.length===1&&s[0].type===i.Literal&&s[0].value==="vitest"},Yt=e=>e.type===i.ObjectPattern,Wn=(e,s)=>{const t=s.parent,r=t.declarations;if(r.length===1)return e.remove(t);const n=r.findIndex(o=>o.range[0]===s.range[0]&&o.range[1]===s.range[1]);if(n===0){const o=r[1];return e.removeRange([s.range[0],o.range[0]])}else{const o=r[n-1];return e.removeRange([o.range[1],s.range[1]])}},Jt=(e,s,t)=>{const r=s.indexOf(t);if(r===-1)throw new Error("Target node not found in nodes array");if(r===0){const n=s[1];return e.removeRange([t.range[0],n.range[0]])}else{const n=s[r-1];return e.removeRange([n.range[1],t.range[1]])}},Oe="no-importing-vitest-globals",Hn=f({name:Oe,meta:{type:"suggestion",docs:{description:"disallow importing Vitest globals",recommended:!1},messages:{noImportingVitestGlobals:"Do not import '{{name}}' from 'vitest'. Use globals configuration instead.",noRequiringVitestGlobals:"Do not require '{{name}}' from 'vitest'. Use globals configuration instead."},fixable:"code",schema:[]},defaultOptions:[],create(e){return{ImportDeclaration(s){if(!zt(s))return;const t=s.specifiers;for(const r of t)Me(r)&&e.report({node:r,messageId:"noImportingVitestGlobals",data:{name:r.imported.name},fix(n){return t.every(o=>Me(o))?n.remove(s):Jt(n,t,r)}})},VariableDeclarator(s){if(!$e(s.init)||!Yt(s.id))return;const t=s.id.properties;for(const r of t)Se(r)&&e.report({node:r,messageId:"noRequiringVitestGlobals",data:{name:r.key.name},fix(n){return t.every(o=>Se(o))?Wn(n,s):Jt(n,t,r)}})}}}}),Re="prefer-importing-vitest-globals",Vn=f({name:Re,meta:{type:"suggestion",docs:{description:"enforce importing Vitest globals",recommended:!1},messages:{preferImportingVitestGlobals:"Import '{{name}}' from 'vitest'"},schema:[],fixable:"code"},defaultOptions:[],create(e){const s=new Set;let t,r;return{ImportDeclaration(n){if(!zt(n))return;const o=n.specifiers;for(const a of o)if(Me(a)){const c=a.imported.name;s.add(c)}t=n.specifiers},VariableDeclarator(n){if(!$e(n.init)||!Yt(n.id))return;const o=n.id.properties;for(const a of o)if(Se(a)){const c=a.key.name;s.add(c)}r=o},CallExpression(n){if(!Dn(n))return;const o=n.callee.name;if(s.has(o))return;const a=e.sourceCode.getScope(n).set.get(o);a&&a.defs.length>0&&a.defs.some(c=>!(c.type==="ImportBinding"||c.type==="Variable"&&c.node.init&&$e(c.node.init)))||e.report({node:n.callee,messageId:"preferImportingVitestGlobals",data:{name:o},fix(c){const l=e.sourceCode.ast;if(!t)if(r){const d=r[r.length-1];return c.insertTextAfter(d,`, ${o}`)}else return c.insertTextBefore(l.body[0],`import { ${o} } from 'vitest';
|
|
`);if(t.find(d=>d.type==="ImportNamespaceSpecifier"))return c.insertTextBefore(l.body[0],`import { ${o} } from 'vitest';
|
|
`);const u=t.find(d=>d.type==="ImportDefaultSpecifier");if(u)return c.insertTextAfter(u,`, { ${o} }`);const p=t[t.length-1];return c.insertTextAfter(p,`, ${o}`)}})}}}}),Ne="no-conditional-in-test",Kn=f({name:Ne,meta:{docs:{description:"disallow conditional tests",requiresTypeChecking:!1,recommended:!1},messages:{noConditionalInTest:"Remove conditional tests"},schema:[],type:"problem"},defaultOptions:[],create(e){return{IfStatement(s){s.parent?.parent?.parent?.type==="CallExpression"&&w(s.parent?.parent?.parent,e,["test","it"])&&e.report({messageId:"noConditionalInTest",node:s})}}}}),Be="no-disabled-tests",Gn=f({name:Be,meta:{type:"suggestion",docs:{description:"disallow disabled tests",recommended:!1},messages:{missingFunction:"Test is missing function argument",pending:"Call to pending()",pendingSuite:"Call to pending() within test suite",pendingTest:"Call to pending() within test",disabledSuite:"Disabled test suite - if you want to skip a test suite temporarily, use .todo() instead",disabledTest:"Disabled test - if you want to skip a test temporarily, use .todo() instead"},schema:[]},defaultOptions:[],create(e){let s=0,t=0;return{CallExpression(r){const n=g(r,e);if(!n)return;n.type==="describe"&&s++,n.type==="test"&&(t++,r.arguments.length<2&&n.members.every(a=>y(a)==="skip")&&e.report({messageId:"missingFunction",node:r}));const o=n.members.find(a=>y(a)==="skip");(n.name.startsWith("x")||o!==void 0)&&e.report({messageId:n.type==="describe"?"disabledSuite":"disabledTest",node:o??n.head.node})},"CallExpression:exit"(r){const n=g(r,e);n&&(n.type==="describe"&&s--,n.type==="test"&&t--)},'CallExpression[callee.name="pending"]'(r){const n=ce(e,r);Dt(n,"pending")||(t>0?e.report({messageId:"pendingTest",node:r}):s>0?e.report({messageId:"pendingSuite",node:r}):e.report({messageId:"pending",node:r}))}}}}),Le="no-done-callback",Xn=(e,s,t)=>{if(s)return e.arguments[1];const r=g(e,t);return r?.type==="hook"&&e.arguments.length>=1?e.arguments[0]:r?.type==="test"&&e.arguments.length>=2?e.arguments[1]:null},zn=f({name:Le,meta:{type:"suggestion",docs:{description:"disallow using a callback in asynchronous tests and hooks",recommended:!1},deprecated:!0,schema:[],messages:{noDoneCallback:"Return a promise instead of relying on callback parameter",suggestWrappingInPromise:"Wrap in `new Promise({{ callback }} => ...`",useAwaitInsteadOfCallback:"Use `await` instead of callback in async function"},hasSuggestions:!0},defaultOptions:[],create(e){return{CallExpression(s){const t=/\.each$|\.concurrent$/.test(O(s.callee)??"");if(t&&s.callee.type!==i.TaggedTemplateExpression||e.sourceCode.getAncestors(s).some(a=>a.type!==i.CallExpression||!w(a,e,["describe","test"])?!1:a.callee.type===i.MemberExpression&&C(a.callee.property,"concurrent")))return;const r=Xn(s,t,e),n=Number(t);if(!r||!S(r)||r.params.length!==1+n)return;const o=r.params[n];if(o.type!==i.Identifier){e.report({node:o,messageId:"noDoneCallback"});return}if(r.async){e.report({node:o,messageId:"useAwaitInsteadOfCallback"});return}e.report({node:s,messageId:"noDoneCallback",suggest:[{messageId:"suggestWrappingInPromise",data:{callback:o.name},fix(a){const{body:c,params:l}=r,{sourceCode:u}=e,p=u.getFirstToken(c),d=u.getLastToken(c),[x]=l,m=l[l.length-1],I=u.getTokenBefore(x);let h=u.getTokenAfter(m);if(h?.value===","&&(h=u.getTokenAfter(h)),!p||!d||!I||!h)throw new Error(`Unexpected null when attempting to fix ${e.filename} - please file an issue at https://github/veritem/eslint-plugin-vitest`);let b=a.replaceText(x,"()");I.value==="("&&h.value===")"&&(b=a.removeRange([I.range[1],h.range[0]]));let q=`new Promise(${o.name} => `,T=")",E=!0;return c.type===i.BlockStatement&&(q=`return ${q}{`,T+="}",E=!1),[b,E?a.insertTextBefore(p,q):a.insertTextAfter(p,q),a.insertTextAfter(d,T)]}}]})}}}}),Fe="no-duplicate-hooks",Yn=f({name:Fe,meta:{docs:{recommended:!1,description:"disallow duplicate hooks and teardown hooks",requiresTypeChecking:!1},messages:{noDuplicateHooks:"Duplicate {{ hook }} in describe block"},schema:[],type:"suggestion"},defaultOptions:[],create(e){const s=[{}];return{CallExpression(t){const r=g(t,e);if(r?.type==="describe"&&s.push({}),r?.type!=="hook")return;const n=s[s.length-1];n[r.name]||=0,n[r.name]+=1,n[r.name]>1&&e.report({messageId:"noDuplicateHooks",data:{hook:r.name},node:t})},"CallExpression:exit"(t){w(t,e,["describe"])&&s.pop()}}}}),Pe="no-large-snapshots",Qt=(e,s,{maxSize:t=50,allowedSnapshots:r={}})=>{const n=s.loc.start.line,o=s.loc.end.line-n;if(!Object.keys(r).every(Ws))throw new Error("All paths for allowedSnapshots must be absolute. You can use JS config and `path.resolve`");let a=!1;if(s.type===i.ExpressionStatement&&"left"in s.expression&&s.expression.left.type===i.MemberExpression&&C(s.expression.left.property)){const c=e.filename,l=r[c];if(l){const u=y(s.expression.left.property);a=l.some(p=>p instanceof RegExp?p.test(u):u===p)}}!a&&o>t&&e.report({node:s,messageId:t===0?"noSnapShot":"tooLongSnapShot",data:{lineCount:o,lineLimit:t}})},Jn=f({name:Pe,meta:{docs:{description:"disallow large snapshots",recommended:!1},messages:{noSnapShot:"`{{ lineCount }}`s should begin with lowercase",tooLongSnapShot:"Expected vitest snapshot to be smaller than {{ lineLimit }} lines but was {{ lineCount }} lines long"},type:"suggestion",schema:[{type:"object",properties:{maxSize:{type:"number"},inlineMaxSize:{type:"number"},allowedSnapshots:{type:"object",additionalProperties:{type:"array"}}},additionalProperties:!1}]},defaultOptions:[{}],create(e,[s]){return e.filename.endsWith(".snap")?{ExpressionStatement(t){Qt(e,t,s)}}:{CallExpression(t){const r=g(t,e);r?.type==="expect"&&["toMatchInlineSnapshot","toThrowErrorMatchingInlineSnapshot"].includes(y(r.matcher))&&r.args.length&&Qt(e,r.args[0],{...s,maxSize:s.inlineMaxSize??s.maxSize})}}}}),Ue="no-interpolation-in-snapshots",Qn=f({name:Ue,meta:{type:"problem",docs:{description:"disallow string interpolation in snapshots",recommended:!1},fixable:"code",schema:[],messages:{noInterpolationInSnapshots:"Do not use string interpolation in snapshots"}},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);t?.type==="expect"&&["toMatchInlineSnapshot","toThrowErrorMatchingInlineSnapshot"].includes(y(t.matcher))&&t.args.forEach(r=>{r.type===i.TemplateLiteral&&r.expressions.length>0&&e.report({messageId:"noInterpolationInSnapshots",node:r})})}}}}),Zt="__mocks__",Zn=e=>e.split(Hs.sep).includes(Zt),es=e=>B(e)&&Zn(W(e)),je="no-mocks-import",er=f({name:je,meta:{type:"problem",docs:{description:"disallow importing from __mocks__ directory",recommended:!1},messages:{noMocksImport:`Mocks should not be manually imported from a ${Zt} directory. Instead use \`vi.mock\` and import from the original module path`},schema:[]},defaultOptions:[],create(e){return{ImportDeclaration(s){es(s.source)&&e.report({node:s,messageId:"noMocksImport"})},'CallExpression[callee.name="require"]'(s){const[t]=s.arguments;t&&es(t)&&e.report({node:t,messageId:"noMocksImport"})}}}}),_e="no-restricted-matchers",tr=(e,s)=>R.hasOwnProperty(s)||s.endsWith(".not")?e.startsWith(s):e===s,sr=f({name:_e,meta:{docs:{description:"disallow the use of certain matchers",recommended:!1},type:"suggestion",schema:[{type:"object",additionalProperties:{type:["string","null"]}}],messages:{restrictedChain:"use of {{ restriction }} is disallowed",restrictedChainWithMessage:"{{ message }}"}},defaultOptions:[{}],create(e,[s]){return{CallExpression(t){const r=g(t,e);if(r?.type!=="expect")return;const n=r.members.map(o=>y(o)).join(".");for(const[o,a]of Object.entries(s))if(tr(n,o)){e.report({messageId:a?"restrictedChainWithMessage":"restrictedChain",data:{message:a,restriction:o},loc:{start:r.members[0].loc.start,end:r.members[r.members.length-1].loc.end}});break}}}}}),De="no-standalone-expect",ts=(e,s)=>{const t=e.parent;if(!t)throw new Error("Unexpected block statement. If you feel like this is a bug report https://github.com/veritem/eslint-plugin-vitest/issues/new");if(t.type===i.FunctionDeclaration)return"function";if(S(t)&&t.parent){const r=t.parent;if(r.type===i.VariableDeclarator)return"function";if(r.type===i.CallExpression&&w(r,s,["describe"]))return"describe"}return null},nr=f({name:De,meta:{docs:{description:"disallow using `expect` outside of `it` or `test` blocks",recommended:!1},type:"suggestion",messages:{noStandaloneExpect:"Expect must be called inside a test block"},schema:[{type:"object",properties:{additionalTestBlockFunctions:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},defaultOptions:[{additionalTestBlockFunctions:[]}],create(e,[{additionalTestBlockFunctions:s=[]}]){const t=[],r=n=>s.includes(O(n)||"");return{CallExpression(n){const o=g(n,e);if(o?.type==="expect"){if(o.head.node.parent?.type===i.MemberExpression&&o.members.length===1&&!["assertions","hasAssertions"].includes(y(o.members[0])))return;const a=t[t.length-1];(!a||a===H.describe)&&e.report({node:n,messageId:"noStandaloneExpect"});return}(o?.type==="test"||r(n))&&t.push("test"),n.callee.type===i.TaggedTemplateExpression&&t.push("template")},"CallExpression:exit"(n){const o=t[t.length-1];(o==="test"&&(w(n,e,["test"])||r(n))&&n.callee.type!==i.MemberExpression||o==="template"&&n.callee.type===i.TaggedTemplateExpression)&&t.pop()},BlockStatement(n){const o=ts(n,e);o&&t.push(o)},"BlockStatement:exit"(n){ts(n,e)&&t.pop()},ArrowFunctionExpression(n){n.parent?.type!==i.CallExpression&&t.push("arrow")},"ArrowFunctionExpression:exit"(){t[t.length-1]==="arrow"&&t.pop()}}}}),We="no-test-prefixes",rr=f({name:We,meta:{docs:{description:"disallow using the `f` and `x` prefixes in favour of `.only` and `.skip`",recommended:!1},type:"suggestion",messages:{usePreferredName:'Use "{{ preferredNodeName }}" instead'},fixable:"code",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="describe"&&t?.type!=="test"||t.name[0]!=="f"&&t.name[0]!=="x")return;const r=[t.name.slice(1),t.name[0]==="f"?"only":"skip",...t.members.map(o=>y(o))].join("."),n=s.callee.type===i.TaggedTemplateExpression?s.callee.tag:s.callee.type===i.CallExpression?s.callee.callee:s.callee;e.report({messageId:"usePreferredName",node:s.callee,data:{preferredNodeName:r},fix:o=>[o.replaceText(n,r)]})}}}}),He="no-test-return-statement",or=e=>{const[,s]=e;return s&&S(s)&&s.body.type===i.BlockStatement?s.body.body:[]},ir=f({name:He,meta:{type:"problem",docs:{description:"disallow return statements in tests",recommended:!1},schema:[],messages:{noTestReturnStatement:"Return statements are not allowed in tests"}},defaultOptions:[],create(e){return{CallExpression(s){if(!w(s,e,["test"]))return;const t=or(s.arguments).find(r=>r.type===i.ReturnStatement);t&&e.report({messageId:"noTestReturnStatement",node:t})},FunctionDeclaration(s){const t=e.sourceCode.getDeclaredVariables(s);if(le(t,e).length===0)return;const r=s.body.body.find(n=>n.type===i.ReturnStatement);r&&e.report({messageId:"noTestReturnStatement",node:r})}}}}),Ve="prefer-called-with",ar=f({name:Ve,meta:{docs:{description:"enforce using `toBeCalledWith()` or `toHaveBeenCalledWith()`",recommended:!1},messages:{preferCalledWith:"Prefer {{ matcherName }}With(/* expected args */)"},type:"suggestion",fixable:"code",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect"||t.modifiers.some(o=>y(o)==="not"))return;const{matcher:r}=t,n=y(r);["toBeCalled","toHaveBeenCalled"].includes(n)&&e.report({data:{matcherName:n},messageId:"preferCalledWith",node:r,fix:o=>[o.replaceText(r,`${n}With`)]})}}}}),ee="valid-title",cr=e=>["f","x"].includes(e.charAt(0))?e.substring(1):e,ss=e=>e.type===i.TemplateLiteral?`\`${e.quasis[0].value.raw}\``:e.raw,ns={type:"array",items:{type:"string"},minItems:1,maxItems:2,additionalItems:!1},te=e=>{const[s,t]=Array.isArray(e)?e:[e];return[new RegExp(s,"u"),t]};function lr(e){return!!(e.flags&j.TypeFlags.StringLike)}const rs=e=>{if(typeof e=="string"||Array.isArray(e)){const s=te(e);return{describe:s,test:s,it:s}}return{describe:e.describe?te(e.describe):null,test:e.test?te(e.test):null,it:e.it?te(e.it):null}},os=e=>B(e.right)?!0:e.left.type===i.BinaryExpression?os(e.left):B(e.left),ur=f({name:ee,meta:{docs:{description:"enforce valid titles",recommended:!1},messages:{titleMustBeString:"Test title must be a string, a function or class name",emptyTitle:"{{ functionName }} should not have an empty title",duplicatePrefix:"should not have duplicate prefix",accidentalSpace:"should not have leading or trailing spaces",disallowedWord:'"{{ word }}" is not allowed in test title',mustNotMatch:"{{ functionName }} should not match {{ pattern }}",mustMatch:"{{ functionName }} should match {{ pattern }}",mustNotMatchCustom:"{{ message }}",mustMatchCustom:"{{ message }}"},type:"suggestion",schema:[{type:"object",properties:{ignoreTypeOfDescribeName:{type:"boolean",default:!1},allowArguments:{type:"boolean",default:!1},disallowedWords:{type:"array",items:{type:"string"}}},patternProperties:{[/^must(?:Not)?Match$/u.source]:{oneOf:[{type:"string"},ns,{type:"object",propertyNames:{type:"string",enum:["describe","test","it"]},additionalProperties:{oneOf:[{type:"string"},ns]}}]}},additionalProperties:!1}],fixable:"code"},defaultOptions:[{ignoreTypeOfDescribeName:!1,allowArguments:!1,disallowedWords:[]}],create(e,[{ignoreTypeOfDescribeName:s,allowArguments:t,disallowedWords:r=[],mustNotMatch:n,mustMatch:o}]){const a=new RegExp(`\\b(${r.join("|")})\\b`,"iu"),c=rs(n??{}),l=rs(o??{}),u=Y(e.settings);return{CallExpression(p){const d=g(p,e);if(d?.type!=="describe"&&d?.type!=="test"&&d?.type!=="it"||d.members&&d.members[0]&&d.members[0].type===i.Identifier&&d.members[0].name==="extend")return;const x=F=>{e.report({messageId:"emptyTitle",data:{functionName:d.type==="describe"?H.describe:A.test},node:F})},[m]=p.arguments,I=u.typecheck?ae.getParserServices(e).getTypeAtLocation(m):null;if(I&&Pt(I)||!m||t&&m.type===i.Identifier)return;if(!B(m)){if(m.type===i.BinaryExpression&&os(m)||I&&lr(I))return;m.type!==i.TemplateLiteral&&!(s&&d.type==="describe")&&e.report({messageId:"titleMustBeString",loc:m.loc});return}const h=W(m);if(!h){x(p);return}if(r.length>0){const F=a.exec(h);if(F){e.report({messageId:"disallowedWord",data:{word:F[1]},node:m});return}}h.trim().length!==h.length&&e.report({messageId:"accidentalSpace",node:m,fix:F=>[F.replaceTextRange(m.range,ss(m).replace(/^([`'"]) +?/u,"$1").replace(/ +?([`'"])$/u,"$1"))]});const b=cr(d.name),[q]=h.split(" ");q.toLowerCase()===b&&e.report({messageId:"duplicatePrefix",node:m,fix:F=>[F.replaceTextRange(m.range,ss(m).replace(/^([`'"]).+? /u,"$1"))]});const T=b,[E,v]=c[T]??[];if(E&&E.test(h)){e.report({messageId:v?"mustNotMatchCustom":"mustNotMatch",node:m,data:{functionName:T,pattern:E,message:v}});return}const[U,G]=l[T]??[];U&&(U.test(h)||e.report({messageId:G?"mustMatchCustom":"mustMatch",node:m,data:{functionName:T,pattern:U,message:G}}))}}}}),se="valid-expect",is=["toReject","toResolve"],pr=e=>(e.type===i.ArrayExpression&&e.parent&&e.parent.type===i.CallExpression&&(e=e.parent),e.type===i.CallExpression&&e.callee.type===i.MemberExpression&&C(e.callee.object,"Promise")&&e.parent?e:null),as=({start:e,end:s})=>`${e.line}:${e.column}-${s.line}:${s.column}`,dr=e=>e.parent.type===i.Property&&e.type===i.FunctionExpression?e.parent:e;function cs(e){const s=e.parent?.parent;return s&&s.type===i.CallExpression&&s.callee.type===i.MemberExpression&&C(s.callee.property)&&["then","catch"].includes(y(s.callee.property))&&s.parent?cs(s):e}const fr=e=>e.parent?.parent&&[i.CallExpression,i.ArrayExpression].includes(e.parent.type)?pr(e.parent):null,ls=({parent:e})=>e?S(e)?e:ls(e):null,us=(e,s)=>s&&e.type===i.ReturnStatement?!0:e.type===i.ConditionalExpression&&e.parent?us(e.parent,s):[i.ArrowFunctionExpression,i.AwaitExpression].includes(e.type),mr=f({name:se,meta:{docs:{description:"enforce valid `expect()` usage",recommended:!1},messages:{tooManyArgs:"Expect takes at most {{ amount}} argument{{ s }}",notEnoughArgs:"Expect requires at least {{ amount }} argument{{ s }}",modifierUnknown:"Expect has an unknown modifier",matcherNotFound:"Expect must have a corresponding matcher call",matcherNotCalled:"Matchers must be called to assert",asyncMustBeAwaited:"Async assertions must be awaited{{ orReturned }}",promisesWithAsyncAssertionsMustBeAwaited:"Promises which return async assertions must be awaited{{ orReturned }}"},type:"suggestion",fixable:"code",schema:[{type:"object",properties:{alwaysAwait:{type:"boolean",default:!1},asyncMatchers:{type:"array",items:{type:"string"}},minArgs:{type:"number",minimum:1},maxArgs:{type:"number",minimum:1}},additionalProperties:!1}]},defaultOptions:[{alwaysAwait:!1,asyncMatchers:is,minArgs:1,maxArgs:1}],create:(e,[{alwaysAwait:s,asyncMatchers:t=is,minArgs:r=1,maxArgs:n=1}])=>{const o=new Set,a=[],c=p=>o.add(as(p)),l=p=>o.has(as(p)),u=p=>{let d=p,{parent:x}=p;for(;x&&x.type===i.MemberExpression;)d=x,x=x.parent;return d};return{CallExpression(p){const d=jt(p,e),x=Y(e.settings);if(typeof d=="string"){const v=p.parent?.type===i.MemberExpression?u(p.parent).property:p;if(d==="matcher-not-found"){e.report({messageId:"matcherNotFound",node:v});return}if(d==="matcher-not-called"&&e.report({messageId:C(v)&&R.hasOwnProperty(y(v))?"matcherNotFound":"matcherNotCalled",node:v}),d==="modifier-unknown"){e.report({messageId:"modifierUnknown",node:v});return}return}else if(d?.type==="expectTypeOf"&&x.typecheck||d?.type!=="expect"||d.modifiers.some(v=>v.type===i.Identifier&&v.name=="to"))return;const{parent:m}=d.head.node;if(m?.type!==i.CallExpression)return;if(m.arguments.length<r){const v=y(d.head.node).length,U={start:{column:m.loc.start.column+v,line:m.loc.start.line},end:{column:m.loc.start.column+v+1,line:m.loc.start.line}};e.report({messageId:"notEnoughArgs",data:{amount:r,s:r===1?"":"s"},node:m,loc:U})}if(m.arguments.length>n){if(m.arguments.length===2){const F=m.arguments[1].type===i.Literal&&typeof m.arguments[1].value=="string",Ds=m.arguments[1].type===i.TemplateLiteral;if(F||Ds)return}const{start:v}=m.arguments[n].loc,{end:U}=m.arguments[m.arguments.length-1].loc,G={start:v,end:{column:U.column+1,line:U.line}};e.report({messageId:"tooManyArgs",data:{amount:n,s:n===1?"":"s"},node:m,loc:G})}const{matcher:I}=d,h=I.parent.parent,b=d.modifiers.some(v=>y(v)!=="not")||t.includes(y(I));if(!h?.parent||!b)return;const q=h.parent.type===i.ArrayExpression,T=cs(h),E=fr(T)||T;E.parent&&!us(E.parent,!s)&&!l(E.loc)&&(a.push({messageId:E===T?"asyncMustBeAwaited":"promisesWithAsyncAssertionsMustBeAwaited",node:E}),q&&c(E.loc))},"Program:exit"(){const p=[];a.forEach(({node:d,messageId:x},m)=>{const I=s?"":" or returned";e.report({loc:d.loc,data:{orReturned:I},messageId:x,node:d,fix(h){const b=ls(d);if(!b)return null;const q=p.some(E=>E.text==="async ");if(!b.async&&!q){const E=dr(b);p.push(h.insertTextBefore(E,"async "))}const T=d.parent?.type===i.ReturnStatement?d.parent:null;if(s&&T){const E=e.sourceCode.getText(T).replace("return","await");p.push(h.replaceText(T,E))}else p.push(h.insertTextBefore(d,"await "));return m===a.length-1?p:null}})})}}}}),ne=e=>e.type===i.Literal&&typeof e.value=="boolean",yr=e=>{const s=y(e.matcher);if(["toBeTruthy","toBeFalsy"].includes(s))return!0;if(e.args.length!==1)return!1;const t=P(e);return L.hasOwnProperty(s)&&ne(t)},hr=(e,s)=>e.type===i.BinaryExpression&&e.operator==="instanceof"&&C(e.right,s),ps=e=>e.arguments.length===1,Ke="prefer-to-be-object",gr=f({name:Ke,meta:{type:"suggestion",docs:{description:"enforce using toBeObject()",recommended:!1},fixable:"code",messages:{preferToBeObject:"Prefer toBeObject() to test if a value is an object"},schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expectTypeOf")return;if(zs(t,"Object")){e.report({node:t.matcher,messageId:"preferToBeObject",fix:o=>[o.replaceTextRange([t.matcher.range[0],t.matcher.range[1]+8],"toBeObject()")]});return}const{parent:r}=t.head.node;if(r?.type!==i.CallExpression)return;const[n]=r.arguments;!n||!yr(t)||!hr(n,"Object")||e.report({node:t.matcher,messageId:"preferToBeObject",fix(o){const a=[o.replaceText(t.matcher,"toBeObject"),o.removeRange([n.left.range[1],n.range[1]])];let c=y(t.matcher)==="toBeFalsy";if(t.args.length){const[l]=t.args;a.push(o.remove(l)),c=l.type===i.Literal&&ue(l).value===!1}if(c){const l=t.modifiers.find(u=>y(u)==="not");a.push(l?o.removeRange([l.range[0]-1,l.range[1]]):o.insertTextBefore(t.matcher,"not."))}return a}})}}}}),Ge="prefer-to-be-truthy",kr=e=>e.type===i.Literal&&e.value===!0,br=f({name:Ge,meta:{type:"suggestion",docs:{description:"enforce using `toBeTruthy`",recommended:!1},messages:{preferToBeTruthy:"Prefer using `toBeTruthy` to test value is `true`"},fixable:"code",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);(t?.type==="expect"||t?.type==="expectTypeOf")&&t.args.length===1&&kr(P(t))&&L.hasOwnProperty(y(t.matcher))&&e.report({node:t.matcher,messageId:"preferToBeTruthy",fix:r=>[r.replaceText(t.matcher,"toBeTruthy"),r.remove(t.args[0])]})}}}}),Xe="prefer-to-be-falsy",xr=e=>e.type===i.Literal&&e.value===!1,Ir=f({name:Xe,meta:{type:"suggestion",docs:{description:"enforce using toBeFalsy()",recommended:!1},fixable:"code",schema:[],messages:{preferToBeFalsy:"Prefer using toBeFalsy()"}},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);(t?.type==="expect"||t?.type==="expectTypeOf")&&t.args.length===1&&xr(P(t))&&L.hasOwnProperty(y(t.matcher))&&e.report({node:t.matcher,messageId:"preferToBeFalsy",fix:r=>[r.replaceText(t.matcher,"toBeFalsy"),r.remove(t.args[0])]})}}}}),ze="prefer-to-have-length",Er=f({name:ze,meta:{type:"suggestion",docs:{description:"enforce using toHaveLength()",recommended:!1},fixable:"code",messages:{preferToHaveLength:"Prefer toHaveLength()"},schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect")return;const{parent:r}=t.head.node;if(r?.type!==i.CallExpression)return;const[n]=r.arguments,{matcher:o}=t;!L.hasOwnProperty(y(o))||n?.type!==i.MemberExpression||!C(n.property,"length")||e.report({node:o,messageId:"preferToHaveLength",fix(a){return[a.removeRange([n.property.range[0]-1,n.range[1]]),a.replaceTextRange([o.parent.object.range[1],o.parent.range[1]],".toHaveLength")]}})}}}}),Ye="prefer-equality-matcher",qr=f({name:Ye,meta:{type:"suggestion",docs:{description:"enforce using the built-in quality matchers",recommended:!1},messages:{useEqualityMatcher:"Prefer using one of the equality matchers instead",suggestEqualityMatcher:"Use `{{ equalityMatcher }}`"},hasSuggestions:!0,schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect"||t.args.length===0)return;const{parent:r}=t.head.node;if(r?.type!==i.CallExpression)return;const{arguments:[n],range:[,o]}=r,{matcher:a}=t,c=P(t);if(n?.type!==i.BinaryExpression||n.operator!=="==="&&n.operator!=="!=="||!L.hasOwnProperty(y(a))||!ne(c))return;const l=c.value,[u]=t.modifiers,p=t.modifiers.some(m=>y(m)==="not"),d=(n.operator==="!=="?!l:l)===p,x=m=>I=>{const{sourceCode:h}=e;let b=u&&y(u)!=="not"?`.${y(u)}`:"";return d&&(b+=`.${R.not}`),[I.replaceText(n,h.getText(n.left)),I.replaceTextRange([o,a.parent.range[1]],`${b}.${m}`),I.replaceText(c,h.getText(n.right))]};e.report({messageId:"useEqualityMatcher",suggest:["toBe","toEqual","toStrictEqual"].map(m=>({messageId:"suggestEqualityMatcher",data:{equalityMatcher:m},fix:x(m)})),node:a})}}}}),Je="prefer-strict-equal",Tr=f({name:Je,meta:{type:"suggestion",docs:{description:"enforce strict equal over equal",recommended:!1},messages:{useToStrictEqual:"Use `toStrictEqual()` instead",suggestReplaceWithStrictEqual:"Replace with `toStrictEqual()`"},schema:[],hasSuggestions:!0},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect")return;const{matcher:r}=t;C(r,"toEqual")&&e.report({messageId:"useToStrictEqual",node:r,suggest:[{messageId:"suggestReplaceWithStrictEqual",fix:n=>[X(n,r,L.toStrictEqual)]}]})}}}}),Qe="prefer-expect-resolves",wr=f({name:Qe,meta:{type:"suggestion",docs:{description:"enforce using `expect().resolves` over `expect(await ...)` syntax",recommended:!1},fixable:"code",messages:{expectResolves:"Use `expect().resolves` instead"},schema:[]},defaultOptions:[],create:e=>({CallExpression(s){const t=g(s,e);if(t?.type!=="expect")return;const{parent:r}=t.head.node;if(r?.type!==i.CallExpression)return;const[n]=r.arguments;n?.type===i.AwaitExpression&&e.report({node:n,messageId:"expectResolves",fix(o){return[o.insertTextBefore(r,"await "),o.removeRange([n.range[0],n.argument.range[0]]),o.insertTextAfter(r,".resolves")]}})}})}),Ze="prefer-each",Ar=f({name:Ze,meta:{type:"suggestion",docs:{description:"enforce using `each` rather than manual loops",recommended:!1},schema:[],messages:{preferEach:"Prefer using `{{ fn }}.each` rather than a manual loop"}},defaultOptions:[],create(e){const s=[];let t=!1;const r=()=>s.length===1&&s[0]==="test"?"it":"describe",n=()=>{s.length===0||t||(s.length=0)},o=a=>{s.length===0||t||(e.report({node:a,messageId:"preferEach",data:{fn:r()}}),s.length=0)};return{ForStatement:n,"ForStatement:exit":o,ForInStatement:n,"ForInStatement:exit":o,ForOfStatement:n,"ForOfStatement:exit":o,CallExpression(a){const{type:c}=g(a,e)??{};(c==="hook"||c==="describe"||c==="test")&&s.push(c),c==="test"&&(t=!0)},"CallExpression:exit"(a){const{type:c}=g(a,e)??{};c==="test"&&(t=!1)}}}}),et="prefer-hooks-on-top",vr=f({name:et,meta:{type:"suggestion",docs:{description:"enforce having hooks before any test cases",recommended:!1},messages:{noHookOnTop:"Hooks should come before test cases"},schema:[]},defaultOptions:[],create(e){const s=[!1];return{CallExpression(t){w(t,e,["test"])&&(s[s.length-1]=!0),s[s.length-1]&&w(t,e,["hook"])&&e.report({messageId:"noHookOnTop",node:t}),s.push(!1)},"CallExpression:exit"(){s.pop()}}}}),tt="prefer-hooks-in-order",ds=["beforeAll","beforeEach","afterEach","afterAll"],Cr=f({name:tt,meta:{type:"suggestion",docs:{description:"enforce having hooks in consistent order",recommended:!1},messages:{reorderHooks:"`{{ currentHook }}` hooks should be before any `{{ previousHook }}` hooks"},schema:[]},defaultOptions:[],create(e){let s=-1,t=!1;return{CallExpression(r){if(t)return;const n=g(r,e);if(n?.type!=="hook"){s=-1;return}t=!0;const o=n.name,a=ds.indexOf(o);if(a<s){e.report({messageId:"reorderHooks",data:{previousHook:ds[s],currentHook:o},node:r}),t=!1;return}s=a},"CallExpression:exit"(r){if(w(r,e,["hook"])){t=!1;return}t||(s=-1)}}}}),st="prefer-mock-promise-shorthand",nt=(e,s)=>`${e}${s?"Once":""}`,Mr=e=>e.body.type!==i.BlockStatement?e.body:e.body.body[0]?.type===i.ReturnStatement?e.body.body[0].argument:null,Sr=f({name:st,meta:{type:"suggestion",docs:{description:"enforce mock resolved/rejected shorthands for promises",recommended:!1},messages:{useMockShorthand:"Prefer {{ replacement }}"},schema:[],fixable:"code"},defaultOptions:[],create(e){const s=(t,r,n,o=n)=>{if(o?.type!==i.CallExpression)return;const a=O(o);if(a!=="Promise.resolve"&&a!=="Promise.reject")return;const c=nt(a.endsWith("reject")?"mockRejectedValue":"mockResolvedValue",r);e.report({node:t,messageId:"useMockShorthand",data:{replacement:c},fix(l){const{sourceCode:u}=e;return o.arguments.length>1?null:[l.replaceText(t,c),l.replaceText(n,o.arguments.length===1?u.getText(o.arguments[0]):"undefined")]}})};return{CallExpression(t){if(t.callee.type!==i.MemberExpression||!C(t.callee.property)||t.arguments.length===0)return;const r=y(t.callee.property),n=r.endsWith("Once");if(r===nt("mockReturnValue",n))s(t.callee.property,n,t.arguments[0]);else if(r===nt("mockImplementation",n)){const[o]=t.arguments;if(!S(o)||o.params.length!==0)return;s(t.callee.property,n,o,Mr(o))}}}}}),$r=Nt(import.meta.url),Or=Nt($r.resolve("eslint"));Or.resolve("espree");const Rr=new Set([i.Program,i.BlockStatement,i.SwitchCase,i.SwitchStatement]),Nr=e=>Rr.has(e),Br=e=>e.value===";"&&e.type===Rt.Punctuator,fs=(e,s)=>{const t=e.getLastToken(s),r=e.getTokenBefore(t),n=e.getTokenAfter(t);return r&&n&&r.range[0]>=s.range[0]&&Br(t)&&t.loc.start.line!==r.loc.end.line&&t.loc.end.line===n.loc.start.line?r:t},Lr=(e,s,t)=>{const r=[];let n=fs(t,e);if(s.loc.start.line-e.loc.end.line>=2)do{const o=t.getTokenAfter(n,{includeComments:!0});o.loc.start.line-n.loc.end.line>=2&&r.push([n,o]),n=o}while(n.range[0]<s.range[0]);return r},ms=(e,s)=>e.loc.end.line===s.loc.start.line,Fr=e=>e.type===i.TSAsExpression||e.type===i.TSTypeAssertion,ys=e=>Fr(e)?ys(e.expression):e,rt="prefer-vi-mocked",Pr=["Mock","MockedFunction","MockedClass","MockedObject"],Ur=f({name:rt,meta:{type:"suggestion",docs:{description:"require `vi.mocked()` over `fn as Mock`",requiresTypeChecking:!0,recommended:!1},fixable:"code",messages:{useViMocked:"Prefer `vi.mocked()`"},schema:[]},defaultOptions:[],create(e){function s(t){const{typeAnnotation:r}=t;if(r.type!==i.TSTypeReference)return;const{typeName:n}=r;if(n.type!==i.Identifier||!Pr.includes(n.name))return;const o=e.sourceCode.text.slice(...ys(t.expression).range);e.report({node:t,messageId:"useViMocked",fix(a){return a.replaceText(t,`vi.mocked(${o})`)}})}return{TSAsExpression(t){t.parent.type!==i.TSAsExpression&&s(t)},TSTypeAssertion(t){s(t)}}}}),ot="prefer-snapshot-hint",jr=["toMatchSnapshot","toThrowErrorMatchingSnapshot"],_r=jr,Dr=e=>{if(e.args.length===0)return!0;if(!C(e.matcher,"toMatchSnapshot"))return e.args.length!==1;if(e.args.length===2)return!1;const[s]=e.args;return!B(s)},Wr=f({name:ot,meta:{type:"suggestion",docs:{description:"enforce including a hint with external snapshots",recommended:!1},messages:{missingHint:"You should provide a hint for this snapshot"},schema:[{type:"string",enum:["always","multi"]}]},defaultOptions:["multi"],create(e,[s]){const t=[];let r=0;const n=[],o=()=>{for(const l of t)Dr(l)&&e.report({messageId:"missingHint",node:l.matcher})},a=()=>{r++},c=()=>{r--,s==="always"&&(o(),t.length=0),s==="multi"&&r===0&&(t.length>1&&o(),t.length=0)};return{"Program:exit"(){a(),c()},FunctionExpression:a,"FunctionExpression:exit":c,ArrowFunctionExpression:a,"ArrowFunctionExpression:exit":c,"CallExpression:exit"(l){w(l,e,["describe","test"])&&(r=n.pop()??0)},CallExpression(l){const u=g(l,e);if(u?.type!=="expect"){(u?.type==="describe"||u?.type==="test")&&(n.push(r),r=0);return}const p=y(u.matcher);_r.includes(p)&&t.push(u)}}}}),re="valid-describe-callback",hs=e=>{const[s]=e,t=e[e.length-1];return{start:s.loc.start,end:t.loc.end}},gs=(e,s)=>e.members.every(t=>y(t)!=="each")&&s.params.length,ks=(e,s)=>{e.body.forEach(t=>{t.type===i.ReturnStatement&&s.report({messageId:"unexpectedReturnInDescribe",node:t})})},Hr=f({name:re,meta:{type:"problem",docs:{description:"enforce valid describe callback",recommended:!1},messages:{nameAndCallback:"Describe requires a name and callback arguments",secondArgumentMustBeFunction:"Second argument must be a function",unexpectedDescribeArgument:"Unexpected argument in describe callback",unexpectedReturnInDescribe:"Unexpected return statement in describe callback"},schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="describe"||t?.members[0]?.type===i.Identifier&&t.members[0].name==="todo")return;if(s.arguments.length<1)return e.report({messageId:"nameAndCallback",loc:s.loc});const[,r,n]=s.arguments;if(!r){e.report({messageId:"nameAndCallback",loc:hs(s.arguments)});return}if(!S(r)){if(n&&S(n)){gs(t,n)&&e.report({messageId:"unexpectedDescribeArgument",node:n}),n.body.type===i.CallExpression&&e.report({messageId:"unexpectedReturnInDescribe",node:n}),n.body.type===i.BlockStatement&&ks(n.body,e);return}e.report({messageId:"secondArgumentMustBeFunction",loc:hs(s.arguments)});return}gs(t,r)&&e.report({messageId:"unexpectedDescribeArgument",node:r}),r.body.type===i.CallExpression&&e.report({messageId:"unexpectedReturnInDescribe",node:r}),r.body.type===i.BlockStatement&&ks(r.body,e)}}}}),it="require-top-level-describe",Vr=f({name:it,meta:{docs:{description:"enforce that all tests are in a top-level describe",recommended:!1},messages:{tooManyDescribes:"There should not be more than {{ max }} describe{{ s }} at the top level",unexpectedTestCase:"All test cases must be wrapped in a describe block",unexpectedHook:"All hooks must be wrapped in a describe block"},type:"suggestion",schema:[{type:"object",properties:{maxNumberOfTopLevelDescribes:{type:"number",minimum:1,default:1/0}},additionalProperties:!1}]},defaultOptions:[{maxNumberOfTopLevelDescribes:1/0}],create(e,s){const t=s[0].maxNumberOfTopLevelDescribes;let r=0,n=0;return{CallExpression(o){const a=g(o,e);if(a){if(a.type==="describe"){n++,n===1&&(r++,r>t&&e.report({node:o,messageId:"tooManyDescribes",data:{max:t,s:t===1?"":"s"}}));return}if(n===0){if(a.type==="test"&&(a.members.length===0||!a.members.every(c=>"name"in c&&c.name==="extend"))){e.report({node:o,messageId:"unexpectedTestCase"});return}a.type==="hook"&&e.report({node:o,messageId:"unexpectedHook"})}}},"CallExpression:exit"(o){w(o,e,["describe"])&&n--}}}}),at="require-to-throw-message",Kr=f({name:at,meta:{type:"suggestion",docs:{description:"require toThrow() to be called with an error message",recommended:!1},schema:[],messages:{addErrorMessage:"Add an error message to {{ matcherName }}()"}},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect")return;const{matcher:r}=t,n=y(r);t.args.length===0&&["toThrow","toThrowError"].includes(n)&&!t.modifiers.some(o=>y(o)==="not")&&e.report({messageId:"addErrorMessage",data:{matcherName:n},node:r})}}}}),ct="require-hook",Gr=(e,s)=>g(e,s)?!0:!!O(e)?.startsWith("vi"),Xr=e=>e.type===i.Literal&&e.value===null||N(e,"undefined"),bs=(e,s,t=[])=>{switch(e.type){case i.ExpressionStatement:return bs(e.expression,s,t);case i.CallExpression:return!(Gr(e,s)||t.includes(O(e)));case i.VariableDeclaration:return e.kind==="const"?!1:e.declarations.some(({init:r})=>r!==null&&!Xr(r));default:return!1}},zr=f({name:ct,meta:{docs:{description:"require setup and teardown to be within a hook",recommended:!1},messages:{useHook:"This should be done within a hook"},type:"suggestion",schema:[{type:"object",properties:{allowedFunctionCalls:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},defaultOptions:[{allowedFunctionCalls:[]}],create(e,s){const t=r=>{for(const n of r)bs(n,e,s[0].allowedFunctionCalls)&&e.report({node:n,messageId:"useHook"})};return{Program(r){t(r.body)},CallExpression(r){if(!w(r,e,["describe"])||r.arguments.length<2)return;const[,n]=r.arguments;!S(n)||n.body.type!==i.BlockStatement||t(n.body.body)}}}}),oe="require-local-test-context-for-concurrent-snapshots",Yr=f({name:oe,meta:{docs:{description:"require local Test Context for concurrent snapshot tests",recommended:!1},messages:{requireLocalTestContext:"Use local Test Context instead"},type:"problem",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);t===null||t.type!=="expect"||t.type==="expect"&&t.head.type==="testContext"||!["toMatchSnapshot","toMatchInlineSnapshot","toMatchFileSnapshot","toThrowErrorMatchingSnapshot","toThrowErrorMatchingInlineSnapshot"].includes(s.callee?.property.name)||!e.sourceCode.getAncestors(s).some(r=>r.type!==i.CallExpression||!w(r,e,["describe","test"])?!1:r.callee.type===i.MemberExpression&&C(r.callee.property,"concurrent"))||e.report({node:s,messageId:"requireLocalTestContext"})}}}}),lt="prefer-todo",Jr=e=>e.members.some(s=>y(s)!=="skip")||e.name.startsWith("x")?!1:!e.name.startsWith("f");function Qr(e){return S(e)?e.body.type===i.BlockStatement&&!e.body.body.length:!1}function xs(e,s){return e.members.length?X(s,e.members[0],"todo"):s.replaceText(e.head.node,`${e.head.local}.todo`)}const Zr=f({name:lt,meta:{type:"layout",docs:{description:"enforce using `test.todo`",recommended:!1},messages:{emptyTest:"Prefer todo test case over empty test case",unimplementedTest:"Prefer todo test case over unimplemented test case"},fixable:"code",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const[t,r]=s.arguments,n=g(s,e);!t||n?.type!=="test"||!Jr(n)||!B(t)||(r&&Qr(r)&&e.report({messageId:"emptyTest",node:s,fix:o=>[o.removeRange([t.range[1],r.range[1]]),xs(n,o)]}),ps(s)&&e.report({messageId:"unimplementedTest",node:s,fix:o=>xs(n,o)}))}}}}),ut="prefer-spy-on",eo=e=>"object"in e?e.object:e.callee.type===i.MemberExpression?e.callee.object:null,Is=e=>{if(e.type!==i.CallExpression&&e.type!==i.MemberExpression)return null;const s=eo(e);return s?s.type===i.Identifier?e.type===i.CallExpression&&O(e.callee)==="vi.fn"?e:null:Is(s):null},to=(e,s)=>{if(e.parent?.type===i.MemberExpression&&e.parent.property.type===i.Identifier&&e.parent.property.name==="mockImplementation")return"";const[t]=e.arguments,r=t&&s.sourceCode.getText(t);return r?`.mockImplementation(${r})`:".mockImplementation()"},so=f({name:ut,meta:{type:"suggestion",docs:{description:"enforce using `vi.spyOn`",recommended:!1},messages:{useViSpayOn:"Use `vi.spyOn` instead"},fixable:"code",schema:[]},defaultOptions:[],create(e){return{AssignmentExpression(s){const{left:t,right:r}=s;if(t.type!==i.MemberExpression)return;const n=Is(r);n&&e.report({node:s,messageId:"useViSpayOn",fix(o){const a=t.property.type===i.Identifier&&!t.computed?"'":"",c=to(n,e);return[o.insertTextBefore(t,"vi.spyOn("),o.replaceTextRange([t.object.range[1],t.property.range[0]],`, ${a}`),o.replaceTextRange([t.property.range[1],n.range[1]],`${a})${c}`)]}})}}}}),pt="prefer-comparison-matcher",Es=e=>B(e)||e?.type===i.TemplateLiteral,no=e=>Es(e.left)||Es(e.right),ro=e=>{switch(e){case">":return"<=";case"<":return">=";case">=":return"<";case"<=":return">"}return null},oo=(e,s)=>{switch(s?ro(e):e){case">":return"toBeGreaterThan";case"<":return"toBeLessThan";case">=":return"toBeGreaterThanOrEqual";case"<=":return"toBeLessThanOrEqual"}return null},io=f({name:pt,meta:{type:"suggestion",docs:{description:"enforce using the built-in comparison matchers",recommended:!1},schema:[],fixable:"code",messages:{useToBeComparison:"Prefer using `{{ preferredMatcher }}` instead"}},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect"||t.args.length===0)return;const{parent:r}=t.head.node;if(r?.type!==i.CallExpression)return;const{arguments:[n],range:[,o]}=r,{matcher:a}=t,c=P(t);if(n?.type!==i.BinaryExpression||no(n)||!L.hasOwnProperty(y(a))||!ne(c))return;const[l]=t.modifiers,u=t.modifiers.some(d=>y(d)==="not"),p=oo(n.operator,c.value===u);p&&e.report({fix(d){const{sourceCode:x}=e,m=l&&y(l)!=="not"?`.${y(l)}`:"";return[d.replaceText(n,x.getText(n.left)),d.replaceTextRange([o,a.parent.range[1]],`${m}.${p}`),d.replaceText(c,x.getText(n.right))]},messageId:"useToBeComparison",data:{preferredMatcher:p},node:a})}}}}),dt="prefer-describe-function-title",ao=f({name:dt,meta:{type:"problem",docs:{description:"enforce using a function as a describe title over an equivalent string",recommended:!1},fixable:"code",schema:[],messages:{preferFunction:"Enforce using a function over an equivalent string"}},defaultOptions:[],create(e){return{CallExpression(s){if(s.arguments.length<2)return;const t=Js(e,s),[r]=s.arguments;if(r.type===i.MemberExpression&&r.object.type===i.Identifier&&r.property.type===i.Identifier){const a=r.object.name;if(t?.set.get(a)?.defs[0]?.type!==Bt.ImportBinding||r.property.name!=="name")return;e.report({node:r,messageId:"preferFunction",fix(c){return c.replaceText(r,a)}});return}if(r.type!==i.Literal||typeof r.value!="string")return;const n=r.value;if(g(s,e)?.type!=="describe")return;const o=t?.set.get(n)?.defs[0];if(o?.type===Bt.ImportBinding){if(Y(e.settings).typecheck){const a=ae.getParserServices(e).getTypeAtLocation(o.node);if(!Pt(a))return}e.report({node:r,messageId:"preferFunction",fix(a){return a.replaceText(r,n)}})}}}}}),ft="prefer-to-contain",co=e=>e.type===i.CallExpression&&e.callee.type===i.MemberExpression&&C(e.callee.property,"includes")&&ps(e)&&e.arguments[0].type!==i.SpreadElement,lo=f({name:ft,meta:{docs:{description:"enforce using toContain()",recommended:!1},messages:{useToContain:"Use toContain() instead"},fixable:"code",type:"suggestion",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect"||t.args.length===0)return;const{parent:r}=t.head.node;if(r?.type!==i.CallExpression)return;const{arguments:[n],range:[,o]}=r,{matcher:a}=t,c=P(t);if(!n||c.type===i.SpreadElement||!L.hasOwnProperty(y(a))||!ne(c)||!co(n))return;const l=t.modifiers.some(u=>y(u)==="not");e.report({fix(u){const{sourceCode:p}=e,d=c.value===l;return[u.removeRange([n.callee.property.range[0]-1,n.range[1]]),u.replaceTextRange([o,a.parent.range[1]],d?`.${R.not}.toContain`:".toContain"),u.replaceText(t.args[0],p.getText(n.arguments[0]))]},messageId:"useToContain",node:a})}}}}),qs="prefer-expect-assertions",uo=e=>{let s=e;for(;s;){if(s.parent?.type===i.BlockStatement)return s.parent.body[0]===s;if(s.parent?.type===i.ArrowFunctionExpression)return!0;s=s.parent}throw new Error("Could not find parent block statement")},Ts=(e,s,t)=>({messageId:"suggestRemovingExtraArguments",fix:r=>Lt(r,e,s,t)}),po=f({name:"prefer-expect-assertions",meta:{docs:{description:"enforce using expect assertions instead of callbacks",recommended:!1},messages:{hasAssertionsTakesNoArguments:"`expect.hasAssertions` expects no arguments",assertionsRequiresOneArgument:"`expect.assertions` excepts a single argument of type number",assertionsRequiresNumberArgument:"This argument should be a number",haveExpectAssertions:"Every test should have either `expect.assertions(<number of assertions>)` or `expect.hasAssertions()` as its first expression",suggestAddingHasAssertions:"Add `expect.hasAssertions()`",suggestAddingAssertions:"Add `expect.assertions(<number of assertions>)`",suggestRemovingExtraArguments:"Remove extra arguments"},type:"suggestion",hasSuggestions:!0,schema:[{type:"object",properties:{onlyFunctionsWithAsyncKeyword:{type:"boolean"},onlyFunctionsWithExpectInLoop:{type:"boolean"},onlyFunctionsWithExpectInCallback:{type:"boolean"}},additionalProperties:!1}]},defaultOptions:[{onlyFunctionsWithAsyncKeyword:!1,onlyFunctionsWithExpectInCallback:!1,onlyFunctionsWithExpectInLoop:!1}],create(e,[s]){let t=0,r=!1,n=!1,o=!1,a=null,c=!1,l=!1;const u=h=>!!(!s.onlyFunctionsWithAsyncKeyword&&!s.onlyFunctionsWithExpectInCallback&&!s.onlyFunctionsWithExpectInLoop||s.onlyFunctionsWithAsyncKeyword&&h.async||s.onlyFunctionsWithExpectInCallback&&r||s.onlyFunctionsWithExpectInLoop&&n);function p(h,b){if(y(h.members[0])==="hasAssertions"){h.args.length&&e.report({messageId:"hasAssertionsTakesNoArguments",node:h.matcher,suggest:[Ts(e,b,0)]});return}if(h.args.length!==1){let{loc:T}=h.matcher;const E=[];h.args.length&&(T=h.args[1].loc,E.push(Ts(e,b,1))),e.report({messageId:"assertionsRequiresOneArgument",suggest:E,loc:T});return}const[q]=h.args;q.type===i.Literal&&typeof q.value=="number"&&Number.isInteger(q.value)||e.report({messageId:"assertionsRequiresNumberArgument",node:q})}const d=()=>c&&t++,x=()=>c&&t--,m=()=>l=!0,I=()=>l=!1;return{FunctionExpression:d,"FunctionExpression:exit":x,ArrowFunctionExpression:d,"ArrowFunctionExpression:exit":x,ForStatement:m,"ForStatement:exit":I,ForInStatement:m,"ForInStatement:exit":I,ForOfStatement:m,"ForOfStatement:exit":I,CallExpression(h){const b=g(h,e);if(b?.type==="test"){c=!0;return}b?.head.type==="testContext"&&b.members[0]&&b.members[0].type===i.Identifier&&b.members[0].name==="expect"&&(a=`${b.head.local}`),b?.type==="expect"&&c&&(t===1&&uo(h)&&b.head.node.parent?.type===i.MemberExpression&&b.members.length===1&&["assertions","hasAssertions"].includes(y(b.members[0]))&&(p(b,h),o=!0),l&&(n=!0),t>1&&(r=!0))},"CallExpression:exit"(h){if(!w(h,e,["test"])||(c=!1,h.arguments.length<2))return;const[,b]=h.arguments;if(!S(b)||!u(b))return;if(n=!1,r=!1,o){o=!1;return}const q=[];if(b.body.type===i.BlockStatement){const T=a?`${a}.`:"";q.push(["suggestAddingHasAssertions",`${T}expect.hasAssertions();`],["suggestAddingAssertions",`${T}expect.assertions();`])}e.report({messageId:"haveExpectAssertions",node:h,suggest:q.map(([T,E])=>({messageId:T,fix:v=>v.insertTextBeforeRange([b.body.range[0]+1,b.body.range[1]],E)}))})}}}});var M=(e=>(e[e.Any=0]="Any",e[e.Always=1]="Always",e))(M||{}),k=(e=>(e[e.Any=0]="Any",e[e.AfterAllToken=1]="AfterAllToken",e[e.AfterEachToken=2]="AfterEachToken",e[e.BeforeAllToken=3]="BeforeAllToken",e[e.BeforeEachToken=4]="BeforeEachToken",e[e.DescribeToken=5]="DescribeToken",e[e.ExpectToken=6]="ExpectToken",e[e.ExpectTypeOfToken=7]="ExpectTypeOfToken",e[e.FdescribeToken=8]="FdescribeToken",e[e.FitToken=9]="FitToken",e[e.ItToken=10]="ItToken",e[e.TestToken=11]="TestToken",e[e.XdescribeToken=12]="XdescribeToken",e[e.XitToken=13]="XitToken",e[e.XtestToken=14]="XtestToken",e))(k||{});const fo=(e,s,t)=>{const{sourceCode:r,ruleContext:n}=t;Lr(e,s,r).length>0||n.report({node:s,messageId:"missingPadding",fix(o){let a=fs(r,e);const c=r.getFirstTokenBetween(a,s,{includeComments:!0,filter(u){return ms(a,u)?(a=u,!1):!0}})||s,l=ms(a,c)?`
|
|
|
|
`:`
|
|
`;return o.insertTextAfter(a,l)}})},mo={0:()=>!0,1:fo},yo=()=>{let e=null;return{get prevNode(){return e.prevNode},set prevNode(s){e.prevNode=s},enter(){e={upper:e,prevNode:null}},exit(){e=e.upper}}},$=e=>(s,t)=>{let r=s;if(r.type===i.ExpressionStatement){r.expression.type===i.AwaitExpression&&(r=r.expression.argument);const n=t.getFirstToken(r);return n?.type===Rt.Identifier&&n.value===e}return!1},ho={0:()=>!0,1:$("afterAll"),2:$("afterEach"),3:$("beforeAll"),4:$("beforeEach"),5:$("describe"),6:$("expect"),7:$("expectTypeOf"),8:$("fdescribe"),9:$("fit"),10:$("it"),11:$("test"),12:$("xdescribe"),13:$("xit"),14:$("xtest")},mt=(e,s,t)=>{let r=e;const{sourceCode:n}=t;for(;r.type===i.LabeledStatement;)r=r.body;return Array.isArray(s)?s.some(o=>mt(r,o,t)):ho[s](r,n)},go=(e,s,t)=>{const{configs:r}=t,n=o=>mo[o](e,s,t);for(let o=r.length-1;o>=0;--o){const{prevStatementType:a,nextStatementType:c,paddingType:l}=r[o];if(mt(e,a,t)&&mt(s,c,t))return n(l)}return n(0)},ws=(e,s)=>{const{scopeInfo:t}=s;Nr(e?.parent.type)&&(t.prevNode&&go(t.prevNode,e,s),t.prevNode=e)},D=(e,s,t,r=!1)=>f({name:e,meta:{docs:{description:s},fixable:"whitespace",deprecated:r,messages:{missingPadding:"expect blank line before this statement"},schema:[],type:"suggestion"},defaultOptions:[],create(n){const o={ruleContext:n,sourceCode:n.sourceCode??n.getSourceCode(),scopeInfo:yo(),configs:t},{scopeInfo:a}=o;return{Program:a.enter,"Program:exit":a.exit,BlockStatement:a.enter,"BlockStatement:exit":a.exit,SwitchStatement:a.enter,"SwitchStatement:exit":a.exit,":statement":c=>ws(c,o),SwitchCase(c){ws(c,o),a.enter()},"SwitchCase:exit":a.exit}}}),yt="padding-around-after-all-blocks",As=[{paddingType:M.Always,prevStatementType:k.Any,nextStatementType:k.AfterAllToken},{paddingType:M.Always,prevStatementType:k.AfterAllToken,nextStatementType:k.Any}],ko=D(yt,"Enforce padding around `afterAll` blocks",As),ht="padding-around-after-each-blocks",vs=[{paddingType:M.Always,prevStatementType:k.Any,nextStatementType:k.AfterEachToken},{paddingType:M.Always,prevStatementType:k.AfterEachToken,nextStatementType:k.Any}],bo=D(ht,"Enforce padding around `afterEach` blocks",vs),gt="padding-around-before-all-blocks",Cs=[{paddingType:M.Always,prevStatementType:k.Any,nextStatementType:k.BeforeAllToken},{paddingType:M.Always,prevStatementType:k.BeforeAllToken,nextStatementType:k.Any}],xo=D(gt,"Enforce padding around `beforeAll` blocks",Cs),kt="padding-around-before-each-blocks",Ms=[{paddingType:M.Always,prevStatementType:k.Any,nextStatementType:k.BeforeEachToken},{paddingType:M.Always,prevStatementType:k.BeforeEachToken,nextStatementType:k.Any}],Io=D(kt,"Enforce padding around `beforeEach` blocks",Ms),bt="padding-around-describe-blocks",Ss=[{paddingType:M.Always,prevStatementType:k.Any,nextStatementType:[k.DescribeToken,k.FdescribeToken,k.XdescribeToken]},{paddingType:M.Always,prevStatementType:[k.DescribeToken,k.FdescribeToken,k.XdescribeToken],nextStatementType:k.Any}],Eo=D(bt,"Enforce padding around `describe` blocks",Ss),xt="padding-around-expect-groups",$s=[{paddingType:M.Always,prevStatementType:k.Any,nextStatementType:k.ExpectToken},{paddingType:M.Always,prevStatementType:k.ExpectToken,nextStatementType:k.Any},{paddingType:M.Any,prevStatementType:k.ExpectToken,nextStatementType:k.ExpectToken},{paddingType:M.Always,prevStatementType:k.Any,nextStatementType:k.ExpectTypeOfToken},{paddingType:M.Always,prevStatementType:k.ExpectTypeOfToken,nextStatementType:k.Any},{paddingType:M.Any,prevStatementType:k.ExpectTypeOfToken,nextStatementType:k.ExpectTypeOfToken}],qo=D(xt,"Enforce padding around `expect` groups",$s),It="padding-around-test-blocks",Os=[{paddingType:M.Always,prevStatementType:k.Any,nextStatementType:[k.TestToken,k.ItToken,k.FitToken,k.XitToken,k.XtestToken]},{paddingType:M.Always,prevStatementType:[k.TestToken,k.ItToken,k.FitToken,k.XitToken,k.XtestToken],nextStatementType:k.Any}],To=D(It,"Enforce padding around `test` blocks",Os),Et="padding-around-all",wo=D(Et,"Enforce padding around vitest functions",[...As,...vs,...Cs,...Ms,...Ss,...$s,...Os]),qt="valid-expect-in-promise",Ao=["toRejectWith","toResolveWith"],Tt=e=>{if(e.type===i.CallExpression&&e.callee.type===i.MemberExpression&&C(e.callee.property)){if(e.arguments.length===0)return!1;switch(y(e.callee.property)){case"then":return e.arguments.length<3;case"catch":case"finally":return e.arguments.length<2}}return!1},vo=(e,s)=>{const t=g(e,s);if(t?.type!=="test")return!1;const r=t.members.some(a=>y(a)==="each");if(r&&e.callee.type!==i.TaggedTemplateExpression)return!0;const[,n]=e.arguments,o=Number(r);return n&&S(n)&&n.params.length===1+o},Rs=(e,s)=>{const{name:t}=s;if(e.argument===null)return!1;if(e.argument.type===i.CallExpression&&e.argument.arguments.length>0){const r=O(e.argument);if(["Promise.all","Promise.allSettled"].includes(r)){const[n]=e.argument.arguments;if(n.type===i.ArrayExpression&&n.elements.some(o=>o&&N(o,t)))return!0}if(["Promise.resolve","Promise.reject"].includes(r)&&e.argument.arguments.length===1)return N(e.argument.arguments[0],t)}return N(e.argument,t)},Ns=(e,s)=>{for(const t of s)if(t?.type===i.AwaitExpression&&N(t.argument,e)||t?.type===i.ArrayExpression&&Ns(e,t.elements))return!0;return!1},Co=(e,s)=>{let t=s;for(;t;){if(t.type===i.CallExpression){if(Ns(e,t.arguments))return!0;t=t.callee}if(t.type!==i.MemberExpression)break;t=t.object}return!1},Mo=e=>{let s=e,t=e;for(;t&&(t.type===i.CallExpression&&(s=t,t=t.callee),t.type===i.MemberExpression);)t=t.object;return s},wt=(e,s,t)=>{const{name:r}=e;for(const n of s)if(!(n.range[0]<=e.range[0])){if(n.type===i.ReturnStatement)return Rs(n,e);if(n.type===i.ExpressionStatement){if(n.expression.type===i.CallExpression){if(Co(r,n.expression))return!0;const o=Mo(n.expression),a=g(n.expression,t);if(a?.type==="expect"&&o.arguments.length>0&&N(o.arguments[0],r)&&a.members.some(c=>{const l=y(c);return l===R.resolves||l===R.rejects}))return!0}if(n.expression.type===i.AwaitExpression&&Rs(n.expression,e))return!0;if(n.expression.type===i.AssignmentExpression){if(N(n.expression.left,r)&&O(n.expression.right)?.startsWith(`${r}.`)&&Tt(n.expression.right))continue;break}}if(n.type===i.BlockStatement&&wt(e,n.body,t))return!0}return!1},Bs=e=>{let s=e;for(;s;){if(s.type===i.BlockStatement)return s.body;s=s.parent}throw new Error("Could not find BlockStatement - please file a github issue at https://github.com/vitest-dev/eslint-plugin-vitest")},So=(e,s)=>{let t=e;for(;t;){if(S(t))return t=t.parent,t?.type===i.CallExpression&&w(t,s,["test"]);t=t.parent}return!1},$o=(e,s)=>{const t=Bs(e);return N(e.id)?wt(e.id,t,s):!0},Oo=f({name:qt,meta:{docs:{description:"require promises that have expectations in their chain to be valid"},messages:{expectInFloatingPromise:"This promise should either be returned or awaited to ensure the expects in its chain are called"},type:"suggestion",schema:[]},defaultOptions:[{alwaysAwait:!1,asyncMatchers:Ao,minArgs:1,maxArgs:1}],create(e){let s=!1;const t=[];return{CallExpression(r){if(vo(r,e)){s=!0;return}if(Tt(r)){t.unshift(!1);return}t.length>0&&w(r,e,["expect"])&&(t[0]=!0)},"CallExpression:exit"(r){if(s){w(r,e,["test"])&&(s=!1);return}if(!Tt(r)||!t.shift())return;const{parent:n}=_t(r);if(!(!n||!So(n,e))){switch(n.type){case i.VariableDeclarator:{if($o(n,e))return;break}case i.AssignmentExpression:{if(n.left.type===i.Identifier&&wt(n.left,Bs(n),e))return;break}case i.ExpressionStatement:break;case i.ReturnStatement:case i.AwaitExpression:default:return}e.report({messageId:"expectInFloatingPromise",node:n})}}}}}),At="prefer-strict-boolean-matchers",Ro=f({name:At,meta:{type:"suggestion",docs:{description:"enforce using `toBe(true)` and `toBe(false)` over matchers that coerce types to boolean",recommended:!1},messages:{preferToBeTrue:"Prefer using `toBe(true)` to test value is `true`",preferToBeFalse:"Prefer using `toBe(false)` to test value is `false`"},fixable:"code",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(!(t?.type==="expect"||t?.type==="expectTypeOf"))return;const r=y(t.matcher);r==="toBeFalsy"&&e.report({node:t.matcher,messageId:"preferToBeFalse",fix:n=>[n.replaceText(t.matcher,"toBe"),n.insertTextAfterRange([t.matcher.range[0],t.matcher.range[1]+1],"false")]}),r==="toBeTruthy"&&e.report({node:t.matcher,messageId:"preferToBeTrue",fix:n=>[n.replaceText(t.matcher,"toBe"),n.insertTextAfterRange([t.matcher.range[0],t.matcher.range[1]+1],"true")]})}}}}),vt="require-mock-type-parameters",No=f({name:vt,meta:{type:"suggestion",docs:{description:"enforce using type parameters with vitest mock functions",recommended:!1},messages:{noTypeParameter:"Missing type parameters"},fixable:"code",schema:[{type:"object",properties:{checkImportFunctions:{type:"boolean"}},additionalProperties:!1}]},defaultOptions:[{checkImportFunctions:!1}],create(e,[s]){return{CallExpression(t){const r=g(t,e);if(r?.type==="vi")for(const n of r?.members)!("name"in n)||n.parent.parent.typeArguments!==void 0||(n.name==="fn"&&e.report({node:n,messageId:"noTypeParameter"}),s.checkImportFunctions&&["importActual","importMock"].includes(n.name)&&e.report({node:n,messageId:"noTypeParameter"}))}}}}),Ct="prefer-called-once",Bo=e=>e.type===i.Literal&&e.value===1,Lo=f({name:Ct,meta:{docs:{description:"enforce using `toBeCalledOnce()` or `toHaveBeenCalledOnce()`",recommended:!1},messages:{preferCalledOnce:"Prefer {{ replacedMatcherName }}()"},type:"suggestion",fixable:"code",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect")return;const{matcher:r}=t,n=y(r);if(["toBeCalledTimes","toHaveBeenCalledTimes"].includes(n)&&t.args.length===1&&Bo(P(t))){const o=n.replace("Times","Once");e.report({data:{replacedMatcherName:o},messageId:"preferCalledOnce",node:r,fix:a=>[a.replaceText(r,o),a.remove(t.args[0])]})}}}}}),Mt="prefer-called-times",Fo=f({name:Mt,meta:{docs:{description:"enforce using `toBeCalledTimes(1)` or `toHaveBeenCalledTimes(1)`",recommended:!1},messages:{preferCalledTimes:"Prefer {{ replacedMatcherName }}(1)"},type:"suggestion",fixable:"code",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect")return;const{matcher:r}=t,n=y(r);if(["toBeCalledOnce","toHaveBeenCalledOnce"].includes(n)){const o=n.replace("Once","Times");e.report({data:{replacedMatcherName:o},messageId:"preferCalledTimes",node:r,fix:a=>[a.replaceText(r,o),a.insertTextAfterRange([t.matcher.range[0],t.matcher.range[1]+1],"1")]})}}}}}),St="prefer-expect-type-of",Po={string:"toBeString",number:"toBeNumber",boolean:"toBeBoolean",object:"toBeObject",function:"toBeFunction",symbol:"toBeSymbol",bigint:"toBeBigInt",undefined:"toBeUndefined"},Uo=f({name:St,meta:{type:"suggestion",docs:{description:"enforce using `expectTypeOf` instead of `expect(typeof ...)`",recommended:!1},schema:[],fixable:"code",messages:{preferExpectTypeOf:'Use `expectTypeOf({{ value }}).{{ matcher }}()` instead of `expect(typeof {{ value }}).toBe("{{ type }}")`'}},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="expect"||t.head.node.parent?.type!==i.CallExpression)return;const r=t.head.node.parent,[n]=r.arguments;if(!n||n.type!==i.UnaryExpression||n.operator!=="typeof")return;const o=y(t.matcher);if(o!=="toBe"&&o!=="toEqual")return;const[a]=t.args;if(!a||a.type!==i.Literal||typeof a.value!="string")return;const c=a.value,l=Po[c];if(!l)return;const u=e.sourceCode.getText(n.argument),p=t.modifiers.map(x=>y(x)).join("."),d=p?`.${p}`:"";e.report({node:s,messageId:"preferExpectTypeOf",data:{value:u,matcher:l,type:c},fix(x){return x.replaceText(s,`expectTypeOf(${u})${d}.${l}()`)}})}}}}),Ls="warn-todo",jo=f({name:Ls,meta:{docs:{description:"disallow `.todo` usage",recommended:!1},messages:{warnTodo:"The use of `.todo` is not recommended."},type:"suggestion",schema:[]},defaultOptions:[],create(e){return{CallExpression(s){const t=g(s,e);if(t?.type!=="describe"&&t?.type!=="test"&&t?.type!=="it")return;const r=t.members.find(n=>n.type==="Identifier"&&n.name==="todo");r&&e.report({messageId:"warnTodo",node:r})}}}}),$t="prefer-import-in-mock",_o=f({name:$t,meta:{fixable:"code",type:"suggestion",docs:{description:"prefer dynamic import in mock"},messages:{preferImport:"Replace '{{path}}' with import('{{path}}')"},schema:[]},defaultOptions:[],create(e){return{CallExpression(s){if(s.callee.type!==i.MemberExpression)return;const{object:t,property:r}=s.callee;if(t.type!==i.Identifier||t.name!=="vi"||r.type!==i.Identifier)return;const n=r.name,o=s.arguments[0];n==="mock"&&o&&o.type===i.Literal&&e.report({messageId:"preferImport",data:{path:o.value},node:s,fix(a){return a.replaceText(o,`import('${o.value}')`)}})}}}}),ie="prefer-called-exactly-once-with",Do=["toHaveBeenCalledOnce","toHaveBeenCalledWith"],Wo=["mockClear","mockReset","mockRestore"],Ho=e=>Do.some(s=>s===e),Vo=(e,s)=>e.type!==i.MemberExpression?null:s.getText(e.object),Ko=(e,s)=>e.arguments.map(t=>s.getText(t)).join(", "),Go=e=>e?.type!=="expect"||e.modifiers.some(s=>y(s)==="not")?null:e,Xo=e=>{const s=Go(e);return s?y(s.matcher):null},Fs=({callee:e})=>{if(e.type!==i.MemberExpression)return null;const{object:s}=e;if(s.type!==i.CallExpression)return null;const[t]=s.arguments;return t.type!==i.Identifier?null:t.name},zo=(e,s)=>{const t=Fs(e);if(!t)return null;const r=Fs(s);return t!==r?null:t},Yo=(e,s,t,r)=>{if(e.type!==i.ExpressionStatement||e.expression.type!==i.CallExpression)return!1;const n=e.loc.start.line;if(n<=t||n>=r)return!1;const{callee:o}=e.expression;if(o.type!==i.MemberExpression)return!1;const{object:a,property:c}=o;return a.type!==i.Identifier||a.name!==s||c.type!==i.Identifier?!1:Wo.some(l=>l===c.name)},Jo=(e,s,t)=>{const r=s.loc.start.line,n=t.loc.start.line,[o,a]=r<n?[r,n]:[n,r],c=zo(s,t);return c?e.some(l=>Yo(l,c,o,a)):!1},Qo=e=>e.callee.type===i.MemberExpression?e.callee.property:null,Zo=f({name:ie,meta:{docs:{description:"Prefer `toHaveBeenCalledExactlyOnceWith` over `toHaveBeenCalledOnce` and `toHaveBeenCalledWith`"},messages:{preferCalledExactlyOnceWith:"Prefer {{matcherName}} (/* expected args */)"},type:"suggestion",fixable:"code",schema:[]},defaultOptions:[],create(e){const{sourceCode:s}=e,t=n=>n.filter(o=>o.type===i.ExpressionStatement).flatMap(o=>o.expression.type===i.CallExpression?o.expression:[]),r=n=>{const o=t(n),a=new Map;for(const c of o){const l=Xo(g(c,e)),u=Vo(c.callee,s);if(!l||!Ho(l)||!u)continue;const p=[...a.get(u)??[],{matcherName:l,callExpression:c}];a.set(u,p)}for(const[c,l]of a.entries()){if(l.length!==2||!l.some(q=>q.matcherName==="toHaveBeenCalledOnce"))continue;const u=l.find(q=>q.matcherName==="toHaveBeenCalledWith");if(!u)continue;const p=Ko(u.callExpression,s),[d,x]=l,m=Qo(x.callExpression);if(!m)continue;const{callExpression:I}=d,{callExpression:h,matcherName:b}=x;Jo(n,I,h)||e.report({messageId:"preferCalledExactlyOnceWith",node:m,data:{matcherName:b},fix(q){const T=`${s.text.slice(I.parent.range[0],I.range[0])}${c}.toHaveBeenCalledExactlyOnceWith(${p})`,E=s.getIndexFromLoc({line:h.parent.loc.start.line,column:0}),v=s.getIndexFromLoc({line:h.parent.loc.end.line+1,column:0});return[q.replaceText(I,T),q.removeRange([E,v])]}})}};return{Program(n){r(n.body)},BlockStatement(n){r(n.body)}}}}),Ps=e=>Object.keys(e).reduce((s,t)=>({...s,[`vitest/${t}`]:e[t]}),{}),Us=e=>({plugins:["@vitest"],rules:Object.keys(e).reduce((s,t)=>({...s,[`@vitest/${t}`]:e[t]}),{})}),js={[pe]:"warn",[de]:"warn",[fe]:"warn",[he]:"warn",[ke]:"warn",[xe]:"warn",[Ee]:"warn",[qe]:"warn",[Te]:"warn",[we]:"warn",[Ae]:"warn",[ve]:"warn",[Ne]:"warn",[Be]:"warn",[Le]:"warn",[Fe]:"warn",[Pe]:"warn",[Ue]:"warn",[je]:"warn",[_e]:"warn",[De]:"warn",[We]:"warn",[He]:"warn",[Ve]:"warn",[Xe]:"off",[Ke]:"warn",[Ge]:"off",[ze]:"warn",[Ye]:"warn",[Je]:"warn",[Qe]:"warn",[Ze]:"warn",[et]:"warn",[tt]:"warn",[st]:"warn",[rt]:"warn",[ot]:"warn",[it]:"warn",[at]:"warn",[ct]:"warn",[lt]:"warn",[ut]:"warn",[pt]:"warn",[dt]:"warn",[ft]:"warn",[qs]:"warn",[Ie]:"warn",[yt]:"warn",[ht]:"warn",[Et]:"warn",[gt]:"warn",[kt]:"warn",[bt]:"warn",[xt]:"warn",[It]:"warn",[qt]:"warn",[J]:"warn",[z]:"warn",[Q]:"warn",[ee]:"warn",[se]:"warn",[re]:"warn",[oe]:"warn",[Z]:"warn",[At]:"warn",[vt]:"warn",[Oe]:"off",[Re]:"warn",[Ct]:"off",[Mt]:"warn",[St]:"warn",[ge]:"warn",[$t]:"warn",[ie]:"warn"},_s={[J]:"error",[z]:"error",[Q]:"error",[ee]:"error",[se]:"error",[re]:"error",[oe]:"error",[Z]:"error",[ie]:"error"},ei={[pe]:mn,[de]:yn,[z]:hn,[fe]:gn,[he]:kn,[J]:xn,[ge]:qn,[ke]:wn,[xe]:vn,[Ie]:On,[Ee]:Rn,[qe]:Nn,[Te]:Bn,[we]:Ln,[Ae]:Fn,[Q]:Un,[ve]:jn,[Ne]:Kn,[Be]:Gn,[Le]:zn,[Fe]:Yn,[Pe]:Jn,[Ue]:Qn,[je]:er,[_e]:sr,[De]:nr,[We]:rr,[He]:ir,[Z]:_n,[Ve]:ar,[ee]:ur,[se]:mr,[Xe]:Ir,[Ke]:gr,[Ge]:br,[ze]:Er,[Ye]:qr,[Je]:Tr,[Qe]:wr,[Ze]:Ar,[et]:vr,[tt]:Cr,[oe]:Yr,[st]:Sr,[rt]:Ur,[ot]:Wr,[re]:Hr,[it]:Vr,[at]:Kr,[ct]:zr,[lt]:Zr,[ut]:so,[pt]:io,[dt]:ao,[ft]:lo,[qs]:po,[yt]:ko,[ht]:bo,[Et]:wo,[gt]:xo,[kt]:Io,[bt]:Eo,[xt]:qo,[It]:To,[qt]:Oo,[At]:Ro,[vt]:No,[Oe]:Hn,[Re]:Vn,[Ct]:Lo,[Mt]:Fo,[St]:Uo,[Ls]:jo,[$t]:_o,[ie]:Zo},Ot={meta:{name:"vitest",version:Vs},rules:ei,environments:{env:{globals:{suite:!0,test:!0,describe:!0,it:!0,expectTypeOf:!0,assertType:!0,expect:!0,assert:!0,chai:!0,vitest:!0,vi:!0,beforeAll:!0,afterAll:!0,beforeEach:!0,afterEach:!0,onTestFailed:!0,onTestFinished:!0}}},configs:{"legacy-recommended":Us(_s),"legacy-all":Us(js),recommended:{name:"vitest/recommended",plugins:{get vitest(){return Ot}},rules:Ps(_s)},all:{name:"vitest/all",plugins:{get vitest(){return Ot}},rules:Ps(js)},env:{name:"vitest/env",languageOptions:{globals:{suite:"writable",test:"writable",describe:"writable",it:"writable",expectTypeOf:"writable",assertType:"writable",expect:"writable",assert:"writable",chai:"writable",vitest:"writable",vi:"writable",beforeAll:"writable",afterAll:"writable",beforeEach:"writable",afterEach:"writable",onTestFailed:"writable",onTestFinished:"writable"}}}}};export{Ot as default};
|