Skip to content

Commit

Permalink
fix: use current available port for watch mode
Browse files Browse the repository at this point in the history
  • Loading branch information
zxch3n committed May 17, 2022
1 parent a89e61b commit 761b9d4
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 92 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"eslint": "^8.9.0",
"fs-extra": "^10.0.1",
"fuse.js": "^6.6.2",
"get-port": "^6.1.2",
"glob": "^7.2.0",
"mighty-promise": "^0.0.8",
"minimatch": "^3.1.1",
Expand Down
3 changes: 2 additions & 1 deletion src/pure/watch/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ type WebSocketStatus = 'OPEN' | 'CONNECTING' | 'CLOSED';
export type RunState = 'idle' | 'running'

export function buildWatchClient(
{ url = 'ws://localhost:51204/__vitest_api__', handlers }: {
{ port, url = `ws://localhost:${port}/__vitest_api__`, handlers }: {
url?: string
handlers?: Partial<WebSocketEvents>
port: number
},
) {
const client = createClient(url, {
Expand Down
200 changes: 109 additions & 91 deletions src/watch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ChildProcess } from 'child_process'
import getPort from 'get-port'
import { getTasks } from '@vitest/ws-client'
import { effect, ref } from '@vue/reactivity'
import Fuse from 'fuse.js'
Expand All @@ -14,6 +15,7 @@ import {
TestRunRequest,
workspace,
} from 'vscode'
import { Lock } from 'mighty-promise'
import { getConfig } from './config'
import type { TestFileDiscoverer } from './discover'
import { execWithLog } from './pure/utils'
Expand Down Expand Up @@ -47,6 +49,7 @@ export class TestWatcher extends Disposable {
public isWatching = ref(false)
public isRunning = ref(false)
public testStatus = ref({ passed: 0, failed: 0, skipped: 0 })
private lock = new Lock()
private process?: ChildProcess
private vitestState?: ReturnType<typeof buildWatchClient>
private run: TestRun | undefined
Expand All @@ -60,92 +63,100 @@ export class TestWatcher extends Disposable {
})
}

public watch() {
if (this.isWatching.value)
return

this.isRunning.value = true
this.isWatching.value = true
const logs = [] as string[]
let timer: any
this.process = execWithLog(
this.vitest.cmd,
[...this.vitest.args, '--api'],
{
cwd: workspace.workspaceFolders?.[0].uri.fsPath,
env: { ...process.env, ...getConfig().env },
},
(line) => {
logs.push(line)
clearTimeout(timer)
timer = setTimeout(() => {
console.log(logs.join('\n'))
logs.length = 0
}, 200)
},
(line) => {
logs.push(line)
clearTimeout(timer)
timer = setTimeout(() => {
console.log(logs.join('\n'))
logs.length = 0
}, 200)
},
).child

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

this.vitestState = buildWatchClient({
handlers: {
onTaskUpdate: (packs) => {
try {
if (!this.vitestState)
return

this.isRunning.value = true
const idMap = this.vitestState.client.state.idMap
const fileSet = new Set<File>()
for (const [id] of packs) {
const task = idMap.get(id)
if (!task)
continue

task.file && fileSet.add(task.file)
}

this.onUpdated(Array.from(fileSet), false)
}
catch (e) {
console.error(e)
}
public async watch() {
const release = await this.lock.acquire()
try {
if (this.isWatching.value)
return

this.isRunning.value = true
this.isWatching.value = true
const logs = [] as string[]
const port = await getPort({ port: 51204 })
let timer: any
this.process = execWithLog(
this.vitest.cmd,
[...this.vitest.args, '--api', port.toString()],
{
cwd: workspace.workspaceFolders?.[0].uri.fsPath,
env: { ...process.env, ...getConfig().env },
},
onFinished: (files) => {
try {
this.isRunning.value = false
this.onUpdated(files, true)
if (!this.run)
return

this.run.end()
this.run = undefined
this.updateStatus()
}
catch (e) {
console.error(e)
}
(line) => {
logs.push(line)
clearTimeout(timer)
timer = setTimeout(() => {
console.log(logs.join('\n'))
logs.length = 0
}, 200)
},
},
})

effect(() => {
this.onFileUpdated(this.vitestState!.files.value)
})
return this.vitestState.loadingPromise.then(() => {
this.updateStatus()
this.isRunning.value = false
})
(line) => {
logs.push(line)
clearTimeout(timer)
timer = setTimeout(() => {
console.log(logs.join('\n'))
logs.length = 0
}, 200)
},
).child

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

this.vitestState = buildWatchClient({
port,
handlers: {
onTaskUpdate: (packs) => {
try {
if (!this.vitestState)
return

this.isRunning.value = true
const idMap = this.vitestState.client.state.idMap
const fileSet = new Set<File>()
for (const [id] of packs) {
const task = idMap.get(id)
if (!task)
continue

task.file && fileSet.add(task.file)
}

this.onUpdated(Array.from(fileSet), false)
}
catch (e) {
console.error(e)
}
},
onFinished: (files) => {
try {
this.isRunning.value = false
this.onUpdated(files, true)
if (!this.run)
return

this.run.end()
this.run = undefined
this.updateStatus()
}
catch (e) {
console.error(e)
}
},
},
})

effect(() => {
this.onFileUpdated(this.vitestState!.files.value)
})
return this.vitestState.loadingPromise.then(() => {
this.updateStatus()
this.isRunning.value = false
})
}
finally {
release()
}
}

updateStatus() {
Expand Down Expand Up @@ -351,12 +362,19 @@ export class TestWatcher extends Disposable {
}
}

public dispose() {
console.log('Stop watch mode')
this.isWatching.value = false
this.vitestState?.client.dispose()
this.process?.kill()
this.process = undefined
this.vitestState = undefined
public async dispose() {
const release = await this.lock.acquire()
try {
console.log('Stop watch mode')
this.isWatching.value = false
this.isRunning.value = false
this.vitestState?.client.dispose()
this.process?.kill()
this.process = undefined
this.vitestState = undefined
}
finally {
release()
}
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.1"

get-port@^6.1.2:
version "6.1.2"
resolved "https://registry.npmmirror.com/get-port/-/get-port-6.1.2.tgz#c1228abb67ba0e17fb346da33b15187833b9c08a"
integrity sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==

get-stream@^6.0.0:
version "6.0.1"
resolved "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
Expand Down

0 comments on commit 761b9d4

Please sign in to comment.