Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/vitest-dev/vscode. VS Code extension for Vitest vitest.dev/vscode
testing vitest vscode
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126import { detectPackageManager } from './pkgManager'
// A compact (code-wise, probably not memory-wise) singly linked list node.type QueueNode<T> = [value: T, next?: QueueNode<T>]
/** * Return a function for running multiple async operations with limited concurrency. */export function limitConcurrency( concurrency = Number.POSITIVE_INFINITY,): <Args extends unknown[], T>( func: (...args: Args) => PromiseLike<T> | T, ...args: Args) => Promise<T> { // The number of currently active + pending tasks. let count = 0
// The head and tail of the pending task queue, built using a singly linked list. // Both head and tail are initially undefined, signifying an empty queue. // They both become undefined again whenever there are no pending tasks. let head: undefined | QueueNode<() => void> let tail: undefined | QueueNode<() => void>
// A bookkeeping function executed whenever a task has been run to completion. const finish = () => { count--
// Check if there are further pending tasks in the queue. if (head) { // Allow the next pending task to run and pop it from the queue. head[0]() head = head[1]
// The head may now be undefined if there are no further pending tasks. // In that case, set tail to undefined as well. tail = head && tail } }
return (func, ...args) => { // Create a promise chain that: // 1. Waits for its turn in the task queue (if necessary). // 2. Runs the task. // 3. Allows the next pending task (if any) to run. return new Promise<void>((resolve) => { if (count++ < concurrency) { // No need to queue if fewer than maxConcurrency tasks are running. resolve() } else if (tail) { // There are pending tasks, so append to the queue. tail = tail[1] = [resolve] } else { // No other pending tasks, initialize the queue with a new tail and head. head = tail = [resolve] } }) .then(() => { // Running func here ensures that even a non-thenable result or an // immediately thrown error gets wrapped into a Promise. return func(...args) }) .finally(finish) }}
export function assert(condition: unknown, message: string | (() => string)): asserts condition { if (!condition) { throw new Error(typeof message === 'string' ? message : message()) }}
export function getSuggestedInstallCommand(cwd: string) { const pkgManager = detectPackageManager(cwd) switch (pkgManager?.name) { case 'bun': return 'bun install --dev vitest' case 'yarn': return 'yarn add -D vitest' case 'pnpm': return 'pnpm add -D vitest' case 'npm': default: return 'npm i --save-dev vitest' }}
export function normalizeDriveLetter(path: string) { if (process.platform !== 'win32') return path return path[0].toUpperCase() + path.slice(1)}
export function createQueuedHandler<T>(resolver: (value: T[]) => Promise<void>, timeout = 50) { const cached = new Set<T>() let promise: Promise<void> | null = null let timer: ReturnType<typeof setTimeout> | null = null let pendingResolvers: Array<() => void> = []
function flush() { if (promise) return const values = [...cached] cached.clear() const resolvers = pendingResolvers pendingResolvers = [] promise = resolver(values).finally(() => { promise = null resolvers.forEach((fn) => fn()) // If more items were queued while resolving, flush them if (cached.size) flush() }) }
return (value: T): Promise<void> => { cached.add(value) if (timer) { clearTimeout(timer) } timer = setTimeout(() => { timer = null flush() }, timeout) return new Promise<void>((resolve) => { pendingResolvers.push(resolve) }) }}