Skip to content

Handle when project config is re-created #1300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 7, 2025
Prev Previous commit
Next Next commit
Add support for test “matrix” inputs
  • Loading branch information
thecrypticace committed Apr 7, 2025
commit b092c4652dbe62e5ba30f7eb9e76118df31bd8af
34 changes: 25 additions & 9 deletions packages/tailwindcss-language-server/src/testing/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { onTestFinished, test, TestOptions } from 'vitest'
import { onTestFinished, test, TestContext, TestOptions } from 'vitest'
import * as os from 'node:os'
import * as fs from 'node:fs/promises'
import * as path from 'node:path'
import * as proc from 'node:child_process'
import dedent from 'dedent'

export interface TestUtils {
export interface TestUtils<TestInput extends Record<string, any>> {
/** The "cwd" for this test */
root: string

/**
* The input for this test — taken from the `inputs` in the test config
*
* @see {TestConfig}
*/
input?: TestInput
}

export interface StorageSymlink {
Expand All @@ -21,19 +28,21 @@ export interface Storage {
[filePath: string]: string | Uint8Array | StorageSymlink
}

export interface TestConfig<Extras extends {}> {
export interface TestConfig<Extras extends {}, TestInput extends Record<string, any>> {
name: string
inputs?: TestInput[]

fs?: Storage
debug?: boolean
prepare?(utils: TestUtils): Promise<Extras>
handle(utils: TestUtils & Extras): void | Promise<void>
prepare?(utils: TestUtils<TestInput>): Promise<Extras>
handle(utils: TestUtils<TestInput> & Extras): void | Promise<void>

options?: TestOptions
}

export function defineTest<T>(config: TestConfig<T>) {
async function runTest(ctx: TestContext) {
let utils = await setup(config)
export function defineTest<T, I>(config: TestConfig<T, I>) {
async function runTest(ctx: TestContext, input?: I) {
let utils = await setup(config, input)
let extras = await config.prepare?.(utils)

await config.handle({
Expand All @@ -42,10 +51,16 @@ export function defineTest<T>(config: TestConfig<T>) {
})
}

if (config.inputs) {
return test.for(config.inputs ?? [])(config.name, config.options ?? {}, (input, ctx) =>
runTest(ctx, input),
)
}

return test(config.name, config.options ?? {}, runTest)
}

async function setup<T>(config: TestConfig<T>): Promise<TestUtils> {
async function setup<T, I>(config: TestConfig<T, I>, input: I): Promise<TestUtils<I>> {
let randomId = Math.random().toString(36).substring(7)

let baseDir = path.resolve(process.cwd(), `../../.debug/${randomId}`)
Expand Down Expand Up @@ -81,6 +96,7 @@ async function setup<T>(config: TestConfig<T>): Promise<TestUtils> {

return {
root: baseDir,
input,
}
}

Expand Down