Skip to content

Commit

Permalink
Merge pull request #28 from Hargne/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Hargne authored Feb 8, 2018
2 parents 64c1187 + bd1b717 commit c6ac142
Show file tree
Hide file tree
Showing 7 changed files with 280 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ To configure this plugin, create a file named `jesthtmlreporter.config.json` in
| `theme` | `STRING` | The name of the reporter themes to use when rendering the report. Available themes are located within *style/* | `"defaultTheme"`
| `executionTimeWarningThreshold` | `NUMBER` | The threshold for test execution time (in seconds) in each test suite that will render a warning on the report page. 5 seconds is the default timeout in Jest. | `5`
| `dateFormat` | `STRING` | The format in which date/time should be formatted in the test report. Have a look in the [Wiki](https://github.com/Hargne/jest-html-reporter/wiki/Date-Format) for the available date format variables. | `"yyyy-mm-dd HH:MM:ss"`
| `sort` | `STRING` | Sorts the test results with the given method. Available methods are: `"default"`, `"status"` More information can be found in the [Wiki](https://github.com/Hargne/jest-html-reporter/wiki/Sorting-Methods). | `"default"`

#### *A note on styleOverridePath
The plugin will search for the file from the root directory, therefore there is no need to prepend the string with ./ or ../
Expand Down Expand Up @@ -119,4 +120,5 @@ The environment variables reflect the properties set in the JSON configuration f
* `JEST_HTML_REPORTER_THEME`
* `JEST_HTML_REPORTER_EXECUTION_TIME_WARNING_THRESHOLD`
* `JEST_HTML_REPORTER_DATE_FORMAT`
* `JEST_HTML_REPORTER_SORT`

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jest-html-reporter",
"version": "1.1.0",
"version": "1.2.0",
"description": "Jest test results processor for generating a summary in HTML",
"main": "dist/main",
"unpkg": "dist/main.min.js",
Expand Down
4 changes: 4 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ const getExecutionTimeWarningThreshold = () =>
const getDateFormat = () =>
config.dateFormat || process.env.JEST_HTML_REPORTER_DATE_FORMAT || 'yyyy-mm-dd HH:MM:ss';

const getSort = () =>
config.sort || process.env.JEST_HTML_REPORTER_SORT || 'default';

module.exports = {
config,
getOutputFilepath,
Expand All @@ -77,4 +80,5 @@ module.exports = {
getExecutionTimeWarningThreshold,
getTheme,
getDateFormat,
getSort,
};
16 changes: 15 additions & 1 deletion src/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const xmlbuilder = require('xmlbuilder');
const stripAnsi = require('strip-ansi');
const dateFormat = require('dateformat');
const config = require('./config');
const sorting = require('./sorting');

/**
* Logs a message of a given type in the terminal
Expand All @@ -26,6 +27,16 @@ const logMessage = ({ type, msg, ignoreConsole }) => {
return { logColor, logMsg }; // Return for testing purposes
};

/**
* Processes an array of test suite results
* @param {Object} suiteResults
* @return {Object}
*/
const processSuiteResults = (suiteResults) => {
const processedTestResults = sorting.sortSuiteResults(suiteResults, config.getSort());
return processedTestResults;
};

/**
* Creates a file at the given destination
* @param {String} filePath
Expand Down Expand Up @@ -98,8 +109,10 @@ const renderHTML = (testData, stylesheet) => new Promise((resolve, reject) => {
${testData.numPendingTests} pending
`);

const processedSuiteResults = processSuiteResults(testData.testResults);

// Test Suites
testData.testResults.forEach((suite) => {
processedSuiteResults.forEach((suite) => {
if (!suite.testResults || suite.testResults.length <= 0) { return; }

// Suite Information
Expand Down Expand Up @@ -162,6 +175,7 @@ const createReport = (testData, ignoreConsole) => {

module.exports = {
logMessage,
processSuiteResults,
writeFile,
createReport,
createHtml,
Expand Down
59 changes: 59 additions & 0 deletions src/sorting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Splits test suites apart based on individual test status and sorts by that status:
* 1. Pending
* 2. Failed
* 3. Passed
* @param {Object} suiteResults
*/
const sortSuiteResultsByStatus = (suiteResults) => {
const pendingSuites = [];
const failingSuites = [];
const passingSuites = [];

suiteResults.forEach((suiteResult) => {
const pending = [];
const failed = [];
const passed = [];

suiteResult.testResults.forEach((x) => {
if (x.status === 'pending') {
pending.push(x);
} else if (x.status === 'failed') {
failed.push(x);
} else {
passed.push(x);
}
});

if (pending.length) {
pendingSuites.push(Object.assign({}, suiteResult, { testResults: pending }));
}
if (failed.length) {
failingSuites.push(Object.assign({}, suiteResult, { testResults: failed }));
}
if (passed.length) {
passingSuites.push(Object.assign({}, suiteResult, { testResults: passed }));
}
});

return [].concat(pendingSuites, failingSuites, passingSuites);
};

/**
* Sorts test suite results
* If sort is undefined or is not a supported value this has no effect
* @param {Object} suiteResults
* @param {String} sort The configured sort
*/
const sortSuiteResults = (suiteResults, sort) => {
if (sort === 'status') {
return sortSuiteResultsByStatus(suiteResults);
}

return suiteResults;
};

module.exports = {
sortSuiteResults,
sortSuiteResultsByStatus,
};
115 changes: 115 additions & 0 deletions test/_mockdata-sorting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
module.exports = {
jestTestData: {
success: true,
startTime: 1498476492,
numTotalTestSuites: 3,
numPassedTestSuites: 1,
numFailedTestSuites: 1,
numRuntimeErrorTestSuites: 1,
numTotalTests: 9,
numPassedTests: 7,
numFailedTests: 1,
numPendingTests: 1,
testResults: [
{
numFailingTests: 0,
numPassingTests: 3,
numPendingTests: 0,
testResults: [
{
title: 'title',
status: 'passed',
ancestorTitles: ['ancestor'],
failureMessages: [],
numPassingAsserts: 0,
},
{
title: 'title',
status: 'passed',
ancestorTitles: ['ancestor'],
failureMessages: [],
numPassingAsserts: 0,
},
{
title: 'title',
status: 'passed',
ancestorTitles: ['ancestor'],
failureMessages: [],
numPassingAsserts: 0,
},
],
perfStats: {
start: 1498476492,
end: 1498476639,
},
testFilePath: 'index-a.js',
},
{
numFailingTests: 1,
numPassingTests: 1,
numPendingTests: 1,
testResults: [
{
title: 'title',
status: 'pending',
ancestorTitles: ['ancestor'],
failureMessages: [],
numPassingAsserts: 0,
},
{
title: 'title',
status: 'failed',
ancestorTitles: ['ancestor'],
failureMessages: ['failure'],
numPassingAsserts: 0,
},
{
title: 'title',
status: 'passed',
ancestorTitles: ['ancestor'],
failureMessages: [],
numPassingAsserts: 0,
},
],
perfStats: {
start: 1498476492,
end: 1498476639,
},
testFilePath: 'index-b.js',
},
{
numFailingTests: 1,
numPassingTests: 1,
numPendingTests: 1,
testResults: [
{
title: 'title',
status: 'pending',
ancestorTitles: ['ancestor'],
failureMessages: [],
numPassingAsserts: 0,
},
{
title: 'title',
status: 'failed',
ancestorTitles: ['ancestor'],
failureMessages: ['failure'],
numPassingAsserts: 0,
},
{
title: 'title',
status: 'passed',
ancestorTitles: ['ancestor'],
failureMessages: [],
numPassingAsserts: 0,
},
],
perfStats: {
start: 1498476492,
end: 1498476639,
},
testFilePath: 'index-c.js',
},
],
},
};
84 changes: 84 additions & 0 deletions test/sorting.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const sorting = require('../src/sorting');
const mockdataSorting = require('./_mockdata-sorting');

describe('sorting', () => {
it('should have no effect when sort not configured', () => {
const { testResults } = mockdataSorting.jestTestData;
const sortedTestResults = sorting.sortSuiteResults(testResults, undefined);

expect(sortedTestResults.length).toEqual(testResults.length);

testResults.forEach((testResult, index) => {
expect(sortedTestResults[index].testFilePath).toEqual(testResult.testFilePath);
});
});

describe('sortByStatus', () => {
/*
see _mockdata-sorting for test data
expected results for "status" are:
pending from index-b
pending from index-c
failed from index-b
failed from index-c
passed from index-a
passed from index-b
passed from index-c
meaning that the results are now broken into three sections:
1. pending
2. failed
3. passed
the pending and failed sections' sorting should match the passed section's sorting to make tests easier to find
*/

it('should order results as 1.pending 2.failed 3.passed', () => {
const { testResults } = mockdataSorting.jestTestData;
const sortedTestResults = sorting.sortSuiteResultsByStatus(testResults);

// pending
expect(sortedTestResults[0].testResults.length).toEqual(1);
expect(sortedTestResults[0].numPendingTests).toEqual(1);
expect(sortedTestResults[0].testFilePath).toEqual('index-b.js');

expect(sortedTestResults[1].testResults.length).toEqual(1);
expect(sortedTestResults[1].numPendingTests).toEqual(1);
expect(sortedTestResults[1].testFilePath).toEqual('index-c.js');

// failed
expect(sortedTestResults[2].testResults.length).toEqual(1);
expect(sortedTestResults[2].numFailingTests).toEqual(1);
expect(sortedTestResults[2].testFilePath).toEqual('index-b.js');

expect(sortedTestResults[3].testResults.length).toEqual(1);
expect(sortedTestResults[3].numFailingTests).toEqual(1);
expect(sortedTestResults[3].testFilePath).toEqual('index-c.js');

// passed
expect(sortedTestResults[4].testResults.length).toEqual(3);
expect(sortedTestResults[4].numPassingTests).toEqual(3);
expect(sortedTestResults[4].testFilePath).toEqual('index-a.js');

expect(sortedTestResults[5].testResults.length).toEqual(1);
expect(sortedTestResults[5].numPassingTests).toEqual(1);
expect(sortedTestResults[5].testFilePath).toEqual('index-b.js');

expect(sortedTestResults[6].testResults.length).toEqual(1);
expect(sortedTestResults[6].numPassingTests).toEqual(1);
expect(sortedTestResults[6].testFilePath).toEqual('index-c.js');
});

it('should sort all passed tests as default', () => {
const { testResults } = mockdataSorting.jestTestData;
const sortedTestResults = sorting.sortSuiteResultsByStatus(testResults);

// skipping the pending and failed sections of the output, the remainder should match
// currently the test data has two suites that each have one failed and one pending test, so skip 4
expect(sortedTestResults[4].testFilePath).toEqual(testResults[0].testFilePath);
expect(sortedTestResults[5].testFilePath).toEqual(testResults[1].testFilePath);
expect(sortedTestResults[6].testFilePath).toEqual(testResults[2].testFilePath);
});
});
});

0 comments on commit c6ac142

Please sign in to comment.