diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..ffa1b71 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "trailingComma": "all" +} diff --git a/src/__tests__/trx-generator.test.ts b/src/__tests__/trx-generator.test.ts index 6149aa5..8f41390 100644 --- a/src/__tests__/trx-generator.test.ts +++ b/src/__tests__/trx-generator.test.ts @@ -1,7 +1,7 @@ import "jest"; +import xml2js = require("xml2js"); import { generateTrx } from "../trx-generator"; import { JestTestRunResult } from "../types"; -import xml2js = require("xml2js"); describe("trx-generator", (): void => { it("processes the results correctly", (done): void => { @@ -42,9 +42,9 @@ describe("trx-generator", (): void => { numPassingAsserts: 1, status: "failed", title: "works not so well", - } - ] - } + }, + ], + }, ], }; const result: string = generateTrx(input); @@ -53,14 +53,24 @@ describe("trx-generator", (): void => { expect(parsed).toBeTruthy(); expect(parsed.TestRun).toBeTruthy(); expect(parsed.TestRun.$).toBeTruthy(); - expect(parsed.TestRun.$.xmlns).toEqual("http://microsoft.com/schemas/VisualStudio/TeamTest/2010"); + expect(parsed.TestRun.$.xmlns).toEqual( + "http://microsoft.com/schemas/VisualStudio/TeamTest/2010", + ); expect(parsed.TestRun.Results).toBeTruthy(); expect(parsed.TestRun.Results.length).toEqual(1); expect(parsed.TestRun.Results[0].UnitTestResult.length).toEqual(2); - expect(parsed.TestRun.Results[0].UnitTestResult[0].$.outcome).toEqual("Passed"); - expect(parsed.TestRun.Results[0].UnitTestResult[0].$.duration).toEqual("00:00:03.500"); - expect(parsed.TestRun.Results[0].UnitTestResult[1].$.outcome).toEqual("Failed"); - expect(parsed.TestRun.Results[0].UnitTestResult[1].$.duration).toEqual("00:00:03.500"); + expect(parsed.TestRun.Results[0].UnitTestResult[0].$.outcome).toEqual( + "Passed", + ); + expect(parsed.TestRun.Results[0].UnitTestResult[0].$.duration).toEqual( + "00:00:03.500", + ); + expect(parsed.TestRun.Results[0].UnitTestResult[1].$.outcome).toEqual( + "Failed", + ); + expect(parsed.TestRun.Results[0].UnitTestResult[1].$.duration).toEqual( + "00:00:03.500", + ); done(); }); @@ -104,9 +114,9 @@ describe("trx-generator", (): void => { numPassingAsserts: 1, status: "failed", title: "works not so well", - } - ] - } + }, + ], + }, ], }; const result: string = generateTrx(input); @@ -115,65 +125,65 @@ describe("trx-generator", (): void => { it("handles skipped test suites", (): void => { const input: JestTestRunResult = { - "numFailedTestSuites": 0, - "numFailedTests": 0, - "numPassedTestSuites": 0, - "numPassedTests": 0, - "numPendingTestSuites": 1, - "numPendingTests": 1, - "numRuntimeErrorTestSuites": 0, - "numTotalTestSuites": 1, - "numTotalTests": 1, - "snapshot": { - "added": 0, - "didUpdate": false, - "failure": false, - "filesAdded": 0, - "filesRemoved": 0, - "filesUnmatched": 0, - "filesUpdated": 0, - "matched": 0, - "total": 0, - "unchecked": 0, - "unmatched": 0, - "updated": 0 + numFailedTestSuites: 0, + numFailedTests: 0, + numPassedTestSuites: 0, + numPassedTests: 0, + numPendingTestSuites: 1, + numPendingTests: 1, + numRuntimeErrorTestSuites: 0, + numTotalTestSuites: 1, + numTotalTests: 1, + snapshot: { + added: 0, + didUpdate: false, + failure: false, + filesAdded: 0, + filesRemoved: 0, + filesUnmatched: 0, + filesUpdated: 0, + matched: 0, + total: 0, + unchecked: 0, + unmatched: 0, + updated: 0, }, - "startTime": 1511376995239, - "success": true, - "testResults": [ + startTime: 1511376995239, + success: true, + testResults: [ { - "numFailingTests": 0, - "numPassingTests": 0, - "numPendingTests": 1, - "perfStats": { - "end": 1511376996104, - "start": 1511376995923 + numFailingTests: 0, + numPassingTests: 0, + numPendingTests: 1, + perfStats: { + end: 1511376996104, + start: 1511376995923, }, - "snapshot": { - "added": 0, - "fileDeleted": false, - "matched": 0, - "unchecked": 0, - "unmatched": 0, - "updated": 0 + snapshot: { + added: 0, + fileDeleted: false, + matched: 0, + unchecked: 0, + unmatched: 0, + updated: 0, }, - "testFilePath": "C:\\Users\\Github\\test\\test.spec.js", - "testResults": [ + testFilePath: "C:\\Users\\Github\\test\\test.spec.js", + testResults: [ { - "ancestorTitles": [], - "duration": 0, - "failureMessages": [], - "fullName": "first", - "numPassingAsserts": 0, - "status": "pending", - "title": "first" - } + ancestorTitles: [], + duration: 0, + failureMessages: [], + fullName: "first", + numPassingAsserts: 0, + status: "pending", + title: "first", + }, ], - "sourceMaps": {}, - "skipped": true - } + sourceMaps: {}, + skipped: true, + }, ], - "wasInterrupted": false + wasInterrupted: false, }; const result: string = generateTrx(input); expect(result).toBeTruthy(); diff --git a/src/index.ts b/src/index.ts index df2659a..7babf63 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,11 @@ import { writeFileSync } from "fs"; import { generateTrx } from "./trx-generator"; -import { JestTestResult, JestTestRunResult, JestTestSuiteResult } from "./types"; +import { + JestTestResult, + JestTestRunResult, + JestTestSuiteResult, +} from "./types"; /** * All the configuration options. @@ -14,9 +18,11 @@ interface IOptions { outputFile: string; } -const processor = (options: IOptions = { - outputFile: "test-results.trx", -}) => (testRunResult: JestTestRunResult): JestTestRunResult => { +const processor = ( + options: IOptions = { + outputFile: "test-results.trx", + }, +) => (testRunResult: JestTestRunResult): JestTestRunResult => { process.stdout.write("Generating TRX file..."); const trx = generateTrx(testRunResult); diff --git a/src/trx-generator.ts b/src/trx-generator.ts index 9aebe1a..e8b220f 100644 --- a/src/trx-generator.ts +++ b/src/trx-generator.ts @@ -2,7 +2,11 @@ import * as os from "os"; import * as uuid from "uuid"; import * as builder from "xmlbuilder"; -import { JestTestResult, JestTestRunResult, JestTestSuiteResult } from "./types"; +import { + JestTestResult, + JestTestRunResult, + JestTestSuiteResult, +} from "./types"; // Magic GUID's and other constants const testListNotInListId = "8c84fa94-04c1-424b-9868-57a2d4851a1d"; @@ -26,9 +30,17 @@ const getTestClassName = (testResult: JestTestResult): string => ? testResult.ancestorTitles[0] : "No suite"; -const getSuitePerTestDuration = (testSuiteResult: JestTestSuiteResult): number => - // take the total duration of suite and divide it by the number of tests (Jest does not provide per test performance info) - Math.floor((testSuiteResult.perfStats.end - testSuiteResult.perfStats.start) / (testSuiteResult.numPassingTests + testSuiteResult.numFailingTests + testSuiteResult.numPendingTests)); +const getSuitePerTestDuration = ( + testSuiteResult: JestTestSuiteResult, +): number => + // take the total duration of suite and divide it by the number of tests + // (Jest does not provide per test performance info) + Math.floor( + (testSuiteResult.perfStats.end - testSuiteResult.perfStats.start) / + (testSuiteResult.numPassingTests + + testSuiteResult.numFailingTests + + testSuiteResult.numPendingTests), + ); // Adapted from https://github.com/hatchteam/karma-trx-reporter const formatDuration = (duration: number): string => { @@ -43,49 +55,69 @@ const formatDuration = (duration: number): string => { durationInner -= h * 3600000; const d = durationInner / 86400000; - return (d > 0 ? d + "." : "") + - (h < 10 ? "0" + h : h) + ":" + - (m < 10 ? "0" + m : m) + ":" + - (s < 10 ? "0" + s : s) + "." + - (ms < 10 ? "00" + ms : ms < 100 ? "0" + ms : ms); + return ( + (d > 0 ? d + "." : "") + + (h < 10 ? "0" + h : h) + + ":" + + (m < 10 ? "0" + m : m) + + ":" + + (s < 10 ? "0" + s : s) + + "." + + (ms < 10 ? "00" + ms : ms < 100 ? "0" + ms : ms) + ); }; const sanitizationRegex = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/g; -const sanitizeString = (str: string): string => str && str.replace(sanitizationRegex, ""); // removes the characters that make xmlbuilder throw +const sanitizeString = (str: string): string => + str && str.replace(sanitizationRegex, ""); // removes the characters that make xmlbuilder throw export const generateTrx = (testRunResult: JestTestRunResult): string => { const computerName = os.hostname(); - const userName = process.env.SUDO_USER || + const userName = + process.env.SUDO_USER || process.env.LOGNAME || process.env.USER || process.env.LNAME || process.env.USERNAME; // TestRun - const resultBuilder = builder.create("TestRun", { version: "1.0", encoding: "UTF-8" }) + const resultBuilder = builder + .create("TestRun", { version: "1.0", encoding: "UTF-8" }) .att("id", uuid.v4()) - .att("name", `${userName}@${computerName} ${new Date(testRunResult.startTime).toISOString()}`) + .att( + "name", + `${userName}@${computerName} ${new Date( + testRunResult.startTime, + ).toISOString()}`, + ) .att("runUser", userName) .att("xmlns", "http://microsoft.com/schemas/VisualStudio/TeamTest/2010"); // TestSettings - resultBuilder.ele("TestSettings") + resultBuilder + .ele("TestSettings") .att("name", "Jest test run") .att("id", uuid.v4()); // Times const startTime = new Date(testRunResult.startTime).toISOString(); - resultBuilder.ele("Times") + resultBuilder + .ele("Times") .att("creation", startTime) .att("queuing", startTime) .att("start", startTime); // ResultSummary - const summary = resultBuilder.ele("ResultSummary") + const summary = resultBuilder + .ele("ResultSummary") .att("outcome", testRunResult.success ? "Passed" : "Failed"); - summary.ele("Counters") + summary + .ele("Counters") .att("total", testRunResult.numTotalTests) - .att("executed", testRunResult.numTotalTests - testRunResult.numPendingTests) + .att( + "executed", + testRunResult.numTotalTests - testRunResult.numPendingTests, + ) .att("passed", testRunResult.numPassedTests) .att("failed", testRunResult.numFailedTests) .att("error", 0); @@ -93,10 +125,12 @@ export const generateTrx = (testRunResult: JestTestRunResult): string => { // TestDefinitions const testDefinitions = resultBuilder.ele("TestDefinitions"); const testLists = resultBuilder.ele("TestLists"); - testLists.ele("TestList") + testLists + .ele("TestList") .att("name", "Results Not in a List") .att("id", testListNotInListId); - testLists.ele("TestList") + testLists + .ele("TestList") .att("name", "All Loaded Results") .att("id", testListAllLoadedResultsId); const testEntries = resultBuilder.ele("TestEntries"); @@ -112,37 +146,56 @@ export const generateTrx = (testRunResult: JestTestRunResult): string => { const fullTestName = getFullTestName(testResult); // UnitTest - const unitTest = testDefinitions.ele("UnitTest") + const unitTest = testDefinitions + .ele("UnitTest") .att("name", fullTestName) .att("id", testId); - unitTest.ele("Execution") - .att("id", executionId); - unitTest.ele("TestMethod") + unitTest.ele("Execution").att("id", executionId); + unitTest + .ele("TestMethod") .att("codeBase", `Jest_${fullTestName}`) .att("name", fullTestName) .att("className", getTestClassName(testResult)); // TestEntry - testEntries.ele("TestEntry") + testEntries + .ele("TestEntry") .att("testId", testId) .att("executionId", executionId) .att("testListId", testListNotInListId); // UnitTestResult - const result = results.ele("UnitTestResult") + const result = results + .ele("UnitTestResult") .att("testId", testId) .att("executionId", executionId) .att("testName", fullTestName) .att("computerName", computerName) .att("duration", perTestDurationFormatted) - .att("startTime", new Date(testSuiteResult.perfStats.start + index * perTestDuration).toISOString()) - .att("endTime", new Date(testSuiteResult.perfStats.start + (index + 1) * perTestDuration).toISOString()) + .att( + "startTime", + new Date( + testSuiteResult.perfStats.start + index * perTestDuration, + ).toISOString(), + ) + .att( + "endTime", + new Date( + testSuiteResult.perfStats.start + (index + 1) * perTestDuration, + ).toISOString(), + ) .att("testType", testType) .att("outcome", testOutcomeTable[testResult.status]) .att("testListId", testListNotInListId); if (testResult.status === "failed") { - result.ele("Output").ele("ErrorInfo").ele("Message", sanitizeString(testResult.failureMessages.join("\n"))); + result + .ele("Output") + .ele("ErrorInfo") + .ele( + "Message", + sanitizeString(testResult.failureMessages.join("\n")), + ); } }); }); diff --git a/tslint.json b/tslint.json index fb70a88..f5a9d91 100644 --- a/tslint.json +++ b/tslint.json @@ -3,6 +3,6 @@ "rules": { "arrow-parens": false, "interface-name": false, - "max-line-length": false + "object-literal-sort-keys": false } }