-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: introduce the new reporter API #7069
base: main
Are you sure you want to change the base?
Changes from all commits
0998e4f
6f0da08
64abbda
f3686b0
9cd58e9
3f6edd5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Test Lifecycle | ||
|
||
<!-- TODO: lifecyle diagram and reporter API --> | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import type { TaskResultPack } from '@vitest/runner' | ||
import type { Vitest } from './core' | ||
import type { TestCase, TestModule } from './reporters/reported-tasks' | ||
import type { TestSpecification } from './spec' | ||
|
||
export class TestRun { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can start helping out with this. Did you already have an idea how this should be integrated into the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted to have parsing logic here, and use higher level methods in This is also the place where we call reporter methods related to the test run ( The inspiration for method names is https://vshaxe.github.io/vscode-extern/vscode/TestRun.html There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also think that proposed events are not enough, we will probably need to add more There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also added |
||
private tests = emptyCounters() | ||
private suites = emptyCounters() | ||
|
||
// Internal state to prevent reporting duplicates and guaranteeing correct order | ||
private runningTestModules = new Set<TestModule['id']>() | ||
private finishedTestModules = new Set<TestModule['id']>() | ||
|
||
private runningTestCases = new Set<TestCase['id']>() | ||
private finishedTestCases = new Set<TestCase['id']>() | ||
|
||
constructor(private vitest: Vitest) {} | ||
|
||
async start(specifications: TestSpecification[]) { | ||
this.tests = emptyCounters() | ||
this.suites = emptyCounters() | ||
this.suites.total = specifications.length | ||
|
||
this.runningTestModules.clear() | ||
this.finishedTestModules.clear() | ||
this.runningTestCases.clear() | ||
this.finishedTestCases.clear() | ||
|
||
await this.vitest.report('onTestRunStart', specifications) | ||
} | ||
|
||
enqueued(_module: TestModule) { | ||
// TODO | ||
} | ||
|
||
collected(_modules: TestModule[]) { | ||
// TODO | ||
} | ||
|
||
async updated(update: TaskResultPack[]) { | ||
const runningTestModules: TestModule[] = [] | ||
const finishedTestModules: TestModule[] = [] | ||
|
||
const runningTestCases: TestCase[] = [] | ||
const finishedTestCases: TestCase[] = [] | ||
|
||
for (const [id] of update) { | ||
const entity = this.vitest.state.getReportedEntity(this.vitest.state.idMap.get(id)) | ||
|
||
if (!entity) { | ||
continue | ||
} | ||
|
||
if (entity.type === 'module') { | ||
const state = entity.state() | ||
|
||
if (state === 'pending' && !this.runningTestModules.has(entity.id)) { | ||
this.runningTestModules.add(entity.id) | ||
runningTestModules.push(entity) | ||
} | ||
|
||
if (state !== 'pending' && state !== 'queued' && !this.finishedTestModules.has(entity.id)) { | ||
this.finishedTestModules.add(entity.id) | ||
finishedTestModules.push(entity) | ||
|
||
// If module run was fast, it's possible that it was never reported to be running | ||
if (!this.runningTestModules.has(entity.id)) { | ||
this.runningTestModules.add(entity.id) | ||
runningTestModules.push(entity) | ||
} | ||
|
||
// Skipped tests need to be reported manually once test module has finished | ||
for (const test of entity.children.tests()) { | ||
if (!this.finishedTestCases.has(test.id)) { | ||
this.finishedTestCases.add(test.id) | ||
finishedTestCases.push(test) | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (entity.type === 'test') { | ||
const state = entity.result().state | ||
|
||
if (state === 'pending' && !this.runningTestCases.has(entity.id)) { | ||
this.runningTestCases.add(entity.id) | ||
runningTestCases.push(entity) | ||
} | ||
|
||
if (state !== 'pending' && !this.finishedTestCases.has(entity.id)) { | ||
this.finishedTestCases.add(entity.id) | ||
finishedTestCases.push(entity) | ||
|
||
// If test finished quickly, it's possible that it was never reported as running | ||
if (!this.runningTestCases.has(entity.id)) { | ||
this.runningTestCases.add(entity.id) | ||
runningTestCases.push(entity) | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Order of reporting is important here | ||
await Promise.all(finishedTestCases.map(testCase => this.vitest.report('onTestCaseFinished', testCase))) | ||
await Promise.all(finishedTestModules.map(module => this.vitest.report('onTestModuleFinished', module))) | ||
|
||
await Promise.all(runningTestModules.map(module => this.vitest.report('onTestModulePrepare', module))) | ||
await Promise.all(runningTestCases.map(testCase => this.vitest.report('onTestCasePrepare', testCase))) | ||
} | ||
|
||
async end() { | ||
// TODO | ||
await this.vitest.report('onTestRunEnd', [], [], 'passed') | ||
} | ||
} | ||
|
||
interface Counter { | ||
total: number | ||
completed: number | ||
passed: number | ||
failed: number | ||
skipped: number | ||
todo: number | ||
} | ||
|
||
function emptyCounters(): Counter { | ||
return { completed: 0, passed: 0, failed: 0, skipped: 0, todo: 0, total: 0 } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we use
vitepress-plugin-mermaid
for this? 🤔https://emersonbottero.github.io/vitepress-plugin-mermaid/guide/styles.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe when the lifecycle is finalised