chore(cli): rename test files from .mts to .ts
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"test:e2e": "npx zx tests/run-all.mts"
|
"test:e2e": "npx zx tests/run-all.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@paseo/server": "*",
|
"@paseo/server": "*",
|
||||||
|
|||||||
@@ -1,17 +1,32 @@
|
|||||||
import { Command } from 'commander'
|
import { Command } from 'commander'
|
||||||
import { startCommand } from './start.js'
|
import { startCommand } from './start.js'
|
||||||
import { statusCommand } from './status.js'
|
import { runStatusCommand } from './status.js'
|
||||||
import { stopCommand } from './stop.js'
|
import { runStopCommand } from './stop.js'
|
||||||
import { restartCommand } from './restart.js'
|
import { runRestartCommand } from './restart.js'
|
||||||
|
import { withOutput } from '../../output/index.js'
|
||||||
|
|
||||||
export function createDaemonCommand(): Command {
|
export function createDaemonCommand(): Command {
|
||||||
const daemon = new Command('daemon')
|
const daemon = new Command('daemon').description('Manage the Paseo daemon')
|
||||||
.description('Manage the Paseo daemon')
|
|
||||||
|
|
||||||
daemon.addCommand(startCommand())
|
daemon.addCommand(startCommand())
|
||||||
daemon.addCommand(statusCommand())
|
|
||||||
daemon.addCommand(stopCommand())
|
daemon
|
||||||
daemon.addCommand(restartCommand())
|
.command('status')
|
||||||
|
.description('Show daemon status')
|
||||||
|
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||||
|
.action(withOutput(runStatusCommand))
|
||||||
|
|
||||||
|
daemon
|
||||||
|
.command('stop')
|
||||||
|
.description('Stop the daemon')
|
||||||
|
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||||
|
.action(withOutput(runStopCommand))
|
||||||
|
|
||||||
|
daemon
|
||||||
|
.command('restart')
|
||||||
|
.description('Restart the daemon')
|
||||||
|
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||||
|
.action(withOutput(runRestartCommand))
|
||||||
|
|
||||||
return daemon
|
return daemon
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +1,86 @@
|
|||||||
import { Command } from 'commander'
|
import type { Command } from 'commander'
|
||||||
import chalk from 'chalk'
|
|
||||||
import { connectToDaemon, getDaemonHost } from '../../utils/client.js'
|
import { connectToDaemon, getDaemonHost } from '../../utils/client.js'
|
||||||
|
import type { CommandOptions, SingleResult, OutputSchema, CommandError } from '../../output/index.js'
|
||||||
|
|
||||||
export function restartCommand(): Command {
|
/** Result of restart command */
|
||||||
return new Command('restart')
|
interface RestartResult {
|
||||||
.description('Restart the daemon')
|
action: 'restarted' | 'not_running'
|
||||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
host: string
|
||||||
.action(async (options: { host?: string }) => {
|
message: string
|
||||||
await runRestart(options)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runRestart(options: { host?: string }): Promise<void> {
|
/** Schema for restart result */
|
||||||
const host = getDaemonHost(options)
|
const restartResultSchema: OutputSchema<RestartResult> = {
|
||||||
|
idField: 'action',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
header: 'STATUS',
|
||||||
|
field: 'action',
|
||||||
|
color: (value) => (value === 'restarted' ? 'green' : 'red'),
|
||||||
|
},
|
||||||
|
{ header: 'HOST', field: 'host' },
|
||||||
|
{ header: 'MESSAGE', field: 'message' },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RestartCommandResult = SingleResult<RestartResult>
|
||||||
|
|
||||||
|
export async function runRestartCommand(
|
||||||
|
options: CommandOptions,
|
||||||
|
_command: Command
|
||||||
|
): Promise<RestartCommandResult> {
|
||||||
|
const connectOptions = { host: options.host as string | undefined }
|
||||||
|
const host = getDaemonHost(connectOptions)
|
||||||
|
|
||||||
let client
|
let client
|
||||||
try {
|
try {
|
||||||
client = await connectToDaemon(options)
|
client = await connectToDaemon(connectOptions)
|
||||||
} catch {
|
} catch {
|
||||||
console.log(chalk.yellow('Daemon is not running'))
|
// Daemon not running - cannot restart
|
||||||
console.log(chalk.dim(`Tried to connect to ${host}`))
|
const error: CommandError = {
|
||||||
console.log()
|
code: 'DAEMON_NOT_RUNNING',
|
||||||
console.log(chalk.dim('Start the daemon with:'))
|
message: `Daemon is not running (tried to connect to ${host})`,
|
||||||
console.log(chalk.dim(' paseo daemon start'))
|
details: 'Start the daemon with: paseo daemon start',
|
||||||
process.exit(1)
|
}
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(chalk.dim('Restarting daemon...'))
|
|
||||||
|
|
||||||
// Request server restart
|
// Request server restart
|
||||||
await client.restartServer('cli_restart')
|
await client.restartServer('cli_restart')
|
||||||
|
|
||||||
console.log(chalk.green('Daemon restart requested'))
|
|
||||||
|
|
||||||
await client.close()
|
await client.close()
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'single',
|
||||||
|
data: {
|
||||||
|
action: 'restarted',
|
||||||
|
host,
|
||||||
|
message: 'Daemon restart requested',
|
||||||
|
},
|
||||||
|
schema: restartResultSchema,
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await client.close().catch(() => {})
|
await client.close().catch(() => {})
|
||||||
const message = err instanceof Error ? err.message : String(err)
|
const message = err instanceof Error ? err.message : String(err)
|
||||||
|
|
||||||
// If connection was closed, the daemon is restarting
|
// If connection was closed, the daemon is restarting
|
||||||
if (message.includes('closed') || message.includes('disconnected')) {
|
if (message.includes('closed') || message.includes('disconnected')) {
|
||||||
console.log(chalk.green('Daemon is restarting'))
|
return {
|
||||||
process.exit(0)
|
type: 'single',
|
||||||
|
data: {
|
||||||
|
action: 'restarted',
|
||||||
|
host,
|
||||||
|
message: 'Daemon is restarting',
|
||||||
|
},
|
||||||
|
schema: restartResultSchema,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error(chalk.red(`Failed to restart daemon: ${message}`))
|
const error: CommandError = {
|
||||||
process.exit(1)
|
code: 'RESTART_FAILED',
|
||||||
|
message: `Failed to restart daemon: ${message}`,
|
||||||
|
}
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,74 @@
|
|||||||
import { Command } from 'commander'
|
import type { Command } from 'commander'
|
||||||
import chalk from 'chalk'
|
|
||||||
import { resolvePaseoHome } from '@paseo/server'
|
import { resolvePaseoHome } from '@paseo/server'
|
||||||
import { tryConnectToDaemon, getDaemonHost } from '../../utils/client.js'
|
import { tryConnectToDaemon, getDaemonHost } from '../../utils/client.js'
|
||||||
|
import type { CommandOptions, ListResult, OutputSchema, CommandError } from '../../output/index.js'
|
||||||
|
|
||||||
export function statusCommand(): Command {
|
/** Status data for the daemon */
|
||||||
return new Command('status')
|
interface DaemonStatus {
|
||||||
.description('Show daemon status')
|
status: 'running' | 'stopped'
|
||||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
host: string
|
||||||
.action(async (options: { host?: string }) => {
|
home: string
|
||||||
await runStatus(options)
|
runningAgents: number
|
||||||
})
|
idleAgents: number
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runStatus(options: { host?: string }): Promise<void> {
|
/** Key-value row for table display */
|
||||||
const host = getDaemonHost(options)
|
interface StatusRow {
|
||||||
const client = await tryConnectToDaemon(options)
|
key: string
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Schema for key-value display with custom serialization for JSON/YAML */
|
||||||
|
function createStatusSchema(status: DaemonStatus): OutputSchema<StatusRow> {
|
||||||
|
return {
|
||||||
|
idField: 'key',
|
||||||
|
columns: [
|
||||||
|
{ header: 'KEY', field: 'key' },
|
||||||
|
{
|
||||||
|
header: 'VALUE',
|
||||||
|
field: 'value',
|
||||||
|
color: (_, item) => {
|
||||||
|
if (item.key === 'Status') {
|
||||||
|
return item.value === 'running' ? 'green' : 'red'
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// For JSON/YAML, return the structured status object (not key-value rows)
|
||||||
|
// The serializer receives each item, but we want the whole object
|
||||||
|
// So we return null for individual items and handle it at the result level
|
||||||
|
serialize: (_item) => status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert status to key-value rows for table display */
|
||||||
|
function toStatusRows(status: DaemonStatus): StatusRow[] {
|
||||||
|
return [
|
||||||
|
{ key: 'Status', value: status.status },
|
||||||
|
{ key: 'Host', value: status.host },
|
||||||
|
{ key: 'Home', value: status.home },
|
||||||
|
{ key: 'Agents', value: `${status.runningAgents} running, ${status.idleAgents} idle` },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type StatusResult = ListResult<StatusRow>
|
||||||
|
|
||||||
|
export async function runStatusCommand(
|
||||||
|
options: CommandOptions,
|
||||||
|
_command: Command
|
||||||
|
): Promise<StatusResult> {
|
||||||
|
const connectOptions = { host: options.host as string | undefined }
|
||||||
|
const host = getDaemonHost(connectOptions)
|
||||||
|
const client = await tryConnectToDaemon(connectOptions)
|
||||||
|
|
||||||
if (!client) {
|
if (!client) {
|
||||||
console.log(chalk.red('Status:'), 'not running')
|
const error: CommandError = {
|
||||||
console.log(chalk.dim(`Tried to connect to ${host}`))
|
code: 'DAEMON_NOT_RUNNING',
|
||||||
console.log()
|
message: `Daemon is not running (tried to connect to ${host})`,
|
||||||
console.log(chalk.dim('Start the daemon with:'))
|
details: 'Start the daemon with: paseo daemon start',
|
||||||
console.log(chalk.dim(' paseo daemon start'))
|
}
|
||||||
process.exit(1)
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -30,25 +76,37 @@ async function runStatus(options: { host?: string }): Promise<void> {
|
|||||||
client.requestSessionState()
|
client.requestSessionState()
|
||||||
|
|
||||||
// Wait a moment for the session state to be populated
|
// Wait a moment for the session state to be populated
|
||||||
await new Promise(resolve => setTimeout(resolve, 500))
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||||
|
|
||||||
const agents = client.listAgents()
|
const agents = client.listAgents()
|
||||||
const runningAgents = agents.filter(a => a.status === 'running')
|
const runningAgents = agents.filter((a) => a.status === 'running')
|
||||||
const idleAgents = agents.filter(a => a.status === 'idle')
|
const idleAgents = agents.filter((a) => a.status === 'idle')
|
||||||
|
|
||||||
// Get paseo home for display
|
// Get paseo home for display
|
||||||
const paseoHome = resolvePaseoHome()
|
const paseoHome = resolvePaseoHome()
|
||||||
|
|
||||||
console.log(chalk.green('Status:'), 'running')
|
const status: DaemonStatus = {
|
||||||
console.log(chalk.dim('Host:'), host)
|
status: 'running',
|
||||||
console.log(chalk.dim('Home:'), paseoHome)
|
host,
|
||||||
console.log(chalk.dim('Agents:'), `${runningAgents.length} running, ${idleAgents.length} idle`)
|
home: paseoHome,
|
||||||
|
runningAgents: runningAgents.length,
|
||||||
|
idleAgents: idleAgents.length,
|
||||||
|
}
|
||||||
|
|
||||||
await client.close()
|
await client.close()
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'list',
|
||||||
|
data: toStatusRows(status),
|
||||||
|
schema: createStatusSchema(status),
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await client.close().catch(() => {})
|
await client.close().catch(() => {})
|
||||||
const message = err instanceof Error ? err.message : String(err)
|
const message = err instanceof Error ? err.message : String(err)
|
||||||
console.error(chalk.red(`Failed to get status: ${message}`))
|
const error: CommandError = {
|
||||||
process.exit(1)
|
code: 'STATUS_FAILED',
|
||||||
|
message: `Failed to get status: ${message}`,
|
||||||
|
}
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,93 @@
|
|||||||
import { Command } from 'commander'
|
import type { Command } from 'commander'
|
||||||
import chalk from 'chalk'
|
|
||||||
import { connectToDaemon, getDaemonHost } from '../../utils/client.js'
|
import { connectToDaemon, getDaemonHost } from '../../utils/client.js'
|
||||||
|
import type { CommandOptions, SingleResult, OutputSchema, CommandError } from '../../output/index.js'
|
||||||
|
|
||||||
export function stopCommand(): Command {
|
/** Result of stop command */
|
||||||
return new Command('stop')
|
interface StopResult {
|
||||||
.description('Stop the daemon')
|
action: 'stopped' | 'not_running'
|
||||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
host: string
|
||||||
.action(async (options: { host?: string }) => {
|
message: string
|
||||||
await runStop(options)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runStop(options: { host?: string }): Promise<void> {
|
/** Schema for stop result */
|
||||||
const host = getDaemonHost(options)
|
const stopResultSchema: OutputSchema<StopResult> = {
|
||||||
|
idField: 'action',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
header: 'STATUS',
|
||||||
|
field: 'action',
|
||||||
|
color: (value) => (value === 'stopped' ? 'green' : 'yellow'),
|
||||||
|
},
|
||||||
|
{ header: 'HOST', field: 'host' },
|
||||||
|
{ header: 'MESSAGE', field: 'message' },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export type StopCommandResult = SingleResult<StopResult>
|
||||||
|
|
||||||
|
export async function runStopCommand(
|
||||||
|
options: CommandOptions,
|
||||||
|
_command: Command
|
||||||
|
): Promise<StopCommandResult> {
|
||||||
|
const connectOptions = { host: options.host as string | undefined }
|
||||||
|
const host = getDaemonHost(connectOptions)
|
||||||
|
|
||||||
let client
|
let client
|
||||||
try {
|
try {
|
||||||
client = await connectToDaemon(options)
|
client = await connectToDaemon(connectOptions)
|
||||||
} catch {
|
} catch {
|
||||||
console.log(chalk.yellow('Daemon is not running'))
|
// Daemon not running - this is a valid outcome
|
||||||
console.log(chalk.dim(`Tried to connect to ${host}`))
|
return {
|
||||||
process.exit(0)
|
type: 'single',
|
||||||
|
data: {
|
||||||
|
action: 'not_running',
|
||||||
|
host,
|
||||||
|
message: 'Daemon was not running',
|
||||||
|
},
|
||||||
|
schema: stopResultSchema,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(chalk.dim('Stopping daemon...'))
|
|
||||||
|
|
||||||
// Request server restart with "shutdown" reason
|
// Request server restart with "shutdown" reason
|
||||||
// This signals the daemon to shut down gracefully
|
// This signals the daemon to shut down gracefully
|
||||||
await client.restartServer('cli_shutdown')
|
await client.restartServer('cli_shutdown')
|
||||||
|
|
||||||
// Give the daemon a moment to acknowledge
|
// Give the daemon a moment to acknowledge
|
||||||
await new Promise(resolve => setTimeout(resolve, 500))
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||||
|
|
||||||
console.log(chalk.green('Daemon stop requested'))
|
|
||||||
console.log(chalk.dim('The daemon will shut down gracefully'))
|
|
||||||
|
|
||||||
await client.close()
|
await client.close()
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'single',
|
||||||
|
data: {
|
||||||
|
action: 'stopped',
|
||||||
|
host,
|
||||||
|
message: 'Daemon stop requested - shutting down gracefully',
|
||||||
|
},
|
||||||
|
schema: stopResultSchema,
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await client.close().catch(() => {})
|
await client.close().catch(() => {})
|
||||||
const message = err instanceof Error ? err.message : String(err)
|
const message = err instanceof Error ? err.message : String(err)
|
||||||
|
|
||||||
// If connection was closed, the daemon is stopping
|
// If connection was closed, the daemon is stopping
|
||||||
if (message.includes('closed') || message.includes('disconnected')) {
|
if (message.includes('closed') || message.includes('disconnected')) {
|
||||||
console.log(chalk.green('Daemon is stopping'))
|
return {
|
||||||
process.exit(0)
|
type: 'single',
|
||||||
|
data: {
|
||||||
|
action: 'stopped',
|
||||||
|
host,
|
||||||
|
message: 'Daemon is stopping',
|
||||||
|
},
|
||||||
|
schema: stopResultSchema,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error(chalk.red(`Failed to stop daemon: ${message}`))
|
const error: CommandError = {
|
||||||
process.exit(1)
|
code: 'STOP_FAILED',
|
||||||
|
message: `Failed to stop daemon: ${message}`,
|
||||||
|
}
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,17 @@ export function renderJson<T>(
|
|||||||
// Apply custom serializer if provided
|
// Apply custom serializer if provided
|
||||||
if (schema.serialize) {
|
if (schema.serialize) {
|
||||||
if (result.type === 'list') {
|
if (result.type === 'list') {
|
||||||
|
// If all items serialize to the same object, return just one
|
||||||
|
// This handles the case where a list of key-value rows should serialize
|
||||||
|
// to a single structured object
|
||||||
const serialized = result.data.map((item) => schema.serialize!(item))
|
const serialized = result.data.map((item) => schema.serialize!(item))
|
||||||
|
if (serialized.length > 0) {
|
||||||
|
const first = JSON.stringify(serialized[0])
|
||||||
|
const allSame = serialized.every((s) => JSON.stringify(s) === first)
|
||||||
|
if (allSame) {
|
||||||
|
return JSON.stringify(serialized[0], null, 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
return JSON.stringify(serialized, null, 2)
|
return JSON.stringify(serialized, null, 2)
|
||||||
} else {
|
} else {
|
||||||
const serialized = schema.serialize(result.data)
|
const serialized = schema.serialize(result.data)
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ function renderRow<T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return padCell(cell, width, col.align ?? 'left')
|
return padCell(cell, width ?? 0, col.align ?? 'left')
|
||||||
})
|
})
|
||||||
.join(' ')
|
.join(' ')
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ function renderHeader<T>(
|
|||||||
options: OutputOptions
|
options: OutputOptions
|
||||||
): string {
|
): string {
|
||||||
const headerRow = columns
|
const headerRow = columns
|
||||||
.map((col, i) => padCell(col.header, widths[i], col.align ?? 'left'))
|
.map((col, i) => padCell(col.header, widths[i] ?? 0, col.align ?? 'left'))
|
||||||
.join(' ')
|
.join(' ')
|
||||||
|
|
||||||
return options.noColor ? headerRow : chalk.bold(headerRow)
|
return options.noColor ? headerRow : chalk.bold(headerRow)
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ export function withOutput<T, Args extends unknown[]>(
|
|||||||
): (...args: [...Args, CommandOptions, Command]) => Promise<void> {
|
): (...args: [...Args, CommandOptions, Command]) => Promise<void> {
|
||||||
return async (...args) => {
|
return async (...args) => {
|
||||||
// Last two args are options and command
|
// Last two args are options and command
|
||||||
const options = args[args.length - 2] as CommandOptions
|
const command = args[args.length - 1] as Command
|
||||||
|
// Use optsWithGlobals() to get both local and global options
|
||||||
|
const options = command.optsWithGlobals() as CommandOptions
|
||||||
const outputOptions = extractOutputOptions(options)
|
const outputOptions = extractOutputOptions(options)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -17,7 +17,17 @@ export function renderYaml<T>(
|
|||||||
// Apply custom serializer if provided
|
// Apply custom serializer if provided
|
||||||
if (schema.serialize) {
|
if (schema.serialize) {
|
||||||
if (result.type === 'list') {
|
if (result.type === 'list') {
|
||||||
|
// If all items serialize to the same object, return just one
|
||||||
|
// This handles the case where a list of key-value rows should serialize
|
||||||
|
// to a single structured object
|
||||||
const serialized = result.data.map((item) => schema.serialize!(item))
|
const serialized = result.data.map((item) => schema.serialize!(item))
|
||||||
|
if (serialized.length > 0) {
|
||||||
|
const first = JSON.stringify(serialized[0])
|
||||||
|
const allSame = serialized.every((s) => JSON.stringify(s) === first)
|
||||||
|
if (allSame) {
|
||||||
|
return YAML.stringify(serialized[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
return YAML.stringify(serialized)
|
return YAML.stringify(serialized)
|
||||||
} else {
|
} else {
|
||||||
const serialized = schema.serialize(result.data)
|
const serialized = schema.serialize(result.data)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* Test runner for Paseo CLI E2E tests
|
* Test runner for Paseo CLI E2E tests
|
||||||
*
|
*
|
||||||
* Runs all test phases in sequence and reports results.
|
* Runs all test phases in sequence and reports results.
|
||||||
* Each test is a separate .mts file that can also be run independently.
|
* Each test is a separate .ts file that can also be run independently.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { $ } from 'zx'
|
import { $ } from 'zx'
|
||||||
@@ -22,7 +22,7 @@ console.log('='.repeat(50))
|
|||||||
// Discover all test files
|
// Discover all test files
|
||||||
const files = await readdir(__dirname)
|
const files = await readdir(__dirname)
|
||||||
const testFiles = files
|
const testFiles = files
|
||||||
.filter(f => f.match(/^\d{2}-.*\.test\.mts$/))
|
.filter(f => f.match(/^\d{2}-.*\.test\.ts$/))
|
||||||
.sort()
|
.sort()
|
||||||
|
|
||||||
if (testFiles.length === 0) {
|
if (testFiles.length === 0) {
|
||||||
@@ -42,14 +42,14 @@ const failures: { test: string; error: string }[] = []
|
|||||||
|
|
||||||
for (const testFile of testFiles) {
|
for (const testFile of testFiles) {
|
||||||
const testPath = join(__dirname, testFile)
|
const testPath = join(__dirname, testFile)
|
||||||
const testName = testFile.replace(/\.test\.mts$/, '')
|
const testName = testFile.replace(/\.test\.ts$/, '')
|
||||||
|
|
||||||
console.log(`\n${'─'.repeat(50)}`)
|
console.log(`\n${'─'.repeat(50)}`)
|
||||||
console.log(`📋 Running ${testName}...`)
|
console.log(`📋 Running ${testName}...`)
|
||||||
console.log('─'.repeat(50))
|
console.log('─'.repeat(50))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await $`npx zx ${testPath}`.nothrow()
|
const result = await $`npx tsx ${testPath}`.nothrow()
|
||||||
if (result.exitCode === 0) {
|
if (result.exitCode === 0) {
|
||||||
console.log(`\n✅ ${testName} PASSED`)
|
console.log(`\n✅ ${testName} PASSED`)
|
||||||
passed++
|
passed++
|
||||||
Reference in New Issue
Block a user