Skip to content

Commit

Permalink
fix: make runSuite proceed to completion when no checks are defined (#…
Browse files Browse the repository at this point in the history
…205)

Fixes #204
  • Loading branch information
chrispcampbell authored Jun 27, 2022
1 parent 8d4fdce commit 32b2edb
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
9 changes: 9 additions & 0 deletions packages/check-core/src/perf/perf-stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ export class PerfStats {
}

toReport(): PerfReport {
if (this.times.length === 0) {
return {
minTime: 0,
maxTime: 0,
avgTime: 0,
allTimes: []
}
}

// Get the absolute min and max times, just for informational
// purposes (these will be thrown out before computing the average)
const minTime = Math.min(...this.times)
Expand Down
34 changes: 33 additions & 1 deletion packages/check-core/src/suite/suite-runner.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import { outputVar } from '../check/_mocks/mock-check-dataset'
import { inputVar } from '../check/_mocks/mock-check-scenario'
import { createConfig } from '../config/config'
import type { Config, ConfigOptions } from '../config/config-types'
import type { SuiteReport } from './suite-report'
import type { RunSuiteCallbacks } from './suite-runner'
import { runSuite } from './suite-runner'

interface MockConfigOptions {
emptyTests?: boolean
invalidTests?: boolean
throwInCurrentGetDatasets?: boolean
}
Expand Down Expand Up @@ -56,7 +58,9 @@ function mockBundle(mockOptions: MockConfigOptions): Bundle {

async function mockConfig(mockOptions: MockConfigOptions): Promise<Config> {
let tests: string[]
if (mockOptions.invalidTests === true) {
if (mockOptions.emptyTests === true) {
tests = []
} else if (mockOptions.invalidTests === true) {
tests = ['INVALID']
} else {
const test = `
Expand Down Expand Up @@ -111,6 +115,34 @@ describe('runSuite', () => {
expect(progressPcts).toEqual([0, 0.5, 1])
})

it('should notify progress and completion callbacks even when there are no tests', async () => {
const config = await mockConfig({ emptyTests: true })

const progressPcts: number[] = []
const report: SuiteReport = await new Promise((resolve, reject) => {
const callbacks: RunSuiteCallbacks = {
onProgress: pct => {
progressPcts.push(pct)
},
onComplete: suiteReport => {
resolve(suiteReport)
},
onError: () => {
reject(new Error('onError should not be called'))
}
}
runSuite(config, callbacks)
})

expect(report).toEqual({
checkReport: {
groups: []
},
compareReport: undefined
})
expect(progressPcts).toEqual([0, 1])
})

it('should notify error callback if there was an error', async () => {
const config = await mockConfig({ invalidTests: true })

Expand Down
25 changes: 24 additions & 1 deletion packages/check-core/src/suite/suite-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,35 @@ class SuiteRunner {
}
}

// Schedule the tasks. The ref data tasks must be processed first so that
// Plan the data tasks. The ref data tasks must be processed first so that
// the reference data is available in memory when checks are performed.
const refDataPlan = refDataPlanner.buildPlan()
const dataPlan = dataPlanner.buildPlan()
const dataRequests = [...refDataPlan.requests, ...dataPlan.requests]
const taskCount = dataRequests.length
if (taskCount === 0) {
// There are no checks or comparison tests; notify completion callback
// with empty reports
let compareReport: CompareReport
if (this.config.compare) {
compareReport = {
datasetReports: [],
perfReportL: this.perfStatsL.toReport(),
perfReportR: this.perfStatsR.toReport()
}
}
this.cancel()
this.callbacks.onProgress?.(1)
this.callbacks.onComplete?.({
checkReport: {
groups: []
},
compareReport
})
return
}

// Schedule a task for each data request
let tasksCompleted = 0
let dataTaskId = 1
for (const dataRequest of dataRequests) {
Expand Down

0 comments on commit 32b2edb

Please sign in to comment.