fix(test): cover new reporters
This commit is contained in:
parent
b2122d5780
commit
09f83ee5ab
|
@ -3,16 +3,20 @@ import { setOrPush } from '@apextoaster/js-utils';
|
|||
import { Rule, RuleError, RuleResult } from '../rule/index.js';
|
||||
import { Reporter } from './index.js';
|
||||
|
||||
export const ERROR_EMPTY_RESULT = 'no errors to report';
|
||||
|
||||
export class SummaryReporter implements Reporter {
|
||||
public async report(results: Array<RuleResult>): Promise<string> {
|
||||
const ruleErrors = new Map<Rule, Array<RuleError>>();
|
||||
|
||||
for (const err of results.flatMap((r) => r.errors)) {
|
||||
setOrPush(ruleErrors, err.rule, err);
|
||||
for (const result of results) {
|
||||
for (const err of result.errors) {
|
||||
setOrPush(ruleErrors, err.rule, err);
|
||||
}
|
||||
}
|
||||
|
||||
if (ruleErrors.size === 0) {
|
||||
return 'no errors to report';
|
||||
return ERROR_EMPTY_RESULT;
|
||||
}
|
||||
|
||||
const summary = ['rule errors'];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { getOrDefault, leftPad, mustExist, mustGet, setOrPush } from '@apextoaster/js-utils';
|
||||
import { getOrDefault, leftPad, mustGet, setOrPush } from '@apextoaster/js-utils';
|
||||
|
||||
import { Rule, RuleResult } from '../rule/index.js';
|
||||
import { Reporter } from './index.js';
|
||||
|
@ -15,6 +15,8 @@ interface RuleCounts {
|
|||
rule: string;
|
||||
}
|
||||
|
||||
export const ERROR_EMPTY_RESULT = 'no results to format';
|
||||
|
||||
export class TableReporter implements Reporter {
|
||||
public async report(results: ReadonlyArray<RuleResult>): Promise<string> {
|
||||
const rules = new Map<Rule, RuleCounts>();
|
||||
|
@ -30,6 +32,11 @@ export class TableReporter implements Reporter {
|
|||
}
|
||||
|
||||
const rows = Array.from(rules.values());
|
||||
|
||||
if (rows.length === 0) {
|
||||
return ERROR_EMPTY_RESULT;
|
||||
}
|
||||
|
||||
return printTable(rows, ['rule', 'errors', 'changes'], {
|
||||
delimiter: {
|
||||
column: COL_DELIMITER,
|
||||
|
|
|
@ -7,7 +7,7 @@ export class YamlReporter implements Reporter {
|
|||
const parser = new YamlParser();
|
||||
const data = {
|
||||
changes: results.flatMap((r) => r.changes).map((c) => c.rule.name),
|
||||
errors: results.flatMap((r) => r.errors).map((c) => c.rule.name),
|
||||
errors: results.flatMap((r) => r.errors).map((e) => e.rule.name),
|
||||
};
|
||||
return parser.dump({
|
||||
data,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { LogLevel, NullLogger } from 'noicejs';
|
||||
|
||||
import { RuleChange, RuleError } from '../src/rule/index.js';
|
||||
import { SchemaRule } from '../src/rule/SchemaRule.js';
|
||||
import { Document, Element } from '../src/source.js';
|
||||
import { VisitorContext } from '../src/visitor/VisitorContext.js';
|
||||
|
@ -36,3 +37,22 @@ export function makeElement(data: unknown): Element {
|
|||
index: 0,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeResults(names: Array<string>, changes: Array<RuleChange> = [], errors: Array<RuleError> = []) {
|
||||
const rules = names.map((name) => new SchemaRule({
|
||||
check: {},
|
||||
desc: name,
|
||||
level: LogLevel.Info,
|
||||
name,
|
||||
select: '',
|
||||
tags: [],
|
||||
}));
|
||||
|
||||
const results = rules.map((rule) => ({
|
||||
changes,
|
||||
errors,
|
||||
rule,
|
||||
}));
|
||||
|
||||
return { rules, results };
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import { expect } from 'chai';
|
||||
import { LogLevel } from 'noicejs';
|
||||
|
||||
import { ERROR_EMPTY_RESULT, SummaryReporter } from '../../src/reporter/SummaryReporter.js';
|
||||
import { RuleResult } from '../../src/rule/index.js';
|
||||
import { makeElement, makeResults } from '../helpers.js';
|
||||
|
||||
describe('summary reporter', () => {
|
||||
it('should handle empty results', async () => {
|
||||
const reporter = new SummaryReporter();
|
||||
const report = await reporter.report([]);
|
||||
expect(report).to.equal(ERROR_EMPTY_RESULT);
|
||||
});
|
||||
|
||||
it('should count results by type', async () => {
|
||||
const ruleNames = ['test', 'foo', 'bar'];
|
||||
const { rules } = makeResults(ruleNames);
|
||||
const results: Array<RuleResult> = rules.map((rule) => ({
|
||||
changes: [],
|
||||
errors: [{
|
||||
data: makeElement({}),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
err: {} as any,
|
||||
level: LogLevel.Debug,
|
||||
msg: '',
|
||||
rule,
|
||||
}],
|
||||
rule,
|
||||
}));
|
||||
|
||||
const reporter = new SummaryReporter();
|
||||
const report = await reporter.report(results);
|
||||
|
||||
for (const name of ruleNames) {
|
||||
expect(report).to.include(`${name}: 1`); // wrap with margin to avoid partial words
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
import { expect } from 'chai';
|
||||
|
||||
import { ERROR_EMPTY_RESULT, TableReporter } from '../../src/reporter/TableReporter.js';
|
||||
import { makeResults } from '../helpers.js';
|
||||
|
||||
describe('table reporter', () => {
|
||||
it('should handle empty results', async () => {
|
||||
const reporter = new TableReporter();
|
||||
const report = await reporter.report([]);
|
||||
expect(report).to.equal(ERROR_EMPTY_RESULT);
|
||||
});
|
||||
|
||||
it('should group results by rule', async () => {
|
||||
const ruleNames = ['test', 'foo', 'bar'];
|
||||
const { results } = makeResults(ruleNames);
|
||||
|
||||
const reporter = new TableReporter();
|
||||
const report = await reporter.report(results);
|
||||
|
||||
for (const name of ruleNames) {
|
||||
expect(report).to.include(` ${name} `); // wrap with margin to avoid partial words
|
||||
}
|
||||
});
|
||||
|
||||
it('should print results in a table', async () => {
|
||||
const ruleNames = ['test', 'foo', 'bar'];
|
||||
const { results } = makeResults(ruleNames);
|
||||
|
||||
const reporter = new TableReporter();
|
||||
const report = await reporter.report(results);
|
||||
|
||||
for (const line of report.split('\n')) {
|
||||
expect(line).to.match(/^|/);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('print table helper', () => {
|
||||
it('should include column names in the first row');
|
||||
it('should have a second row with delimiters');
|
||||
it('should show data starting from the third row');
|
||||
it('should pad and right-align short fields');
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { expect } from 'chai';
|
||||
import { LogLevel } from 'noicejs';
|
||||
|
||||
import { YamlReporter } from '../../src/reporter/YamlReporter.js';
|
||||
import { RuleResult } from '../../src/rule/index.js';
|
||||
import { makeElement, makeResults } from '../helpers.js';
|
||||
|
||||
describe('yaml reporter', () => {
|
||||
it('should handle empty results', async () => {
|
||||
const reporter = new YamlReporter();
|
||||
const report = await reporter.report([]);
|
||||
expect(report).to.equal('changes: []\nerrors: []\n');
|
||||
});
|
||||
|
||||
it('should collect results by type', async () => {
|
||||
const ruleNames = ['test', 'foo', 'bar'];
|
||||
const { rules } = makeResults(ruleNames, [], [{
|
||||
data: makeElement({}),
|
||||
err: {} as any,
|
||||
level: LogLevel.Debug,
|
||||
msg: '',
|
||||
rule: {
|
||||
name: 'test',
|
||||
} as any,
|
||||
}]);
|
||||
const results: Array<RuleResult> = rules.map((rule) => ({
|
||||
changes: [],
|
||||
errors: [{
|
||||
data: makeElement({}),
|
||||
err: {} as any,
|
||||
level: LogLevel.Debug,
|
||||
msg: '',
|
||||
rule,
|
||||
}],
|
||||
rule,
|
||||
}));
|
||||
|
||||
const reporter = new YamlReporter();
|
||||
const report = await reporter.report(results);
|
||||
|
||||
for (const name of ruleNames) {
|
||||
expect(report).to.include(`- ${name}\n`); // wrap with margin to avoid partial words
|
||||
}
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue