@pact-toolbox/test
Version:
1 lines • 11.7 kB
Source Map (JSON)
{"version":3,"file":"index.node.cjs","names":["configOverrides?: Partial<PactToolboxConfigObj> | string","config: PactToolboxConfigObj","PactToolboxClient","PactToolboxNetwork","items: T[]","iteratorFn: (item: T) => Promise<R>","concurrency: number","results: R[]","running: Promise<void>[]","config?: Required<PactToolboxConfigObj>","file: string","result"],"sources":["../src/utils.ts","../src/createTestEnv.ts","../src/repl.ts"],"sourcesContent":["import type { NetworkConfig, PactToolboxConfigObj } from \"@pact-toolbox/config\";\n\nimport {\n getNetworkConfig,\n getSerializableNetworkConfig,\n isDevNetworkConfig,\n isPactServerNetworkConfig,\n} from \"@pact-toolbox/config\";\nimport { getRandomNetworkPorts } from \"@pact-toolbox/utils\";\n\nexport function getConfigOverrides(\n configOverrides?: Partial<PactToolboxConfigObj> | string,\n): Partial<PactToolboxConfigObj> {\n if (typeof configOverrides === \"string\") {\n return {\n defaultNetwork: configOverrides,\n };\n }\n return configOverrides || {};\n}\n\nexport function injectNetworkConfig(config: PactToolboxConfigObj): void {\n const network = getSerializableNetworkConfig(config);\n (globalThis as any).__PACT_TOOLBOX_NETWORK_CONFIG__ = network;\n}\n\nexport async function updatePorts(config: PactToolboxConfigObj): Promise<NetworkConfig> {\n const ports = await getRandomNetworkPorts();\n const network = getNetworkConfig(config);\n if (isPactServerNetworkConfig(network)) {\n if (network.serverConfig) {\n network.serverConfig.port = ports.service;\n }\n }\n if (isDevNetworkConfig(network)) {\n if (network.containerConfig) {\n network.containerConfig.port = ports.service;\n }\n }\n\n return network;\n}\n","import type { PactToolboxConfigObj } from \"@pact-toolbox/config\";\n\nimport { resolveConfig } from \"@pact-toolbox/config\";\nimport { PactToolboxNetwork } from \"@pact-toolbox/network\";\nimport { PactToolboxClient } from \"@pact-toolbox/runtime\";\nimport { logger } from \"@pact-toolbox/utils\";\n\nimport { injectNetworkConfig, updatePorts } from \"./utils\";\n\nexport interface PactTestEnv {\n client: PactToolboxClient;\n stop: () => Promise<void>;\n start: () => Promise<void>;\n restart: () => Promise<void>;\n config: PactToolboxConfigObj;\n}\n\nexport interface CreatePactTestEnvOptions {\n network?: string;\n client?: PactToolboxClient;\n configOverrides?: Partial<PactToolboxConfigObj>;\n config?: Required<PactToolboxConfigObj>;\n isStateless?: boolean;\n}\nexport async function createPactTestEnv({\n network,\n client,\n config,\n configOverrides,\n}: CreatePactTestEnvOptions = {}): Promise<PactTestEnv> {\n logger.pauseLogs();\n if (!config) {\n config = await resolveConfig(configOverrides);\n }\n\n if (network) {\n config.defaultNetwork = network;\n }\n\n await updatePorts(config);\n injectNetworkConfig(config);\n\n if (!client) {\n client = new PactToolboxClient(config);\n }\n\n const localNetwork = new PactToolboxNetwork(config, {\n client,\n isDetached: true,\n logAccounts: false,\n isStateless: true,\n });\n return {\n start: async () => localNetwork.start(),\n stop: async () => localNetwork.stop(),\n restart: async () => localNetwork.restart(),\n client,\n config,\n };\n}\n","import type { PactToolboxConfigObj } from \"@pact-toolbox/config\";\nimport { join } from \"pathe\";\nimport readdir from \"tiny-readdir-glob\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { cpus } from \"node:os\";\nimport { resolveConfig } from \"@pact-toolbox/config\";\nimport { execAsync } from \"@pact-toolbox/utils\";\n\ninterface TestResult {\n filePath: string;\n status: \"passed\" | \"failed\";\n error?: Error;\n duration: number;\n}\n\nasync function runWithConcurrency<T, R>(\n items: T[],\n iteratorFn: (item: T) => Promise<R>,\n concurrency: number,\n): Promise<R[]> {\n const results: R[] = [];\n const running: Promise<void>[] = [];\n let index = 0;\n\n async function run() {\n if (index >= items.length) {\n return;\n }\n const i = index++;\n const item = items[i];\n if (!item) return;\n\n const promise = iteratorFn(item).then((result) => {\n results[i] = result;\n });\n\n running.push(promise);\n\n if (running.length >= concurrency) {\n await Promise.race(running);\n }\n\n await promise.finally(() => {\n const promiseIndex = running.indexOf(promise);\n if (promiseIndex > -1) {\n running.splice(promiseIndex, 1);\n }\n });\n\n await run();\n }\n\n const initialRuns = Array.from({ length: Math.min(concurrency, items.length) }, run);\n await Promise.all(initialRuns);\n await Promise.all(running);\n\n return results;\n}\n\nexport async function runReplTests(config?: Required<PactToolboxConfigObj>): Promise<void> {\n const startTime = Date.now();\n if (!config) {\n config = await resolveConfig();\n }\n\n const spinner = ora(\"Finding REPL tests\").start();\n\n const cwd = join(process.cwd(), config.contractsDir);\n const aborter = new AbortController();\n const result = await readdir(`**/*.repl`, {\n cwd,\n depth: 20,\n limit: 1_000_000,\n followSymlinks: true,\n ignore: [\"prelude/**\"],\n signal: aborter.signal,\n });\n\n const testFiles = result.files;\n\n if (testFiles.length === 0) {\n spinner.succeed(\"No REPL tests found.\");\n return;\n }\n\n spinner.info(`${testFiles.length} tests found.`);\n spinner.start(`Running REPL tests...`);\n\n let completed = 0;\n\n const runTest = async (file: string): Promise<TestResult> => {\n const testStartTime = Date.now();\n const cleanedFile = file.replace(cwd, \"\").substring(1);\n try {\n await execAsync(`pact -t ${file}`);\n const duration = Date.now() - testStartTime;\n completed++;\n spinner.text = `[${completed}/${testFiles.length}] Running REPL tests... (${cleanedFile})`;\n return { filePath: cleanedFile, status: \"passed\", duration };\n } catch (error) {\n completed++;\n spinner.text = `[${completed}/${testFiles.length}] Running REPL tests... (${cleanedFile})`;\n const duration = Date.now() - testStartTime;\n return {\n filePath: cleanedFile,\n status: \"failed\",\n error: error as Error,\n duration,\n };\n }\n };\n\n const concurrency = Math.max(1, cpus().length - 1);\n const allResults = await runWithConcurrency(testFiles, runTest, concurrency);\n\n spinner.stop();\n const totalDuration = Date.now() - startTime;\n\n const passedTests = allResults.filter((r) => r.status === \"passed\");\n const failedTests = allResults.filter((r) => r.status === \"failed\");\n\n console.log(\"\\n\");\n\n for (const result of allResults) {\n if (result.status === \"passed\") {\n console.log(`${chalk.green.bold(\"PASS\")} ${result.filePath} ${chalk.gray(`(${result.duration}ms)`)}`);\n } else {\n console.log(`${chalk.red.bold(\"FAIL\")} ${result.filePath} ${chalk.gray(`(${result.duration}ms)`)}`);\n }\n }\n\n if (failedTests.length > 0) {\n console.log(`\\n${chalk.red.bold(\"Failed Tests:\")}`);\n for (const test of failedTests) {\n console.log(`\\n${chalk.red.bold(\"●\")} ${test.filePath}`);\n const errorMessage = test.error?.message ?? \"Unknown error\";\n const cleanedError = errorMessage.includes(\"Command failed:\")\n ? (errorMessage.split(\"Command failed:\")[1]?.trim() ?? \"\")\n : errorMessage;\n console.log(`${chalk.red(cleanedError)}`);\n }\n }\n\n console.log(\"\\n\");\n console.log(chalk.bold(\"REPL Test-runner Summary\"));\n console.log(\n ` ${chalk.bold(\"Test Suites:\")} ${\n failedTests.length > 0 ? `${chalk.red.bold(`${failedTests.length} failed`)}, ` : \"\"\n }${chalk.green.bold(`${passedTests.length} passed`)}, ${allResults.length} total`,\n );\n console.log(` ${chalk.bold(\"Time:\")} ${(totalDuration / 1000).toFixed(2)}s`);\n console.log(\"\\n\");\n\n if (failedTests.length > 0) {\n process.exit(1);\n }\n}\n"],"mappings":"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"}