Skip to content

Commit

Permalink
fix: run single test on Windows not working properly
Browse files Browse the repository at this point in the history
  • Loading branch information
IGx89 committed Dec 29, 2022
1 parent 7c3de6e commit c037333
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/pure/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
filterColorFormatOutput,
sanitizeFilePath,
} from './utils'
import { isWindows } from './platform'
import type { StartConfig } from './ApiProcess'
import { runVitestWithApi } from './ApiProcess'

Expand Down Expand Up @@ -77,8 +78,15 @@ export class TestRunner {
if (updateSnapshot)
args.push('--update')

if (testNamePattern)
args.push('-t', testNamePattern.replace(/[$^+?()[\]]/g, '\\$&'))
if (testNamePattern) {
// Vitest's test name pattern is a regex, so we need to escape any special regex characters.
// Additionally, when a custom start process is not used on Windows, child_process.spawn is used with shell: true.
// That disables automatic quoting/escaping of arguments, requiring us to manually perform that here as well.
if (isWindows && !customStartProcess)
args.push('-t', `"${testNamePattern.replace(/[$^+?()[\]"]/g, '\\$&')}"`)
else
args.push('-t', testNamePattern.replace(/[$^+?()[\]"]/g, '\\$&'))
}

const workspacePath = sanitizeFilePath(this.workspacePath, false)
const outputs: string[] = []
Expand Down
82 changes: 82 additions & 0 deletions test/runner.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { afterEach, describe, expect, test, vi } from 'vitest'
import { TestRunner } from '../src/pure/runner'
import * as platformConstants from '../src/pure/platform'

// Mock vscode ("pure" modules aren't quite pure)
vi.mock('vscode', () => {
return {
default: { myDefaultKey: vi.fn() },
namedExport: vi.fn(),
window: {
createOutputChannel: () => {
return {
appendLine: vi.fn(),
}
},
},
}
})

// Mock config
vi.mock('../src/config', () => {
return {
getConfig: () => {
return {
env: null,
}
},
}
})

// Mock runVitestWithApi, causing it to return its arguments as its output to allow us to assert their values
vi.mock('../src/pure/ApiProcess', () => {
return {
runVitestWithApi: (
vitest: { cmd: string; args: string[] },
workspace: string,
handlers: any,
customStartProcess?: (config: any) => void,
) => {
return `vitest.cmd=${vitest.cmd}`
+ ` vitest.args=${vitest.args}`
+ ` workspace=${workspace}`
+ ` customStartProcess=${!!customStartProcess}`
},
}
})

describe('TestRunner', () => {
const prevIsWindows = platformConstants.isWindows

afterEach(() => {
Object.defineProperty(platformConstants, 'isWindows', { value: prevIsWindows, writable: true })
})

test.each([
[false, false, 'vitest,abc.spec.ts,-t,a \\(b\\) \\\"c\\\" d'],
[false, true, 'vitest,abc.spec.ts,-t,a \\(b\\) \\\"c\\\" d'],
[true, false, 'vitest,abc.spec.ts,-t,\"a \\(b\\) \\\"c\\\" d\"'],
[true, true, 'vitest,abc.spec.ts,-t,a \\(b\\) \\\"c\\\" d'],
])('scheduleRun properly escapes arguments (isWindows: %s, customStartProcess: %s)', async (isWindows, useCustomStartProcess, expectedArgs) => {
Object.defineProperty(platformConstants, 'isWindows', { value: isWindows, writable: true })

const workspacePath = '/test'
const testFiles = ['abc.spec.ts']
const testNamePattern = 'a (b) "c" d'
const customStartProcess = useCustomStartProcess ? () => {} : undefined

const { testResultFiles, output } = await new TestRunner(workspacePath, undefined).scheduleRun(
testFiles,
testNamePattern,
undefined,
undefined,
undefined,
undefined,
undefined,
customStartProcess,
)

expect(testResultFiles).toBeDefined()
expect(output).toBe(`vitest.cmd=npx vitest.args=${expectedArgs} workspace=/test customStartProcess=${useCustomStartProcess}`)
})
})

0 comments on commit c037333

Please sign in to comment.