All files / src ci-summary.ts

100% Statements 20/20
93.33% Branches 14/15
100% Functions 4/4
100% Lines 20/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74      31x                       65x                   66x   66x     66x 4x       61x           119x 67x   78x               78x 66x   66x 66x   5x       4x 1x 5x       61x     73x    
import { readFile, readdir } from "node:fs/promises";
import { join } from "node:path";
 
const allureStatuses = ["passed", "failed", "broken", "skipped"] as const;
type AllureStatus = (typeof allureStatuses)[number];
 
interface AllureStatusResult {
  readonly status: AllureStatus;
}
 
export interface AllureCounts extends Record<AllureStatus, number> {
  readonly tests: number;
}
 
function isAllureStatus(status: unknown): status is AllureStatus {
  return (
    typeof status === "string" &&
    (allureStatuses as readonly string[]).includes(status)
  );
}
 
function parseAllureStatusResult(
  text: string,
  path: string,
): AllureStatusResult {
  const value: unknown = JSON.parse(text);
  const status =
    typeof value === "object" && value !== null && "status" in value
      ? value.status
      : undefined;
  if (!isAllureStatus(status)) {
    throw new Error(
      `Allure test result ${path} has unsupported status ${JSON.stringify(status)}`,
    );
  }
  return { status };
}
 
export async function readAllureCounts(
  directory: string,
): Promise<AllureCounts> {
  const files = (await readdir(directory))
    .filter((file) => file.endsWith("-result.json"))
    .sort();
  const counts: AllureCounts = {
    tests: files.length,
    passed: 0,
    failed: 0,
    broken: 0,
    skipped: 0,
  };
 
  for (const file of files) {
    const path = join(directory, file);
    let result: AllureStatusResult;
    try {
      result = parseAllureStatusResult(await readFile(path, "utf8"), path);
    } catch (cause) {
      if (
        cause instanceof Error &&
        cause.message.startsWith("Allure test result")
      )
        throw cause;
      const detail = cause instanceof Error ? cause.message : String(cause);
      throw new Error(`Cannot read Allure test result ${path}: ${detail}`, {
        cause,
      });
    }
    counts[result.status] += 1;
  }
 
  return counts;
}