import { describe, expect, it } from 'vitest'; import { groupConvertible, rankBlockers } from './report.ts'; import type { Result } from './scan.ts'; describe('rankBlockers', () => { it('counts distinct repos, not occurrences', () => { const results: Result[] = []; for (let i = 0; i < 50; i++) { results.push({ owner: 'a.org', repo: 'a.org/mono', file: `.github/workflows/${i}.yml`, error: 'A', }); } for (let i = 0; i < 10; i++) { results.push({ owner: `b${i}.org`, repo: `b${i}.org/repo`, file: '.github/workflows/ci.yml', error: 'B', }); } expect(rankBlockers(results)).toEqual([ { error: 'B', repos: 10, owners: 10, files: 10 }, { error: 'A', repos: 1, owners: 1, files: 50 }, ]); }); it('breaks a repo tie on distinct owners', () => { const results: Result[] = [ { owner: 'a.org', repo: 'a.org/one', file: 'x.yml', error: 'one owner', }, { owner: 'a.org', repo: 'a.org/two', file: 'x.yml', error: 'one owner', }, { owner: 'a.org', repo: 'a.org/three', file: 'x.yml', error: 'one owner', }, { owner: 'a.org', repo: 'a.org/one', file: 'y.yml', error: 'three owners', }, { owner: 'b.org', repo: 'b.org/one', file: 'y.yml', error: 'three owners', }, { owner: 'c.org', repo: 'c.org/one', file: 'y.yml', error: 'three owners', }, ]; expect(rankBlockers(results).map((b) => b.error)).toEqual([ 'three owners', 'one owner', ]); }); it('groups by the error with details stripped', () => { const results: Result[] = [ { owner: 'a.org', repo: 'a.org/one', file: 'x.yml', error: 'Unsupported key "strategy" in job "test"', }, { owner: 'b.org', repo: 'b.org/one', file: 'x.yml', error: 'Unsupported key "strategy" in job "lint"', }, { owner: 'b.org', repo: 'b.org/one', file: 'y.yml', error: 'Unsupported key "strategy" in job "test"', }, ]; expect(rankBlockers(results)).toEqual([ { error: 'Unsupported key "strategy" in job', repos: 2, owners: 2, files: 3, }, ]); }); it('ignores converted files', () => { const results: Result[] = [ { owner: 'a.org', repo: 'a.org/one', file: 'x.yml', error: null, }, ]; expect(rankBlockers(results)).toEqual([]); }); }); describe('groupConvertible', () => { it('lists converting files per repo with the repo total', () => { const results: Result[] = [ { owner: 'a.org', repo: 'a.org/partial', file: 'ci.yml', error: null, }, { owner: 'a.org', repo: 'a.org/partial', file: 'release.yml', error: 'A', }, { owner: 'a.org', repo: 'a.org/partial', file: 'lint.yml', error: null, }, ]; expect(groupConvertible(results)).toEqual([ { repo: 'a.org/partial', converting: ['ci.yml', 'lint.yml'], workflows: 3, }, ]); }); it('sorts by workflow count, then by name', () => { const results: Result[] = [ { owner: 'a.org', repo: 'a.org/two', file: 'ci.yml', error: null, }, { owner: 'a.org', repo: 'a.org/two', file: 'lint.yml', error: null, }, { owner: 'a.org', repo: 'a.org/one-b', file: 'ci.yml', error: null, }, { owner: 'a.org', repo: 'a.org/one-a', file: 'ci.yml', error: null, }, ]; expect(groupConvertible(results).map((c) => c.repo)).toEqual([ 'a.org/two', 'a.org/one-a', 'a.org/one-b', ]); }); it('leaves out repos without a converting file', () => { const results: Result[] = [ { owner: 'a.org', repo: 'a.org/one', file: 'x.yml', error: 'A', }, ]; expect(groupConvertible(results)).toEqual([]); }); });