name: tests

on:
  push:
    branches: [ "**" ]
  pull_request:
    branches: [ "**" ]

jobs:
  test:
    name: tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - name: Install dependencies (lockfile)
        if: ${{ hashFiles('package-lock.json') != '' }}
        run: npm ci

      - name: Install dependencies
        if: ${{ hashFiles('package-lock.json') == '' }}
        run: npm install

      - name: Run tests with coverage
        run: npx jest --runInBand --coverage --coverageReporters=text-summary --coverageReporters=lcov --coverageReporters=json-summary

      - name: Upload coverage artifact
        if: always() && hashFiles('coverage/coverage-summary.json') != ''
        uses: actions/upload-artifact@v4
        with:
          name: coverage
          path: coverage/**

      - name: Add coverage summary to job summary
        if: always() && hashFiles('coverage/coverage-summary.json') != ''
        shell: bash
        run: |
          node <<'NODE'
          const fs = require('fs');
          const p = 'coverage/coverage-summary.json';
          const out = process.env.GITHUB_STEP_SUMMARY;
          if (!out) {
            console.log('GITHUB_STEP_SUMMARY not set; skipping');
            process.exit(0);
          }
          const s = JSON.parse(fs.readFileSync(p, 'utf8'));
          const c = s.total;
          const lines = [
            '## Coverage summary',
            '',
            `- Statements: ${c.statements.pct}% (${c.statements.covered}/${c.statements.total})`,
            `- Branches: ${c.branches.pct}% (${c.branches.covered}/${c.branches.total})`,
            `- Functions: ${c.functions.pct}% (${c.functions.covered}/${c.functions.total})`,
            `- Lines: ${c.lines.pct}% (${c.lines.covered}/${c.lines.total})`,
            '',
          ];
          fs.appendFileSync(out, lines.join('\n'));
          NODE
