diff --git a/.eslintignore b/.eslintignore index 1c260130990d..ad6f76826327 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,7 +1,8 @@ -bin/ -docs/ +**/coverage/** **/node_modules/** **/vendor/** -website/ -**/coverage/** +bin/ +docs/ packages/*/build/** +types/** +website/ diff --git a/packages/jest-cli/src/reporters/DefaultTestReporter.js b/packages/jest-cli/src/reporters/DefaultTestReporter.js index 04b05f8cb34b..711a5db76eef 100644 --- a/packages/jest-cli/src/reporters/DefaultTestReporter.js +++ b/packages/jest-cli/src/reporters/DefaultTestReporter.js @@ -4,14 +4,34 @@ * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. + * + * @flow */ 'use strict'; +import type {AggregatedResult, TestResult} from 'types/TestResult'; +import type {Config} from 'types/Config'; +import type {Process} from 'types/Process'; + const chalk = require('chalk'); const formatFailureMessage = require('jest-util').formatFailureMessage; const path = require('path'); const VerboseLogger = require('./VerboseLogger'); +type SnapshotSummary = { + added: number, + didUpdate: boolean, + filesAdded: number, + filesRemoved: number, + filesUnmatched: number, + filesUpdated: number, + matched: number, + total: number, + unchecked: number, + unmatched: number, + updated: number, +}; + // Explicitly reset for these messages since they can get written out in the // middle of error logging (should have listened to Spengler and not crossed the // streams). @@ -34,15 +54,19 @@ const pluralize = (word, count) => `${count} ${word}${count === 1 ? '' : 's'}`; class DefaultTestReporter { - constructor(customProcess) { + _config: Config; + _process: Process; + verboseLogger: VerboseLogger; + + constructor(customProcess: Process) { this._process = customProcess || process; } - log(string) { - this._process.stdout.write(string + '\n'); + log(message: string) { + this._process.stdout.write(message + '\n'); } - onRunStart(config, results) { + onRunStart(config: Config, results: AggregatedResult) { this._config = config; this._printWaitingOn(results); if (this._config.verbose) { @@ -50,7 +74,11 @@ class DefaultTestReporter { } } - onTestResult(config, testResult, results) { + onTestResult( + config: Config, + testResult: TestResult, + results: AggregatedResult, + ) { this._clearWaitingOn(); const pathStr = @@ -105,7 +133,7 @@ class DefaultTestReporter { this._printWaitingOn(results); } - onRunComplete(config, aggregatedResults) { + onRunComplete(config: Config, aggregatedResults: AggregatedResult) { const totalTestSuites = aggregatedResults.numTotalTestSuites; const failedTests = aggregatedResults.numFailedTests; const passedTests = aggregatedResults.numPassedTests; @@ -158,7 +186,7 @@ class DefaultTestReporter { return snapshotFailure ? false : aggregatedResults.success; } - _getSnapshotSummary(aggregatedResults) { + _getSnapshotSummary(aggregatedResults: AggregatedResult): SnapshotSummary { let added = 0; let filesAdded = 0; let filesRemoved = aggregatedResults.snapshotFilesRemoved; @@ -204,7 +232,7 @@ class DefaultTestReporter { }; } - _printSnapshotSummary(snapshots) { + _printSnapshotSummary(snapshots: SnapshotSummary) { if ( snapshots.added || snapshots.filesRemoved || @@ -265,7 +293,7 @@ class DefaultTestReporter { } } - _printSummary(aggregatedResults) { + _printSummary(aggregatedResults: AggregatedResult) { // If there were any failing tests and there was a large number of tests // executed, re-print the failing results at the end of execution output. const failedTests = aggregatedResults.numFailedTests; @@ -305,7 +333,7 @@ class DefaultTestReporter { this._process.stdout.write(this._config.noHighlight ? '' : '\r\x1B[K'); } - _printWaitingOn(results) { + _printWaitingOn(results: AggregatedResult) { const remaining = results.numTotalTestSuites - results.numPassedTestSuites - results.numFailedTestSuites - diff --git a/packages/jest-cli/src/reporters/IstanbulTestReporter.js b/packages/jest-cli/src/reporters/IstanbulTestReporter.js index 43fbbcd7c629..952c2f718660 100644 --- a/packages/jest-cli/src/reporters/IstanbulTestReporter.js +++ b/packages/jest-cli/src/reporters/IstanbulTestReporter.js @@ -4,6 +4,8 @@ * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. +* +* @flow */ 'use strict'; @@ -16,8 +18,15 @@ const reporter = new istanbul.Reporter(); const FAIL_COLOR = chalk.bold.red; +import type {Config} from 'types/Config'; +import type {AggregatedResult, TestResult} from 'types/TestResult'; + class IstanbulTestReporter extends DefaultTestReporter { - onTestResult(config, testResult, aggregatedResults) { + onTestResult( + config: Config, + testResult: TestResult, + aggregatedResults: AggregatedResult, + ) { super.onTestResult(config, testResult, aggregatedResults); if (config.collectCoverage && testResult.coverage) { @@ -29,7 +38,7 @@ class IstanbulTestReporter extends DefaultTestReporter { } } - onRunComplete(config, aggregatedResults) { + onRunComplete(config: Config, aggregatedResults: AggregatedResult) { aggregatedResults.success = super.onRunComplete(config, aggregatedResults); if (config.collectCoverage) { diff --git a/packages/jest-cli/src/reporters/VerboseLogger.js b/packages/jest-cli/src/reporters/VerboseLogger.js index 844c30af2b12..0f0dc7fcd5c7 100644 --- a/packages/jest-cli/src/reporters/VerboseLogger.js +++ b/packages/jest-cli/src/reporters/VerboseLogger.js @@ -4,25 +4,62 @@ * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. + * + * @flow */ 'use strict'; +import type { + AssertionResult, + Suite, +} from 'types/TestResult'; +import type {Process} from 'types/Process'; + const chalk = require('chalk'); class VerboseLogger { - constructor(customProcess) { + _process: Process; + + constructor(customProcess?: ?Process) { this._process = customProcess || process; } - logTestResults(testResults) { - groupTestsBySuites(testResults).forEach(suite => + static groupTestsBySuites(testResults: Array) { + const root: Suite = { + suites: [], + tests: [], + title: 'Root Suite', + }; + + testResults.forEach(testResult => { + let targetSuite = root; + + // Find the target suite for this test, + // creating nested suites as necessary. + for (const title of testResult.ancestorTitles) { + let matchingSuite = targetSuite.suites.find(s => s.title === title); + if (!matchingSuite) { + matchingSuite = {title, suites: [], tests: []}; + targetSuite.suites.push(matchingSuite); + } + targetSuite = matchingSuite; + } + + targetSuite.tests.push(testResult); + }); + + return root.suites; + } + + logTestResults(testResults: Array) { + VerboseLogger.groupTestsBySuites(testResults).forEach(suite => this._logSuite(suite, 0) ); this._logLine(); } - _logSuite(suite, indentLevel) { + _logSuite(suite: Suite, indentLevel: number) { this._logLine(suite.title, indentLevel); suite.tests.forEach(test => @@ -34,7 +71,7 @@ class VerboseLogger { ); } - _getIcon(status) { + _getIcon(status: string) { if (status === 'failed') { return chalk.red('\u2715'); } else if (status === 'pending') { @@ -44,42 +81,15 @@ class VerboseLogger { } } - _logTest(test, indentLevel) { + _logTest(test: AssertionResult, indentLevel: number) { const status = this._getIcon(test.status); this._logLine(`${status} ${chalk.gray(test.title)}`, indentLevel); } - _logLine(str, indentLevel) { - str = str || ''; - indentLevel = indentLevel || 0; - + _logLine(str: string = '', indentLevel: number = 0) { const indentation = ' '.repeat(indentLevel); this._process.stdout.write(`${indentation}${str}\n`); } } -function groupTestsBySuites(testResults) { - const root = {suites: []}; - - testResults.forEach(testResult => { - let targetSuite = root; - - // Find the target suite for this test, - // creating nested suites as necessary. - for (const title of testResult.ancestorTitles) { - let matchingSuite = targetSuite.suites.find(s => s.title === title); - if (!matchingSuite) { - matchingSuite = {title, suites: [], tests: []}; - targetSuite.suites.push(matchingSuite); - } - targetSuite = matchingSuite; - } - - targetSuite.tests.push(testResult); - }); - - return root.suites; -} - -VerboseLogger.groupTestsBySuites = groupTestsBySuites; module.exports = VerboseLogger; diff --git a/packages/jest-snapshot/src/SnapshotFile.js b/packages/jest-snapshot/src/SnapshotFile.js index 0aab7a18b58d..eb45c151a176 100644 --- a/packages/jest-snapshot/src/SnapshotFile.js +++ b/packages/jest-snapshot/src/SnapshotFile.js @@ -25,6 +25,8 @@ export type MatchResult = { pass: boolean, }; +type SnapshotData = {[key: string]: string}; + type SaveStatus = { deleted: boolean, saved: boolean, @@ -47,7 +49,7 @@ const fileExists = (filePath: Path): boolean => { class SnapshotFile { - _content: {[key: string]: any}; + _content: SnapshotData; _dirty: boolean; _filename: Path; _uncheckedKeys: Set; @@ -59,7 +61,9 @@ class SnapshotFile { this._content = Object.create(null); if (this.fileExists(filename)) { try { + /* eslint-disable no-useless-call */ Object.assign(this._content, require.call(null, filename)); + /* eslint-enable no-useless-call */ } catch (e) {} } this._uncheckedKeys = new Set(Object.keys(this._content)); diff --git a/types/Config.js b/types/Config.js index c272e2c57514..4cfbc339ebb2 100644 --- a/types/Config.js +++ b/types/Config.js @@ -26,6 +26,11 @@ export type Config = { colors: boolean, coverageCollector: Path, coverageReporters: Array, + coverageThreshold: { + global: { + [key: string]: number, + }, + }, globals: ConfigGlobals, haste: HasteConfig, mocksPattern: string, diff --git a/types/Process.js b/types/Process.js new file mode 100644 index 000000000000..a4acb3db826d --- /dev/null +++ b/types/Process.js @@ -0,0 +1,4 @@ +export interface Process { + stdout : stream$Writable | tty$WriteStream; + exit(code? : number) : void; +}; diff --git a/types/TestResult.js b/types/TestResult.js index e50ff756887c..07a3f65eba13 100644 --- a/types/TestResult.js +++ b/types/TestResult.js @@ -36,9 +36,32 @@ export type AssertionResult = { numPassingAsserts: number, }; +export type AggregatedResult = { + didUpdate: boolean, + numFailedTests: number, + numFailedTestSuites: number, + numPassedTests: number, + numPassedTestSuites: number, + numPendingTests: number, + numRuntimeErrorTestSuites: number, + numTotalTests: number, + numTotalTestSuites: number, + snapshotFilesRemoved: number, + startTime: number, + success: boolean, + testResults: Array, +}; + +export type Suite = { + title: string, + suites: Array, + tests: Array, +}; + export type TestResult = { coverage: ?Coverage, hasUncheckedKeys: boolean, + message: string, numFailingTests: number, numPassingTests: number, numPendingTests: number,