Skip to content

Commit

Permalink
fix: add log & fix potential error cause #44
Browse files Browse the repository at this point in the history
  • Loading branch information
zxch3n committed Jun 18, 2022
1 parent 5b61b1c commit 080b5b8
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 47 deletions.
23 changes: 21 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { workspace } from 'vscode'
import * as vscode from 'vscode'
import type { WorkspaceConfiguration, WorkspaceFolder } from 'vscode'
import { isVitestEnv } from './pure/isVitestEnv'
export const extensionId = 'zxch3n.vitest-explorer'

export function getConfigValue<T>(
Expand All @@ -12,6 +13,7 @@ export function getConfigValue<T>(
}

export function getConfig(workspaceFolder: WorkspaceFolder) {
const workspace = vscode.workspace
const folderConfig = workspace.getConfiguration('vitest', workspaceFolder)
const rootConfig = workspace.getConfiguration('vitest')

Expand All @@ -27,9 +29,26 @@ export function getConfig(workspaceFolder: WorkspaceFolder) {
}

export function getRootConfig() {
const rootConfig = workspace.getConfiguration('vitest')
const rootConfig = vscode.workspace.getConfiguration('vitest')

return {
showFailMessages: rootConfig.get('showFailMessages', false),
}
}

export const vitestEnvironmentFolders: ReadonlyArray<WorkspaceFolder> = []

export async function detectVitestEnvironmentFolders() {
const vitestFolders = vitestEnvironmentFolders as WorkspaceFolder[]
vitestFolders.splice(0, vitestFolders.length)
if (
vscode.workspace.workspaceFolders == null
|| vscode.workspace.workspaceFolders.length === 0
)
return

for (const folder of vscode.workspace.workspaceFolders) {
if (await isVitestEnv(folder) || getConfig(folder).enable)
vitestFolders.push(folder)
}
}
3 changes: 2 additions & 1 deletion src/discover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { shouldIncludeFile } from './vscodeUtils'

import { getConfig } from './config'
import { log } from './log'

export class TestFileDiscoverer extends vscode.Disposable {
private lastWatches = [] as vscode.FileSystemWatcher[]
Expand Down Expand Up @@ -251,7 +252,7 @@ export function discoverTestFromFileContent(
result = parse(fileItem.id, content)
}
catch (e) {
console.log('parse error')
log.error('parse error')
return
}

Expand Down
31 changes: 10 additions & 21 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
import * as vscode from 'vscode'
import semver from 'semver'
import { effect } from '@vue/reactivity'
import { extensionId, getConfig } from './config'
import { detectVitestEnvironmentFolders, extensionId, getConfig, vitestEnvironmentFolders } from './config'
import { TestFileDiscoverer } from './discover'
import { isVitestEnv } from './pure/isVitestEnv'
import { getVitestCommand, getVitestVersion, isNodeAvailable, negate } from './pure/utils'
import { debugHandler, gatherTestItemsFromWorkspace, runHandler, updateSnapshot } from './runHandler'
import { TestFile, WEAKMAP_TEST_DATA } from './TestData'
import { TestWatcher } from './watch'
import { Command } from './command'
import { StatusBarItem } from './StatusBarItem'
import { log } from './log'

const log = vscode.window.createOutputChannel('Vitest')
export async function activate(context: vscode.ExtensionContext) {
if (
vscode.workspace.workspaceFolders == null
|| vscode.workspace.workspaceFolders.length === 0
)
await detectVitestEnvironmentFolders()
if (vitestEnvironmentFolders.length === 0) {
log.info('The extension is not activated because no Vitest environment was detected.')
return

const vitestEnvironmentFolders: Array<vscode.WorkspaceFolder> = []

for (const folder of vscode.workspace.workspaceFolders) {
if (await isVitestEnv(folder) || getConfig(folder).enable)
vitestEnvironmentFolders.push(folder)
}

if (vitestEnvironmentFolders.length === 0)
return

const ctrl = vscode.tests.createTestController(`${extensionId}`, 'Vitest')

const fileDiscoverer = new TestFileDiscoverer()
Expand Down Expand Up @@ -61,12 +50,12 @@ export async function activate(context: vscode.ExtensionContext) {
const cmd = getVitestCommand(folder.uri.fsPath)

const version = await getVitestVersion(cmd, getConfig(folder).env || undefined).catch(async (e) => {
log.appendLine(e.toString())
log.appendLine(`process.env.PATH = ${process.env.PATH}`)
log.appendLine(`vitest.nodeEnv = ${JSON.stringify(getConfig(folder).env)}`)
log.info(e.toString())
log.info(`process.env.PATH = ${process.env.PATH}`)
log.info(`vitest.nodeEnv = ${JSON.stringify(getConfig(folder).env)}`)
let errorMsg = e.toString()
if (!isNodeAvailable(getConfig(folder).env || undefined)) {
log.appendLine('Cannot spawn node process')
log.info('Cannot spawn node process')
errorMsg += 'Cannot spawn node process. Please try setting vitest.nodeEnv as {"PATH": "/path/to/node"} in your settings.'
}

Expand All @@ -89,7 +78,7 @@ export async function activate(context: vscode.ExtensionContext) {
}))

vitestRunConfigs.forEach((vitest) => {
console.log(`Vitest Workspace: [${vitest.workspace.name}] Version: ${vitest.version}`)
log.info(`Vitest Workspace [${vitest.workspace.name}]: Vitest version = ${vitest.version}`)
})

const isCompatibleVitestConfig = (config: typeof vitestRunConfigs[number]) =>
Expand Down
27 changes: 27 additions & 0 deletions src/log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { window } from 'vscode'

const _log = window.createOutputChannel('Vitest')
export const log = {
info: (...args: any[]) => {
console.log(...args)
const time = new Date().toLocaleTimeString()
_log.appendLine(`[INFO ${time}] ${args.join(' ')}`)
},
error: (...args: any[]) => {
console.error(...args)
const time = new Date().toLocaleTimeString()
for (let i = 0; i < args.length; i++) {
if (args[i] instanceof Error) {
const err = args[i] as Error
args[i] = `[Error ${err.name}] ${err.message}\n${err.stack}`
}
}
_log.appendLine(`[Error ${time}] ${args.join(' ')}`)
},
workspaceInfo: (folder: string, ...args: any[]) => {
log.info(`[Workspace ${folder}]`, ...args)
},
workspaceError: (folder: string, ...args: any[]) => {
log.error(`[Workspace ${folder}]`, ...args)
},
} as const
5 changes: 3 additions & 2 deletions src/pure/watch/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import WebSocket from 'ws'
import { computed, effect, reactive, ref, shallowRef } from '@vue/reactivity'
import type { ResolvedConfig, Task, TaskResult, WebSocketEvents } from 'vitest'
import { log } from '../../log'
import { createClient } from './ws-client'

type WebSocketStatus = 'OPEN' | 'CONNECTING' | 'CLOSED';
Expand Down Expand Up @@ -28,7 +29,7 @@ export function buildWatchClient(
const ws = client.ws
status.value = 'CONNECTING'
ws.addEventListener('open', () => {
console.log('WS Opened')
log.info('WS Opened')
status.value = 'OPEN'
client.state.filesMap.clear()
client.rpc.getFiles().then(files => client.state.collectFiles(files))
Expand All @@ -40,7 +41,7 @@ export function buildWatchClient(
})

ws.addEventListener('close', () => {
console.log('WS Close')
log.info('WS Close')
setTimeout(() => {
if (status.value === 'CONNECTING')
status.value = 'CLOSED'
Expand Down
67 changes: 51 additions & 16 deletions src/runHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
} from './TestData'
import { getConfig } from './config'
import { TestWatcher } from './watch'
import { log } from './log'

export async function runHandler(
ctrl: vscode.TestController,
Expand All @@ -32,20 +33,24 @@ export async function runHandler(
if (
vscode.workspace.workspaceFolders === undefined
|| vscode.workspace.workspaceFolders.length === 0
)
) {
log.info('ERROR: No workspace folder found')
vscode.window.showErrorMessage('Cannot run tests: No workspace folder found')
return
}

if (watchers.some(watcher => TestWatcher.isWatching(watcher.id)) && watchers.length > 0) {
log.info('Use watchers to run tests')
watchers.forEach((watcher) => {
watcher.runTests(gatherTestItemsFromWorkspace(request.include ?? [], watcher.workspace.uri.fsPath))
})

return
}

log.info('Tests run start')
const run = ctrl.createTestRun(request)

for (const folder of vscode.workspace.workspaceFolders) {
await Promise.allSettled(vscode.workspace.workspaceFolders.map(async (folder) => {
const runner = new TestRunner(
folder.uri.fsPath,
getVitestCommand(folder.uri.fsPath),
Expand All @@ -54,11 +59,27 @@ export async function runHandler(
const items = request.include ?? ctrl.items

const testForThisWorkspace = gatherTestItemsFromWorkspace(items, folder.uri.fsPath)
if (testForThisWorkspace.length)
if (testForThisWorkspace.length === 0)
return

log.info(`[Workspace "${folder.name}] Run tests from workspace`)
try {
await runTest(ctrl, runner, run, testForThisWorkspace, 'run')
}
log.info(`[Workspace "${folder.name}] Test run finished"`)
}
catch (e) {
log.error(`[Workspace "${folder.name}] Run error`)
if (e instanceof Error) {
const err = e
console.error(e)
log.info(`[Workspace ${folder.name}] Error: ${e.toString()}`)
testForThisWorkspace.forEach(test => run.errored(test, new vscode.TestMessage(err.toString())))
}
}
}))

run.end()
log.info('Tests run end')
}

export async function updateSnapshot(
Expand Down Expand Up @@ -98,10 +119,20 @@ export async function debugHandler(

for (const folder of vscode.workspace.workspaceFolders) {
const items = request.include ?? ctrl.items

const testForThisWorkspace = gatherTestItemsFromWorkspace(items, folder.uri.fsPath)
if (testForThisWorkspace.length)
await runTest(ctrl, undefined, run, testForThisWorkspace, 'debug')
const testsInThisWorkspace = gatherTestItemsFromWorkspace(items, folder.uri.fsPath)
if (testsInThisWorkspace.length === 0)
return
try {
await runTest(ctrl, undefined, run, testsInThisWorkspace, 'debug')
}
catch (e) {
if (e instanceof Error) {
const err = e
console.error(e)
log.info(`Error in ${folder.name}: ${e.toString()}`)
testsInThisWorkspace.forEach(test => run.errored(test, new vscode.TestMessage(err.toString())))
}
}
}

run.end()
Expand All @@ -125,7 +156,7 @@ export function gatherTestItemsFromWorkspace(collection: readonly vscode.TestIte
return gatherTestItems(collection).filter((item: vscode.TestItem) => item.uri && isPathASubdirectory(workspace, item.uri.fsPath))
}

function determineWorkspaceForTestItems(collection: readonly vscode.TestItem[] | vscode.TestItemCollection, workspaces: readonly vscode.WorkspaceFolder[]) {
function determineWorkspaceForTestItems(collection: readonly vscode.TestItem[] | vscode.TestItemCollection, workspaces: readonly vscode.WorkspaceFolder[]): vscode.WorkspaceFolder {
if (workspaces.length === 1)
return workspaces[0]

Expand Down Expand Up @@ -161,8 +192,9 @@ async function runTest(
for (const item of items) {
const testingData = WEAKMAP_TEST_DATA.get(item)
if (!testingData) {
console.error('Item not found')
throw new Error('Item not found')
log.workspaceError(workspaceFolder.name, `Item not found ${item.uri?.fsPath}`)
run.errored(item, new vscode.TestMessage('Item not found'))
continue
}

if (testingData instanceof TestFile)
Expand All @@ -174,8 +206,11 @@ async function runTest(
}
else {
file = testingData.fileItem
if (!file)
throw new Error('file item not found')
if (!file) {
log.workspaceError(workspaceFolder.name, `File item not found for item ${item.uri?.fsPath}`)
run.errored(item, new vscode.TestMessage('Item not found'))
continue
}
}

fileItems.push(file)
Expand Down Expand Up @@ -348,7 +383,7 @@ async function debugTest(
() => {
vscode.debug.onDidChangeActiveDebugSession((e) => {
if (!e) {
console.log('DISCONNECTED')
log.info('DISCONNECTED')
setTimeout(async () => {
if (!existsSync(outputFilePath)) {
const prefix = 'When running:\r\n'
Expand All @@ -371,7 +406,7 @@ async function debugTest(
},
(err) => {
console.error(err)
console.log('START DEBUGGING FAILED')
log.error('START DEBUGGING FAILED', err)
reject(new Error('START DEBUGGING FAILED'))
},
)
Expand Down
11 changes: 6 additions & 5 deletions src/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { execWithLog } from './pure/utils'
import { buildWatchClient } from './pure/watch/client'
import type { TestFile } from './TestData'
import { TestCase, TestDescribe, WEAKMAP_TEST_DATA } from './TestData'
import { log } from './log'

const stackUtils = new StackUtils({
cwd: '/ensure_absolute_paths',
Expand Down Expand Up @@ -83,22 +84,22 @@ export class TestWatcher extends Disposable {
logs.push(line)
clearTimeout(timer)
timer = setTimeout(() => {
console.log(logs.join('\n'))
log.info(logs.join('\n'))
logs.length = 0
}, 200)
},
(line) => {
logs.push(line)
clearTimeout(timer)
timer = setTimeout(() => {
console.log(logs.join('\n'))
log.info(logs.join('\n'))
logs.length = 0
}, 200)
},
).child

this.process.on('exit', () => {
console.log('VITEST WATCH PROCESS EXIT')
log.info('VITEST WATCH PROCESS EXIT')
})

this.vitestState = buildWatchClient({
Expand Down Expand Up @@ -204,7 +205,7 @@ export class TestWatcher extends Disposable {
)
}

private runFiles(files: File[]) {
private runFiles(files: File[]): Promise<void> | undefined {
if (!this.vitestState)
return

Expand Down Expand Up @@ -359,7 +360,7 @@ export class TestWatcher extends Disposable {
public async dispose() {
const release = await this.lock.acquire()
try {
console.log('Stop watch mode')
log.info('Stop watch mode')
this.isWatching.value = false
this.isRunning.value = false
this.vitestState?.client.dispose()
Expand Down

0 comments on commit 080b5b8

Please sign in to comment.