vitest 0.0.54 → 0.0.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.gh.md +8 -10
- package/dist/index.d.ts +13 -0
- package/dist/node/cli.js +1 -1
- package/dist/runtime/entry.js +1 -1
- package/package.json +1 -1
package/README.gh.md
CHANGED
|
@@ -25,18 +25,16 @@ A blazing fast unit test framework powered by Vite.
|
|
|
25
25
|
|
|
26
26
|
- [Vite](https://vitejs.dev/)'s config, transformers, resolvers, and plugins. Use the same setup from your app!
|
|
27
27
|
- [Jest Snapshot](https://jestjs.io/docs/snapshot-testing)
|
|
28
|
-
- [Chai](https://www.chaijs.com/) built-in for assertions, with [
|
|
29
|
-
- [Smart watch mode](#watch-mode),
|
|
30
|
-
- [
|
|
31
|
-
- [Sinon](https://sinonjs.org/) built-in for mocking
|
|
28
|
+
- [Chai](https://www.chaijs.com/) built-in for assertions, with [Jest expect](https://jestjs.io/docs/expect) compatible APIs.
|
|
29
|
+
- [Smart & instant watch mode](#watch-mode), like HMR for tests!
|
|
30
|
+
- [Native code coverage](#coverage) via [c8](https://github.com/bcoe/c8)
|
|
31
|
+
- [Sinon](https://sinonjs.org/) built-in for mocking, stubbing, and spies.
|
|
32
32
|
- [JSDOM](https://github.com/jsdom/jsdom) and [happy-dom](https://github.com/capricorn86/happy-dom) built-in for DOM and browser API mocking
|
|
33
|
-
- Components testing ([Vue
|
|
34
|
-
-
|
|
35
|
-
- ESM
|
|
33
|
+
- Components testing ([Vue](./test/vue), [React](./test/react), [Lit](./test/lit), [Vitesse](./test/vitesse))
|
|
34
|
+
- Workers multi-threading via [Piscina](https://github.com/piscinajs/piscina)
|
|
35
|
+
- ESM first, top level await
|
|
36
36
|
- Out-of-box TypeScript / JSX support
|
|
37
|
-
-
|
|
38
|
-
- Suite and Test filtering (skip, only, todo)
|
|
39
|
-
- Concurrent Tests
|
|
37
|
+
- Filtering, timeouts, concurrent for suite and tests
|
|
40
38
|
|
|
41
39
|
```ts
|
|
42
40
|
import { it, describe, expect, assert } from 'vitest'
|
package/dist/index.d.ts
CHANGED
|
@@ -136,10 +136,23 @@ declare global {
|
|
|
136
136
|
toBeNull(): void;
|
|
137
137
|
toBeDefined(): void;
|
|
138
138
|
toBeInstanceOf(c: any): void;
|
|
139
|
+
toBeCalledTimes(n: number): void;
|
|
139
140
|
toHaveBeenCalledTimes(n: number): void;
|
|
140
141
|
toHaveBeenCalledOnce(): void;
|
|
141
142
|
toHaveBeenCalled(): void;
|
|
143
|
+
toBeCalled(): void;
|
|
142
144
|
toHaveBeenCalledWith(...args: any[]): void;
|
|
145
|
+
toBeCalledWith(...args: any[]): void;
|
|
146
|
+
toReturn(): void;
|
|
147
|
+
toHaveReturned(): void;
|
|
148
|
+
toReturnTimes(times: number): void;
|
|
149
|
+
toHaveReturnedTimes(times: number): void;
|
|
150
|
+
toReturnWith(value: any): void;
|
|
151
|
+
toHaveReturnedWith(value: any): void;
|
|
152
|
+
toHaveLastReturnedWith(value: any): void;
|
|
153
|
+
lastReturnedWith(value: any): void;
|
|
154
|
+
toHaveNthReturnedWith(nthCall: number, value: any): void;
|
|
155
|
+
nthReturnedWith(nthCall: number, value: any): void;
|
|
143
156
|
}
|
|
144
157
|
}
|
|
145
158
|
}
|
package/dist/node/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{addSnapshotResult,emptySummary,getNames,getSuites,getTests,hasFailed}from"../chunk-4STHXS4C.js";import{defaultExcludes,defaultIncludes,distDir}from"../chunk-2PVIVCXM.js";import{__commonJS,__spreadProps,__spreadValues,__toModule,init_esm_shims}from"../chunk-64PJVUUV.js";var require_indent_string=__commonJS({"node_modules/.pnpm/indent-string@4.0.0/node_modules/indent-string/index.js"(exports,module){init_esm_shims();"use strict";module.exports=(string,count=1,options)=>{if(options=__spreadValues({indent:" ",includeEmptyLines:!1},options),typeof string!="string")throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof string}\``);if(typeof count!="number")throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);if(typeof options.indent!="string")throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\``);if(count===0)return string;let regex=options.includeEmptyLines?/^/gm:/^(?!\s*$)/gm;return string.replace(regex,options.indent.repeat(count))}}});init_esm_shims();import sade from"sade";import c4 from"picocolors";import{install as installSourceMapSupport}from"source-map-support";var version="0.0.
|
|
1
|
+
import{addSnapshotResult,emptySummary,getNames,getSuites,getTests,hasFailed}from"../chunk-4STHXS4C.js";import{defaultExcludes,defaultIncludes,distDir}from"../chunk-2PVIVCXM.js";import{__commonJS,__spreadProps,__spreadValues,__toModule,init_esm_shims}from"../chunk-64PJVUUV.js";var require_indent_string=__commonJS({"node_modules/.pnpm/indent-string@4.0.0/node_modules/indent-string/index.js"(exports,module){init_esm_shims();"use strict";module.exports=(string,count=1,options)=>{if(options=__spreadValues({indent:" ",includeEmptyLines:!1},options),typeof string!="string")throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof string}\``);if(typeof count!="number")throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);if(typeof options.indent!="string")throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\``);if(count===0)return string;let regex=options.includeEmptyLines?/^/gm:/^(?!\s*$)/gm;return string.replace(regex,options.indent.repeat(count))}}});init_esm_shims();import sade from"sade";import c4 from"picocolors";import{install as installSourceMapSupport}from"source-map-support";var version="0.0.55";init_esm_shims();import{performance}from"perf_hooks";import{relative as relative2}from"path";import c3 from"picocolors";import figures2 from"figures";init_esm_shims();import{promises as fs,existsSync}from"fs";import c from"picocolors";import{createPatch}from"diff";import{notNullish}from"@antfu/utils";import{SourceMapConsumer}from"source-map";async function printError(error){let{server}=process.__vitest__,e=error,codeFramePrinted=!1,nearest=parseStack(e.stack||e.stackStr||"").find(stack=>server.moduleGraph.getModuleById(stack.file));if(nearest){let mod=server.moduleGraph.getModuleById(nearest.file),transformResult=mod==null?void 0:mod.ssrTransformResult,pos=await getOriginalPos(transformResult==null?void 0:transformResult.map,nearest);if(pos&&existsSync(nearest.file)){let sourceCode=await fs.readFile(nearest.file,"utf-8");console.error(`${c.red(`${c.bold(e.name||e.nameStr||"Unknown Error")}: ${e.message}`)}`),console.log(c.gray(`${nearest.file}:${pos.line}:${pos.column}`)),console.log(c.yellow(generateCodeFrame(sourceCode,pos))),codeFramePrinted=!0}}codeFramePrinted||console.error(e),e.showDiff&&console.error(c.gray(generateDiff(stringify(e.actual),stringify(e.expected))))}function getOriginalPos(map,{line,column}){return new Promise(resolve2=>{if(!map)return resolve2(null);SourceMapConsumer.with(map,null,consumer=>{let pos=consumer.originalPositionFor({line,column});pos.line!=null&&pos.column!=null?resolve2(pos):resolve2(null)})})}var splitRE=/\r?\n/;function posToNumber(source,pos){if(typeof pos=="number")return pos;let lines=source.split(splitRE),{line,column}=pos,start2=0;for(let i=0;i<line-1;i++)start2+=lines[i].length+1;return start2+column}function generateCodeFrame(source,start2=0,end,range=2){start2=posToNumber(source,start2),end=end||start2;let lines=source.split(splitRE),count=0,res=[];for(let i=0;i<lines.length;i++)if(count+=lines[i].length+1,count>=start2){for(let j=i-range;j<=i+range||end>count;j++){if(j<0||j>=lines.length)continue;let line=j+1;res.push(`${c.gray(`${line}${" ".repeat(Math.max(3-String(line).length,0))}|`)} ${lines[j]}`);let lineLength=lines[j].length;if(lineLength>200)return"";if(j===i){let pad=start2-(count-lineLength)+1,length=Math.max(1,end>count?lineLength-pad:end-start2);res.push(`${c.gray(" |")} ${" ".repeat(pad)}${"^".repeat(length)}`)}else if(j>i){if(end>count){let length=Math.max(Math.min(end-count,lineLength),1);res.push(`${c.gray(" |")} ${"^".repeat(length)}`)}count+=lineLength+1}}break}return res.join(`
|
|
2
2
|
`)}function stringify(obj){return String(obj)}var stackFnCallRE=/at (.*) \((.+):(\d+):(\d+)\)$/,stackBarePathRE=/at ()(.+):(\d+):(\d+)$/;function parseStack(stack){return stack.split(`
|
|
3
3
|
`).map(raw=>{let line=raw.trim(),match=line.match(stackFnCallRE)||line.match(stackBarePathRE);if(!match)return null;let file=match[2];return file.startsWith("file://")&&(file=file.slice(7)),{method:match[1],file:match[2],line:parseInt(match[3]),column:parseInt(match[4])}}).filter(notNullish)}function generateDiff(actual,expected){let diffSize=2048;return actual.length>diffSize&&(actual=`${actual.substring(0,diffSize)} ... Lines skipped`),expected.length>diffSize&&(expected=`${expected.substring(0,diffSize)} ... Lines skipped`),unifiedDiff(actual,expected)}function unifiedDiff(actual,expected){let indent=" ";function cleanUp(line){return line[0]==="+"?indent+c.green(`${line[0]} ${line.slice(1)}`):line[0]==="-"?indent+c.red(`${line[0]} ${line.slice(1)}`):line.match(/@@/)?"--":line.match(/\\ No newline/)?null:indent+line}let lines=createPatch("string",actual,expected).split(`
|
|
4
4
|
`).splice(5);return`
|
package/dist/runtime/entry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getNames,hasFailed,hasTests,interpretOnlyMode,packSnapshotState,partitionSuiteChildren}from"../chunk-4STHXS4C.js";import{clearContext,context,createSuiteHooks,defaultSuite,getFn,getHooks,setHooks}from"../chunk-OGVCGRFA.js";import"../chunk-2PVIVCXM.js";import{init_esm_shims}from"../chunk-64PJVUUV.js";init_esm_shims();init_esm_shims();init_esm_shims();import chai from"chai";import SinonChai from"sinon-chai";import Subset from"chai-subset";init_esm_shims();init_esm_shims();import path from"path";import Snap from"jest-snapshot";import{expect}from"chai";init_esm_shims();var rpc=async(method,...args)=>{var _a;return(_a=process.__vitest_worker__)==null?void 0:_a.rpc(method,...args)},send=async(method,...args)=>{var _a;return(_a=process.__vitest_worker__)==null?void 0:_a.send(method,...args)};var{SnapshotState}=Snap,resolveSnapshotPath=testPath=>path.join(path.join(path.dirname(testPath),"__snapshots__"),`${path.basename(testPath)}.snap`),SnapshotClient=class{test;testFile="";snapshotState;setTest(test){this.test=test,this.testFile!==this.test.file.filepath&&(this.snapshotState&&this.saveSnap(),this.testFile=this.test.file.filepath,this.snapshotState=new SnapshotState(resolveSnapshotPath(this.testFile),process.__vitest_worker__.config.snapshotOptions))}clearTest(){this.test=void 0}assert(received,message){if(!this.test)throw new Error("Snapshot can't not be used outside of test");let{actual,expected,key,pass}=this.snapshotState.match({testName:getNames(this.test).slice(1).join(" > "),received,isInline:!1});pass||expect(actual.trim()).equals(expected?expected.trim():"",message||`Snapshot name: \`${key}\``)}async saveSnap(){if(!this.testFile||!this.snapshotState)return;let result=packSnapshotState(this.testFile,this.snapshotState);await rpc("snapshotSaved",result),this.testFile="",this.snapshotState=void 0}};var _client;function getSnapshotClient(){return _client||(_client=new SnapshotClient),_client}function SnapshotPlugin(){return function(chai2,utils){for(let key of["matchSnapshot","toMatchSnapshot"])utils.addMethod(chai2.Assertion.prototype,key,function(message){let expected=utils.flag(this,"object");getSnapshotClient().assert(expected,message)})}}init_esm_shims();function JestChaiExpect(){return(chai2,utils)=>{function def(name,fn){utils.addMethod(chai2.Assertion.prototype,
|
|
1
|
+
import{getNames,hasFailed,hasTests,interpretOnlyMode,packSnapshotState,partitionSuiteChildren}from"../chunk-4STHXS4C.js";import{clearContext,context,createSuiteHooks,defaultSuite,getFn,getHooks,setHooks}from"../chunk-OGVCGRFA.js";import"../chunk-2PVIVCXM.js";import{init_esm_shims}from"../chunk-64PJVUUV.js";init_esm_shims();init_esm_shims();init_esm_shims();import chai from"chai";import SinonChai from"sinon-chai";import Subset from"chai-subset";init_esm_shims();init_esm_shims();import path from"path";import Snap from"jest-snapshot";import{expect}from"chai";init_esm_shims();var rpc=async(method,...args)=>{var _a;return(_a=process.__vitest_worker__)==null?void 0:_a.rpc(method,...args)},send=async(method,...args)=>{var _a;return(_a=process.__vitest_worker__)==null?void 0:_a.send(method,...args)};var{SnapshotState}=Snap,resolveSnapshotPath=testPath=>path.join(path.join(path.dirname(testPath),"__snapshots__"),`${path.basename(testPath)}.snap`),SnapshotClient=class{test;testFile="";snapshotState;setTest(test){this.test=test,this.testFile!==this.test.file.filepath&&(this.snapshotState&&this.saveSnap(),this.testFile=this.test.file.filepath,this.snapshotState=new SnapshotState(resolveSnapshotPath(this.testFile),process.__vitest_worker__.config.snapshotOptions))}clearTest(){this.test=void 0}assert(received,message){if(!this.test)throw new Error("Snapshot can't not be used outside of test");let{actual,expected,key,pass}=this.snapshotState.match({testName:getNames(this.test).slice(1).join(" > "),received,isInline:!1});pass||expect(actual.trim()).equals(expected?expected.trim():"",message||`Snapshot name: \`${key}\``)}async saveSnap(){if(!this.testFile||!this.snapshotState)return;let result=packSnapshotState(this.testFile,this.snapshotState);await rpc("snapshotSaved",result),this.testFile="",this.snapshotState=void 0}};var _client;function getSnapshotClient(){return _client||(_client=new SnapshotClient),_client}function SnapshotPlugin(){return function(chai2,utils){for(let key of["matchSnapshot","toMatchSnapshot"])utils.addMethod(chai2.Assertion.prototype,key,function(message){let expected=utils.flag(this,"object");getSnapshotClient().assert(expected,message)})}}init_esm_shims();function JestChaiExpect(){return(chai2,utils)=>{function def(name,fn){let addMethod=n=>{utils.addMethod(chai2.Assertion.prototype,n,fn)};Array.isArray(name)?name.forEach(n=>addMethod(n)):addMethod(name)}def("toEqual",function(expected){return this.eql(expected)}),def("toStrictEqual",function(expected){return this.equal(expected)}),def("toBe",function(expected){return this.equal(expected)}),def("toMatchObject",function(expected){return this.containSubset(expected)}),def("toMatch",function(expected){return typeof expected=="string"?this.include(expected):this.match(expected)}),def("toContain",function(item){return this.contain(item)}),def("toContainEqual",function(expected){let obj=utils.flag(this,"object"),index=Array.from(obj).findIndex(item=>{try{chai2.assert.deepEqual(item,expected)}catch{return!1}return!0});this.assert(index!==-1,"expected #{this} to deep equally contain #{exp}","expected #{this} to not deep equally contain #{exp}",expected)}),def("toBeTruthy",function(){let obj=utils.flag(this,"object");this.assert(Boolean(obj),"expected #{this} to be truthy","expected #{this} to not be truthy",obj)}),def("toBeFalsy",function(){let obj=utils.flag(this,"object");this.assert(!obj,"expected #{this} to be falsy","expected #{this} to not be falsy",obj)}),def("toBeNaN",function(){return this.be.NaN}),def("toBeUndefined",function(){return this.be.undefined}),def("toBeNull",function(){return this.be.null}),def("toBeDefined",function(){return this.not.be.undefined}),def("toBeInstanceOf",function(obj){return this.instanceOf(obj)}),def(["toHaveBeenCalledTimes","toBeCalledTimes"],function(number){return this.callCount(number)}),def("toHaveBeenCalledOnce",function(){return this.callCount(1)}),def(["toHaveBeenCalled","toBeCalled"],function(){return this.called}),def(["toHaveBeenCalledWith","toBeCalledWith"],function(...args){return this.calledWith(...args)}),def(["toHaveReturned","toReturn"],function(){let spy=utils.flag(this,"object"),calledAndNotThrew=spy.called&&!spy.alwaysThrew();this.assert(calledAndNotThrew,"expected spy to be successfully called at least once","expected spy not to be successfully called",calledAndNotThrew,!calledAndNotThrew)}),def(["toHaveReturnedTimes","toReturnTimes"],function(times){let successfullReturns=utils.flag(this,"object").getCalls().reduce((success,call)=>call.threw()?success:++success,0);this.assert(successfullReturns===times,`expected spy to be successfully called ${times} times`,`expected spy not to be successfully called ${times} times`,`expected number of returns: ${times}`,`recieved number of returns: ${successfullReturns}`)}),def(["toHaveReturnedWith","toReturnWith"],function(value){return this.returned(value)}),def(["toHaveLastReturnedWith","lastReturnedWith"],function(value){let spy=utils.flag(this,"object"),lastReturn=spy.lastCall.returned(value);this.assert(lastReturn,"expected last spy call to return #{exp}","expected last spy call not to return #{exp}",value,spy.lastCall.returnValue)});let ordinalOf=i=>{let j=i%10,k=i%100;return j===1&&k!==11?`${i}st`:j===2&&k!==12?`${i}nd`:j===3&&k!==13?`${i}rd`:`${i}th`};def(["toHaveNthReturnedWith","nthReturnedWith"],function(nthCall,value){let spy=utils.flag(this,"object"),isNot=utils.flag(this,"negate"),call=spy.getCall(nthCall-1),ordinalCall=`${ordinalOf(nthCall)} call`;!isNot&&call.threw()&&chai2.assert.fail(`expected ${ordinalCall} to return #{exp}, but instead it threw an error`);let nthCallReturn=call.returned(value);this.assert(nthCallReturn,`expected ${ordinalCall} spy call to return #{exp}`,`expected ${ordinalCall} spy call not to return #{exp}`,value,call.returnValue)})}}var installed=!1;async function setupChai(){installed||(chai.use(SinonChai),chai.use(JestChaiExpect()),chai.use(Subset),chai.use(SnapshotPlugin()),installed=!0)}async function setupEnv(config){if(await setupChai(),config.global&&(await import("../global-JR77FFGO.js")).registerApiGlobally(),config.dom==="happy-dom")return(await import("../happy-dom-EZVJENUI.js")).setupHappyDOM(globalThis).restore;if(config.dom)return(await import("../jsdom-VHB26LUJ.js")).setupJSDOM(globalThis).restore}init_esm_shims();import{performance as performance2}from"perf_hooks";init_esm_shims();import{basename}from"path";import{performance}from"perf_hooks";import{nanoid}from"nanoid";init_esm_shims();function processError(err){return err&&(err.stack&&(err.stackStr=String(err.stack)),err.name&&(err.nameStr=String(err.name)),err)}async function collectTests(paths){let files=[];for(let filepath of paths){let file={id:nanoid(),name:basename(filepath),type:"suite",mode:"run",computeMode:"serial",filepath,tasks:[]};setHooks(file,createSuiteHooks()),clearContext();try{await import(filepath);for(let c of[defaultSuite,...context.tasks])if(c.type==="test")file.tasks.push(c);else{let suite=await c.collect(file);(suite.name||suite.tasks.length)&&file.tasks.push(suite)}}catch(e){file.result={start:performance.now(),state:"fail",error:processError(e)}}files.push(file)}let tasks=files.reduce((tasks2,file)=>tasks2.concat(file.tasks),[]);return interpretOnlyMode(tasks),tasks.forEach(i=>{i.type==="suite"&&(i.mode==="skip"?i.tasks.forEach(c=>c.mode==="run"&&(c.mode="skip")):interpretOnlyMode(i.tasks))}),files}async function callHook(suite,name,args){await Promise.all(getHooks(suite)[name].map(fn=>fn(...args)))}function updateTask(task){return rpc("onTaskUpdate",[task.id,task.result])}async function runTest(test){if(test.mode==="run"){test.result={start:performance2.now(),state:"run"},updateTask(test),getSnapshotClient().setTest(test);try{await callHook(test.suite,"beforeEach",[test,test.suite]),await getFn(test)(),test.result.state="pass"}catch(e){test.result.state="fail",test.result.error=processError(e)}try{await callHook(test.suite,"afterEach",[test,test.suite])}catch(e){test.result.state="fail",test.result.error=processError(e)}getSnapshotClient().clearTest(),test.result.end=performance2.now(),updateTask(test)}}async function runSuite(suite){var _a;if(((_a=suite.result)==null?void 0:_a.state)!=="fail"){if(suite.result={start:performance2.now(),state:"run"},updateTask(suite),suite.mode==="skip")suite.result.state="skip";else if(suite.mode==="todo")suite.result.state="todo";else try{await callHook(suite,"beforeAll",[suite]);for(let tasksGroup of partitionSuiteChildren(suite)){let computeMode=tasksGroup[0].computeMode;if(computeMode==="serial")for(let c of tasksGroup)await runSuiteChild(c);else computeMode==="concurrent"&&await Promise.all(tasksGroup.map(c=>runSuiteChild(c)))}await callHook(suite,"afterAll",[suite])}catch(e){suite.result.state="fail",suite.result.error=processError(e)}suite.result.end=performance2.now(),suite.mode==="run"&&(hasTests(suite)?hasFailed(suite)?suite.result.state="fail":suite.result.state="pass":(suite.result.state="fail",suite.result.error||(suite.result.error=new Error(`No tests found in suite ${suite.name}`)))),updateTask(suite)}}async function runSuiteChild(c){return c.type==="test"?runTest(c):runSuite(c)}async function runSuites(suites){for(let suite of suites)await runSuite(suite)}async function startTests(paths){let files=await collectTests(paths);send("onCollected",files),await runSuites(files),await getSnapshotClient().saveSnap()}async function run(files,config){let restore=await setupEnv(config);await startTests(files),restore==null||restore()}export{run};
|