report.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import { Duration } from "effect"
  2. import { indent, pad } from "./assertions"
  3. import type { Options, Result, Scenario } from "./types"
  4. export const color = {
  5. dim: "\x1b[2m",
  6. green: "\x1b[32m",
  7. red: "\x1b[31m",
  8. yellow: "\x1b[33m",
  9. cyan: "\x1b[36m",
  10. reset: "\x1b[0m",
  11. }
  12. export function printHeader(
  13. options: Options,
  14. effectRoutes: string[],
  15. selected: Scenario[],
  16. missing: string[],
  17. extra: Scenario[],
  18. paths: { database: string; global: string },
  19. ) {
  20. console.log(`${color.cyan}HttpApi exerciser${color.reset}`)
  21. console.log(`${color.dim}db=${paths.database}${color.reset}`)
  22. console.log(`${color.dim}global=${paths.global}${color.reset}`)
  23. console.log(
  24. `${color.dim}mode=${options.mode} selected=${selected.length} scenarioTimeout=${Duration.format(options.scenarioTimeout)} effectRoutes=${effectRoutes.length} missing=${missing.length} extra=${extra.length}${color.reset}`,
  25. )
  26. console.log("")
  27. }
  28. export function printResults(results: Result[], missing: string[], extra: Scenario[]) {
  29. for (const result of results) {
  30. if (result.status === "pass") {
  31. console.log(
  32. `${color.green}PASS${color.reset} ${pad(result.scenario.method, 6)} ${pad(result.scenario.path, 48)} ${result.scenario.name}`,
  33. )
  34. continue
  35. }
  36. if (result.status === "skip") {
  37. console.log(
  38. `${color.yellow}SKIP${color.reset} ${pad(result.scenario.method, 6)} ${pad(result.scenario.path, 48)} ${result.scenario.name} ${color.dim}${result.scenario.reason}${color.reset}`,
  39. )
  40. continue
  41. }
  42. console.log(
  43. `${color.red}FAIL${color.reset} ${pad(result.scenario.method, 6)} ${pad(result.scenario.path, 48)} ${result.scenario.name}`,
  44. )
  45. console.log(`${color.red}${indent(result.message)}${color.reset}`)
  46. }
  47. if (missing.length > 0) {
  48. console.log("\nMissing scenarios")
  49. for (const route of missing) console.log(`${color.red}MISS${color.reset} ${route}`)
  50. }
  51. if (extra.length > 0) {
  52. console.log("\nExtra scenarios")
  53. for (const scenario of extra)
  54. console.log(`${color.yellow}EXTRA${color.reset} ${routeKey(scenario)} ${scenario.name}`)
  55. }
  56. console.log(
  57. `\n${color.dim}summary pass=${results.filter((result) => result.status === "pass").length} fail=${results.filter((result) => result.status === "fail").length} skip=${results.filter((result) => result.status === "skip").length} missing=${missing.length} extra=${extra.length}${color.reset}`,
  58. )
  59. }
  60. function routeKey(scenario: Scenario) {
  61. return `${scenario.method} ${scenario.path}`
  62. }