All files / packages/design-system-2-site/src/lib/zeroheight report.js

91.66% Statements 33/36
59.09% Branches 13/22
84.61% Functions 11/13
92.3% Lines 24/26

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 75 76 77 78 79 80 81            2x                         3x 3x 3x 3x 3x               4x 4x 1x 1x                   24x             1x 24x 8x 2x 2x     1x               1x 1x 1x       1x     1x 1x   1x    
/**
 * Render audit findings as a markdown report.
 */
 
/** @typedef {import('./audit.js').Finding} Finding */
 
const SECTIONS = [
  ['new', 'New in Zeroheight (not ported)'],
  ['changed', 'Changed in Zeroheight since last sync'],
  ['locally-edited', 'Edited locally since last sync'],
  ['likely-changed', 'Likely changed since the port (first run, low similarity)'],
  ['empty-export', 'Empty locally, has content in Zeroheight'],
  ['unmatched', 'No local file mapped'],
  ['missing-local', 'Mapped local file is missing'],
  ['deleted', 'Gone from Zeroheight'],
];
 
/** @param {Finding} f */
function label(f) {
  const where = [f.category, f.name].filter(Boolean).join(' / ');
  const tab = f.tab ? ` > ${f.tab}` : '';
  const file = f.localFile ? ` - \`${f.localFile}\`` : '';
  const score = f.similarity !== undefined ? ` (similarity ${f.similarity.toFixed(2)})` : '';
  return `- ${where}${tab}${file}${score} \`${f.uid}\``;
}
 
/**
 * @param {{ findings: Finding[], orphans: string[], releaseId: number | null,
 *           pageCount: { visible: number, hidden: number }, threshold: number }} opts
 */
export function renderReport({ findings, orphans, releaseId, pageCount, threshold }) {
  const visible = findings.filter((f) => !f.hidden);
  const hidden = findings.filter((f) => f.hidden);
  const hiddenOnSite = hidden.filter((f) => f.localFile);
  const lines = [
    '# Zeroheight drift audit',
    '',
    `- Release: ${releaseId ?? 'unknown'}`,
    `- Pages: ${pageCount.visible} visible, ${pageCount.hidden} hidden`,
    `- Similarity threshold: ${threshold}`,
    '',
    '| Status | Count |',
    '| --- | --- |',
    ...SECTIONS.map(
      ([key, title]) => `| ${title} | ${visible.filter((f) => f.status.includes(key)).length} |`,
    ),
    `| Hidden in Zeroheight but on the site | ${hiddenOnSite.length} |`,
    `| Hidden in Zeroheight | ${hidden.length} |`,
    `| Local files with no Zeroheight page | ${orphans.length} |`,
  ];
 
  for (const [key, title] of SECTIONS) {
    const rows = visible.filter((f) => f.status.includes(key));
    if (!rows.length) continue;
    if (key === 'likely-changed') rows.sort((a, b) => (a.similarity ?? 0) - (b.similarity ?? 0));
    lines.push('', `## ${title}`, '', ...rows.map(label));
  }
 
  Iif (hiddenOnSite.length) {
    lines.push(
      '',
      '## Hidden in Zeroheight but on the site',
      '',
      ...hiddenOnSite.map((f) => `${label(f)} - ${f.decision}`),
    );
  }
  const hiddenElsewhere = hidden.filter((f) => !f.localFile);
  Eif (hiddenElsewhere.length) {
    lines.push(
      '',
      '## Hidden in Zeroheight',
      '',
      ...hiddenElsewhere.map((f) => `${label(f)} - ${f.decision}`),
    );
  }
  Eif (orphans.length) {
    lines.push('', '## Local files with no Zeroheight page', '', ...orphans.map((f) => `- \`${f}\``));
  }
  return `${lines.join('\n')}\n`;
}