From 10a756fcb093b58585ca367479d1383fd6369aa8 Mon Sep 17 00:00:00 2001 From: AriPerkkio Date: Wed, 22 Mar 2023 10:50:21 +0200 Subject: [PATCH] feat: option to silence logging --- README.md | 15 +++++++++++++ src/sonar-reporter.ts | 9 +++++++- test/index.test.ts | 47 ++++++++++++++++++++++++++++++---------- test/utils.ts | 3 ++- test/vite.test-config.ts | 5 +++++ 5 files changed, 66 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3aa313e..2846a35 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,21 @@ sonar.testExecutionReportPaths=sonar-report.xml - ❌ Do not `import` reporter as `import SonarReporter from 'vitest-sonar-reporter';` - ✅ Define reporter as `reporters: ['vitest-sonar-reporter']` so that `vitest` will process it. This quarantees support for projects without `{ type: 'module' }`. +### Options + +You can pass additional options using `test.sonarReporterOptions` in `vite.config.ts`. Note that passing custom options to Vitest reporters is unconventional and may require you to use `@ts-ignore` when using TypeScript. + +#### `silent` + +Silence reporter's verbose logging. + +```ts +test: { + reporters: 'vitest-sonar-reporter', + sonarReporterOptions: { silent: true } +} +``` + ## Code Coverage This reporter does not process code coverage - Vitest already supports that out-of-the-box! diff --git a/src/sonar-reporter.ts b/src/sonar-reporter.ts index b0c4886..1b00123 100644 --- a/src/sonar-reporter.ts +++ b/src/sonar-reporter.ts @@ -10,10 +10,14 @@ import { generateXml } from './xml.js'; export default class SonarReporter implements Reporter { ctx!: Vitest; outputFile!: string; + silent!: boolean; onInit(ctx: Vitest) { this.ctx = ctx; + // @ts-expect-error -- untyped + this.silent = ctx.config.sonarReporterOptions?.silent === true; + if (!this.ctx.config.outputFile) { throw new Error( 'SonarReporter requires config.outputFile to be defined in vite config' @@ -38,7 +42,10 @@ export default class SonarReporter implements Reporter { const sorted = files?.sort(sortByFilename); writeFileSync(reportFile, generateXml(sorted), 'utf-8'); - this.ctx.logger.log(`SonarQube report written to ${reportFile}`); + + if (!this.silent) { + this.ctx.logger.log(`SonarQube report written to ${reportFile}`); + } } } diff --git a/test/index.test.ts b/test/index.test.ts index e022091..715a5b2 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,4 +1,4 @@ -import { execSync } from 'child_process'; +import { exec } from 'child_process'; import { existsSync, readFileSync, rmSync } from 'fs'; import { beforeEach, expect, test } from 'vitest'; import { stabilizeReport } from './utils'; @@ -7,18 +7,10 @@ import { outputFile } from './vite.test-config'; beforeEach(cleanup); -test('writes a report', () => { +test('writes a report', async () => { expect(existsSync(outputFile)).toBe(false); - try { - // "vitest" binary should be available when run through package.json script - execSync('vitest --config test/vite.test-config.ts', { - stdio: 'inherit', - }); - } catch (_) { - // Ignore exit codes - } - + await runVitest(); expect(existsSync(outputFile)).toBe(true); const contents = readFileSync(outputFile, 'utf-8'); @@ -71,6 +63,39 @@ test('writes a report', () => { `); }); +test('report location is logged', async () => { + const data = await runVitest(); + expect(existsSync(outputFile)).toBe(true); + + expect(stabilizeReport(data)).toMatchInlineSnapshot( + '"SonarQube report written to /report-from-tests.xml"' + ); +}); + +test('logging can be silenced', async () => { + const data = await runVitest({ + env: { ...process.env, TEST_ARGS_SILENT: 1 }, + }); + + expect(existsSync(outputFile)).toBe(true); + expect(data).toBe(''); +}); + +async function runVitest(opts = {}) { + // "vitest" binary should be available when run through package.json script + const subprocess = exec('vitest --config test/vite.test-config.ts', opts); + + let stdout = ''; + subprocess.stdout?.on('data', (data) => (stdout += data.toString())); + + await new Promise((resolve, reject) => { + subprocess.on('exit', resolve); + subprocess.stderr?.on('data', reject); + }); + + return stdout; +} + function cleanup() { if (existsSync(outputFile)) { rmSync(outputFile); diff --git a/test/utils.ts b/test/utils.ts index 316f274..86490bf 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -40,6 +40,7 @@ export function stabilizeReport(report: string) { limitStacktraces, removeCwd, removeLineNumbers, - removeDurations + removeDurations, + (text) => text.trim() )(report); } diff --git a/test/vite.test-config.ts b/test/vite.test-config.ts index a80d1f0..a7a9e05 100644 --- a/test/vite.test-config.ts +++ b/test/vite.test-config.ts @@ -4,6 +4,8 @@ import SonarReporter from '../src/sonar-reporter'; export const outputFile = 'report-from-tests.xml'; +const silent = Boolean(process.env.TEST_ARGS_SILENT); + export default defineConfig({ test: { watch: false, @@ -13,5 +15,8 @@ export default defineConfig({ 'test/fixtures/animals.test.ts', 'test/fixtures/math.test.ts', ], + + // @ts-expect-error -- untyped + sonarReporterOptions: { silent }, }, });