diff --git a/.flowconfig b/.flowconfig index 5b49eeb..d5141d8 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,5 +1,6 @@ [ignore] .*/node_modules/fbjs/.* +.*/node_modules/yargs/.* .*/dist/.* .*/__tests__/fixtures/.* diff --git a/__tests__/integrations/cli/test-badge-reporter.js b/__tests__/integrations/cli/test-badge-reporter.js index baae796..9256a92 100644 --- a/__tests__/integrations/cli/test-badge-reporter.js +++ b/__tests__/integrations/cli/test-badge-reporter.js @@ -22,39 +22,43 @@ async function svg2json(filePath) { describe('badge reporter', () => { it('should generate red badges on project-low-coverage-with-error', async () => { - const tmpDir = tempy.directory(); + const temporaryDir = tempy.directory(); const {exitCode} = await runFlowCoverageReport([ - '-i', `"src/*.js"`, '-t', 'badge', '-o', tmpDir + '-i', '"src/*.js"', '-t', 'badge', '-o', temporaryDir ], {cwd: testLowCoverageDir}); // Expect flow-coverage-report to exit with 2 on low coverage. expect(exitCode).toBe(2); - const flowBadge = await svg2json(path.join(tmpDir, 'flow-badge.svg')); - const flowCoverageBadge = await svg2json(path.join(tmpDir, 'flow-coverage-badge.svg')); + const flowBadge = await svg2json(path.join(temporaryDir, 'flow-badge.svg')); + const flowCoverageBadge = await svg2json(path.join(temporaryDir, 'flow-coverage-badge.svg')); expect(flowBadge).toMatchSnapshot('flow-badge red'); expect(flowCoverageBadge).toMatchSnapshot('flow-coverage-badge red'); - await new Promise(resolve => rimraf(path.join(tmpDir, '*.svg'), resolve)); + await new Promise(resolve => { + rimraf(path.join(temporaryDir, '*.svg'), resolve); + }); }); it('should generate green badges on full covered project', async () => { - const tmpDir = tempy.directory(); + const temporaryDir = tempy.directory(); const {exitCode} = await runFlowCoverageReport([ - '-i', `"src/*.js"`, '-t', 'badge', '-o', tmpDir + '-i', '"src/*.js"', '-t', 'badge', '-o', temporaryDir ], {cwd: testFullCoverageDir}); expect(exitCode).toBe(0); - const flowBadge = await svg2json(path.join(tmpDir, 'flow-badge.svg')); - const flowCoverageBadge = await svg2json(path.join(tmpDir, 'flow-coverage-badge.svg')); + const flowBadge = await svg2json(path.join(temporaryDir, 'flow-badge.svg')); + const flowCoverageBadge = await svg2json(path.join(temporaryDir, 'flow-coverage-badge.svg')); expect(flowBadge).toMatchSnapshot('flow-badge green'); expect(flowCoverageBadge).toMatchSnapshot('flow-coverage-badge green'); - await new Promise(resolve => rimraf(path.join(tmpDir, '*.svg'), resolve)); + await new Promise(resolve => { + rimraf(path.join(temporaryDir, '*.svg'), resolve); + }); }); }); diff --git a/__tests__/integrations/cli/test-exit-value.js b/__tests__/integrations/cli/test-exit-value.js index 4453bf1..20ee63e 100644 --- a/__tests__/integrations/cli/test-exit-value.js +++ b/__tests__/integrations/cli/test-exit-value.js @@ -12,7 +12,7 @@ const testProjectDir = path.join(FIXTURE_PATH, 'project-low-coverage'); describe('CLI exit value', async () => { it('should exit with code 2 when total coverage is lower than the default threshold', async () => { const {exitCode, error} = await runFlowCoverageReport([ - '-i', `"src/*.js"` + '-i', '"src/*.js"' ], {cwd: testProjectDir}); expect({exitCode, error}).toMatchSnapshot(); @@ -20,8 +20,10 @@ describe('CLI exit value', async () => { it('should exit with code 2 when total coverage is lower than the custom threshold', async () => { const {exitCode, error} = await runFlowCoverageReport([ - '-i', `"src/*.js"`, - '--threshold', '22' + '-i', + '"src/*.js"', + '--threshold', + '22' ], {cwd: testProjectDir}); expect({exitCode, error}).toMatchSnapshot(); @@ -29,8 +31,10 @@ describe('CLI exit value', async () => { it('should exit with code 0 when total coverage is higher than the custom threshold', async () => { const {exitCode, error} = await runFlowCoverageReport([ - '-i', `"src/*.js"`, - '--threshold', '10' + '-i', + '"src/*.js"', + '--threshold', + '10' ], {cwd: testProjectDir}); expect({exitCode, error}).toMatchSnapshot(); diff --git a/__tests__/integrations/cli/test-file-special-chars-escape.js b/__tests__/integrations/cli/test-file-special-chars-escape.js index 4b7649e..c9e6576 100644 --- a/__tests__/integrations/cli/test-file-special-chars-escape.js +++ b/__tests__/integrations/cli/test-file-special-chars-escape.js @@ -9,15 +9,15 @@ import { const testProjectDir = path.join(FIXTURE_PATH, 'file-special-chars-escape'); -jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // 10 second timeout +jest.setTimeout(10000); // 10 second timeout test('Fixed #92 - Escape special chars in filenames', async () => { const {stdout, stderr} = await runFlowCoverageReport([ - '-i', `"src/*.js"` + '-i', '"src/*.js"' ], {cwd: testProjectDir}); const filteredStdout = stdout.split('\n').filter( - line => line.indexOf('src/file-with-a') >= 0 + line => line.includes('src/file-with-a') ); expect({filteredStdout, stderr}).toMatchSnapshot(); diff --git a/__tests__/integrations/cli/test-flow-strict.js b/__tests__/integrations/cli/test-flow-strict.js index ddfc3fb..55b1840 100644 --- a/__tests__/integrations/cli/test-flow-strict.js +++ b/__tests__/integrations/cli/test-flow-strict.js @@ -9,15 +9,15 @@ import { const testProjectDir = path.join(FIXTURE_PATH, 'flow-strict'); -jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // 10 second timeout +jest.setTimeout(10000); // 10 second timeout test('Accept \'@flow strict\' and \'@flow strict-local\' pragmas', async () => { const {stdout, stderr} = await runFlowCoverageReport([ - '-i', `"src/*.js"` + '-i', '"src/*.js"' ], {cwd: testProjectDir}); - const filteredStdoutMain = stdout.split('\n').filter(line => line.indexOf('src/main') >= 0); - const filteredStdoutLocal = stdout.split('\n').filter(line => line.indexOf('src/local') >= 0); + const filteredStdoutMain = stdout.split('\n').filter(line => line.includes('src/main')); + const filteredStdoutLocal = stdout.split('\n').filter(line => line.includes('src/local')); expect({filteredStdoutMain, filteredStdoutLocal, stderr}).toMatchSnapshot(); }); diff --git a/__tests__/integrations/cli/test-issue-135.js b/__tests__/integrations/cli/test-issue-135.js index 19caa7a..047566b 100644 --- a/__tests__/integrations/cli/test-issue-135.js +++ b/__tests__/integrations/cli/test-issue-135.js @@ -9,14 +9,14 @@ import { const testProjectDir = path.join(FIXTURE_PATH, 'issue-135'); -jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // 10 second timeout +jest.setTimeout(10000); // 10 second timeout test('Fixed #135 - Annotation wrong on multiple pragma on the same line', async () => { const {stdout, stderr} = await runFlowCoverageReport([ - '-i', `"src/*.js"` + '-i', '"src/*.js"' ], {cwd: testProjectDir}); - const filteredStdout = stdout.split('\n').filter(line => line.indexOf('src/multiple-pragmas') >= 0); + const filteredStdout = stdout.split('\n').filter(line => line.includes('src/multiple-pragmas')); expect({filteredStdout, stderr}).toMatchSnapshot(); }); diff --git a/__tests__/integrations/cli/test-percent-decimals.js b/__tests__/integrations/cli/test-percent-decimals.js index 0729edd..165eb4d 100644 --- a/__tests__/integrations/cli/test-percent-decimals.js +++ b/__tests__/integrations/cli/test-percent-decimals.js @@ -12,12 +12,14 @@ const testProjectDir = path.join(FIXTURE_PATH, 'project-decimal-coverage'); describe('--percent-decimals option', () => { it('should round percent values using the requested precision', async () => { const {exitCode, error, stderr, stdout} = await runFlowCoverageReport([ - '--percent-decimals', '2', - '-i', '"src/**.js"' + '--percent-decimals', + '2', + '-i', + '"src/**.js"' ], {cwd: testProjectDir}); const filteredStdout = stdout.split('\n').filter( - line => line.indexOf('src/main.js') >= 0 || line.indexOf('project-decimal-coverage') >= 0); + line => line.includes('src/main.js') || line.includes('project-decimal-coverage')); expect({exitCode, error, stderr, filteredStdout}).toMatchSnapshot(); }); diff --git a/__tests__/integrations/cli/test-regression-issue-57.js b/__tests__/integrations/cli/test-regression-issue-57.js index 3bab6e1..5edeb62 100644 --- a/__tests__/integrations/cli/test-regression-issue-57.js +++ b/__tests__/integrations/cli/test-regression-issue-57.js @@ -9,14 +9,14 @@ import { const testProjectDir = path.join(FIXTURE_PATH, 'issue-57'); -jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // 10 second timeout +jest.setTimeout(10000); // 10 second timeout test('Fixed #57 - NaN in text report', async () => { const {stdout, stderr} = await runFlowCoverageReport([ - '-i', `"src/*.js"` + '-i', '"src/*.js"' ], {cwd: testProjectDir}); - const filteredStdout = stdout.split('\n').filter(line => line.indexOf('src/url.js') >= 0); + const filteredStdout = stdout.split('\n').filter(line => line.includes('src/url.js')); expect({filteredStdout, stderr}).toMatchSnapshot(); }); diff --git a/bin/flow-coverage-report.js b/bin/flow-coverage-report.js index d95cd64..444584f 100755 --- a/bin/flow-coverage-report.js +++ b/bin/flow-coverage-report.js @@ -1,4 +1,4 @@ #!/usr/bin/env node const path = require('path'); -require(path.join(__dirname, '../dist/lib/cli')).run(); // eslint-disable-line import/no-dynamic-require +require(path.join(__dirname, '../dist/lib/cli')).run(); diff --git a/flow-typed/npm/glob_v7.1.x.js b/flow-typed/npm/glob_v7.1.x.js new file mode 100644 index 0000000..9a01f87 --- /dev/null +++ b/flow-typed/npm/glob_v7.1.x.js @@ -0,0 +1,87 @@ +// flow-typed signature: 257135a98dbce29a68026e7b9b7f381d +// flow-typed version: c6154227d1/glob_v7.1.x/flow_>=v0.42.x <=v0.103.x + +declare module "glob" { + declare type MinimatchOptions = {| + debug?: boolean, + nobrace?: boolean, + noglobstar?: boolean, + dot?: boolean, + noext?: boolean, + nocase?: boolean, + nonull?: boolean, + matchBase?: boolean, + nocomment?: boolean, + nonegate?: boolean, + flipNegate?: boolean + |}; + + declare type Options = {| + ...MinimatchOptions, + cwd?: string, + root?: string, + nomount?: boolean, + mark?: boolean, + nosort?: boolean, + stat?: boolean, + silent?: boolean, + strict?: boolean, + cache?: { + [path: string]: boolean | "DIR" | "FILE" | $ReadOnlyArray + }, + statCache?: { + [path: string]: boolean | { isDirectory(): boolean } | void + }, + symlinks?: { [path: string]: boolean | void }, + realpathCache?: { [path: string]: string }, + sync?: boolean, + nounique?: boolean, + nodir?: boolean, + ignore?: string | $ReadOnlyArray, + follow?: boolean, + realpath?: boolean, + absolute?: boolean + |}; + + /** + * Called when an error occurs, or matches are found + * err + * matches: filenames found matching the pattern + */ + declare type CallBack = (err: ?Error, matches: Array) => void; + + declare class Glob extends events$EventEmitter { + constructor(pattern: string): this; + constructor(pattern: string, callback: CallBack): this; + constructor(pattern: string, options: Options, callback: CallBack): this; + + minimatch: {}; + options: Options; + aborted: boolean; + cache: { + [path: string]: boolean | "DIR" | "FILE" | $ReadOnlyArray + }; + statCache: { + [path: string]: boolean | { isDirectory(): boolean } | void + }; + symlinks: { [path: string]: boolean | void }; + realpathCache: { [path: string]: string }; + found: Array; + + pause(): void; + resume(): void; + abort(): void; + } + + declare class GlobModule { + Glob: Class; + + (pattern: string, callback: CallBack): void; + (pattern: string, options: Options, callback: CallBack): void; + + hasMagic(pattern: string, options?: Options): boolean; + sync(pattern: string, options?: Options): Array; + } + + declare module.exports: GlobModule; +} diff --git a/flow-typed/npm/minimatch_v3.x.x.js b/flow-typed/npm/minimatch_v3.x.x.js index e2b73ff..93e65b4 100644 --- a/flow-typed/npm/minimatch_v3.x.x.js +++ b/flow-typed/npm/minimatch_v3.x.x.js @@ -1,5 +1,5 @@ -// flow-typed signature: bc0af4a44bb8631039f713b1afba6988 -// flow-typed version: d42cbef63c/minimatch_v3.x.x/flow_>=v0.25.x +// flow-typed signature: 372b91a58c99da7bdf7640dc9aa42756 +// flow-typed version: c6154227d1/minimatch_v3.x.x/flow_>=v0.25.x <=v0.103.x type $npm$minimatch$Options = { debug?: boolean, diff --git a/flow-typed/npm/strip-json-comments_v2.x.x.js b/flow-typed/npm/strip-json-comments_v3.x.x.js similarity index 100% rename from flow-typed/npm/strip-json-comments_v2.x.x.js rename to flow-typed/npm/strip-json-comments_v3.x.x.js diff --git a/flow-typed/npm/temp_v0.8.x.js b/flow-typed/npm/temp_v0.9.x.js similarity index 100% rename from flow-typed/npm/temp_v0.8.x.js rename to flow-typed/npm/temp_v0.9.x.js diff --git a/flow-typed/npm/yargs_v8.x.x.js b/flow-typed/npm/yargs_v16.x.x.js similarity index 74% rename from flow-typed/npm/yargs_v8.x.x.js rename to flow-typed/npm/yargs_v16.x.x.js index b35c87a..e6b6daf 100644 --- a/flow-typed/npm/yargs_v8.x.x.js +++ b/flow-typed/npm/yargs_v16.x.x.js @@ -1,11 +1,8 @@ -// flow-typed signature: 28b06f0a373cccd37c902772cd2b3a57 -// flow-typed version: da30fe6876/yargs_v8.x.x/flow_>=v0.42.x - declare module "yargs" { declare type Argv = { + [key: string]: any, _: Array, $0: string, - [key: string]: mixed }; declare type Options = $Shape<{ @@ -13,10 +10,10 @@ declare module "yargs" { array: boolean, boolean: boolean, choices: Array, - coerce: (arg: mixed) => mixed, + coerce: (arg: {[key: string]: any} | any) => mixed, config: boolean, configParser: (configPath: string) => { [key: string]: mixed }, - conflicts: string | { [key: string]: string }, + conflicts: string | Array | { [key: string]: string }, count: boolean, default: mixed, defaultDescription: string, @@ -30,17 +27,18 @@ declare module "yargs" { nargs: number, normalize: boolean, number: boolean, + required: boolean, requiresArg: boolean, skipValidation: boolean, string: boolean, - type: "array" | "boolean" | "count" | "number" | "string" + type: "array" | "boolean" | "count" | "number" | "string", }>; declare type CommonModuleObject = {| command?: string | Array, aliases?: Array | string, builder?: { [key: string]: Options } | ((yargsInstance: Yargs) => mixed), - handler?: (argv: Argv) => void + handler?: ((argv: Argv) => void) | ((argv: Argv) => Promise) |}; declare type ModuleObjectDesc = {| @@ -63,6 +61,12 @@ declare module "yargs" { | ModuleObjectDescribe | ModuleObjectDescription; + declare type MiddleWareCallback = + | (argv: Argv, yargsInstance?: Yargs) => void + | (argv: Argv, yargsInstance?: Yargs) => Promise; + + declare type Middleware = MiddleWareCallback | Array; + declare class Yargs { (args: Array): Yargs; @@ -70,7 +74,7 @@ declare module "yargs" { alias(alias: { [key: string]: string | Array }): this; argv: Argv; array(key: string | Array): this; - boolean(paramter: string | Array): this; + boolean(parameter: string | Array): this; check(fn: (argv: Argv, options: Array) => ?boolean): this; choices(key: string, allowed: Array): this; choices(allowed: { [key: string]: Array }): this; @@ -93,13 +97,28 @@ declare module "yargs" { command(module: ModuleObject): this; + commandDir( + directory: string, + options?: { + exclude?: string | Function, + extensions?: Array, + include?: string | Function, + recurse?: boolean, + visit?: Function, + }, + ): this; + completion( - cmd: string, - description?: string, + cmd?: string, + description?: string | false | ( + current: string, + argv: Argv, + done: (compeltion: Array) => void + ) => ?(Array | Promise>), fn?: ( current: string, argv: Argv, - done: (competion: Array) => void + done: (completion: Array) => void ) => ?(Array | Promise>) ): this; @@ -114,8 +133,8 @@ declare module "yargs" { ): this; config(config: { [key: string]: mixed }): this; - conflicts(keyA: string, keyB: string): this; - conflicts(keys: { [key: string]: string }): this; + conflicts(key: string, value: string | Array): this; + conflicts(keys: { [key: string]: string | Array }): this; count(name: string): this; @@ -128,6 +147,7 @@ declare module "yargs" { demandOption(key: string | Array, msg?: string | boolean): this; + demandCommand(): this; demandCommand(min: number, minMsg?: string): this; demandCommand( min: number, @@ -146,7 +166,7 @@ declare module "yargs" { epilog(text: string): this; epilogue(text: string): this; - example(cmd: string, desc: string): this; + example(cmd: string, desc?: string): this; exitProcess(enable: boolean): this; @@ -158,10 +178,14 @@ declare module "yargs" { group(key: string | Array, groupName: string): this; + help(option: boolean): this; + help(option?: string, desc?: string): this; - implies(keyA: string, keyB: string): this; - implies(keys: { [key: string]: string }): this; + hide(key: string): this; + + implies(key: string, value: string | Array): this; + implies(keys: { [key: string]: string | Array }): this; locale( locale: | "de" @@ -186,6 +210,11 @@ declare module "yargs" { ): this; locale(): string; + middleware( + middlewareCallbacks: Middleware, + applyBeforeValidation?: boolean, + ): this; + nargs(key: string, count: number): this; normalize(key: string): this; @@ -199,17 +228,21 @@ declare module "yargs" { options(optionMap: { [key: string]: Options }): this; parse( - args: string | Array, - context?: { [key: string]: mixed }, + args?: string | Array, + context?: { [key: string]: any }, parseCallback?: (err: Error, argv: Argv, output?: string) => void ): Argv; parse( - args: string | Array, + args?: string | Array, parseCallback?: (err: Error, argv: Argv, output?: string) => void ): Argv; + parserConfiguration(configuration: {[key: string]: any}): this; + pkgConf(key: string, cwd?: string): this; + positional(key: string, opt?: Options): this; + recommendCommands(): this; // Alias of demand() @@ -220,9 +253,12 @@ declare module "yargs" { reset(): this; + scriptName(name: string): this; + showCompletionScript(): this; showHelp(consoleLevel?: "error" | "warn" | "log"): this; + showHelp(printCallback: (usageData: string) => void): this; showHelpOnFail(enable: boolean, message?: string): this; @@ -234,13 +270,15 @@ declare module "yargs" { string(key: string | Array): this; + terminalWidth(): number; + updateLocale(obj: { [key: string]: string }): this; updateStrings(obj: { [key: string]: string }): this; usage(message: string, opts?: { [key: string]: Options }): this; version(): this; - version(version: string): this; + version(version: string | false): this; version(option: string | (() => string), version: string): this; version( option: string | (() => string), diff --git a/package.json b/package.json index 31abc2f..14d5818 100644 --- a/package.json +++ b/package.json @@ -44,46 +44,48 @@ "url": "git+https://github.com/rpl/flow-coverage-report.git" }, "dependencies": { - "array.prototype.find": "2.0.4", - "babel-runtime": "6.23.0", - "@rpl/badge-up": "2.2.0", - "flow-annotation-check": "1.8.1", - "glob": "7.1.1", - "minimatch": "3.0.4", + "@babel/runtime": "^7.11.2", + "@rpl/badge-up": "^2.2.0", + "array.prototype.find": "^2.0.4", + "flow-annotation-check": "^1.8.1", + "glob": "^7.1.1", + "minimatch": "^3.0.4", "mkdirp": "^1.0.4", - "parse-json": "2.2.0", - "react": "15.5.4", - "react-dom": "15.5.4", - "strip-json-comments": "2.0.1", - "temp": "0.8.3", - "terminal-table": "0.0.12", - "yargs": "8.0.1" + "parse-json": "^5.1.0", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "strip-json-comments": "^3.1.1", + "temp": "^0.9.1", + "terminal-table": "^0.0.12", + "yargs": "^16.0.3" }, "devDependencies": { - "babel-cli": "6.24.1", - "babel-core": "6.24.1", - "babel-eslint": "7.2.3", - "babel-jest": "22.1.0", - "babel-plugin-istanbul": "4.1.3", - "babel-plugin-transform-flow-strip-types": "6.22.0", - "babel-plugin-transform-runtime": "6.23.0", - "babel-preset-es2015": "6.24.1", - "babel-preset-react": "6.24.1", - "babel-preset-stage-2": "6.24.1", - "cross-env": "5.0.0", - "eslint-config-xo-react": "0.12.0", - "eslint-plugin-flowtype": "2.33.0", - "eslint-plugin-jest": "20.0.2", - "eslint-plugin-react": "7.1.0", - "flow-bin": "0.72.0", - "flow-typed": "2.4.0", - "jest": "22.1.1", - "react-test-renderer": "15.5.4", - "rimraf": "2.6.2", - "svgson": "4.0.0", - "tempy": "0.2.1", - "xo": "0.18.1", - "yaml-jest": "1.0.5" + "@babel/cli": "^7.11.6", + "@babel/core": "^7.11.6", + "@babel/plugin-transform-runtime": "^7.11.5", + "@babel/preset-env": "^7.11.5", + "@babel/preset-flow": "^7.10.4", + "@babel/preset-react": "^7.10.4", + "babel-core": "^7.0.0-bridge.0", + "babel-eslint": "^10.1.0", + "babel-jest": "^22.1.0", + "babel-plugin-istanbul": "^6.0.0", + "cross-env": "^5.0.0", + "eslint": "^7.9.0", + "eslint-config-xo-react": "^0.23.0", + "eslint-plugin-flowtype": "^5.2.0", + "eslint-plugin-jest": "^24.0.1", + "eslint-plugin-react": "^7.20.6", + "eslint-plugin-react-hooks": "^4.1.2", + "flow-bin": "^0.72.0", + "flow-typed": "^2.4.0", + "jest": "^22.1.1", + "react-test-renderer": "^16.13.1", + "rimraf": "^2.6.2", + "svgson": "^4.0.0", + "tempy": "^0.2.1", + "xo": "^0.33.1", + "yaml-jest": "^1.0.5" }, "xo": { "extends": "xo-react", @@ -112,7 +114,8 @@ "flowtype/space-after-type-colon": [ 1, "always" - ] + ], + "unicorn/no-fn-reference-in-iterator": 0 }, "overrides": [ { @@ -132,19 +135,12 @@ "babel": { "compact": false, "presets": [ - "es2015", - "stage-2", - "react" + "@babel/env", + "@babel/react", + "@babel/flow" ], "plugins": [ - "transform-flow-strip-types", - [ - "transform-runtime", - { - "polyfill": false, - "regenerator": true - } - ] + "@babel/plugin-transform-runtime" ], "ignore": [ "assets/" diff --git a/src/__tests__/fixtures.js b/src/__tests__/fixtures.js index 0719241..d20efc9 100644 --- a/src/__tests__/fixtures.js +++ b/src/__tests__/fixtures.js @@ -35,7 +35,7 @@ const FLOW_COVERAGE_SUMMARY_DATA = { threshold: 40, percent: 50, globIncludePatterns: [firstGlob, secondGlob], - files: allFiles.reduce((acc, filename) => { + files: allFiles.reduce((acc, filename) => { // eslint-disable-line unicorn/no-reduce acc[filename] = { percent: 50, annotation: fakeTypeAnnotations[filename] || 'flow', diff --git a/src/__tests__/react-components/__snapshots__/test-body-coverage-sourcefile.js.snap b/src/__tests__/react-components/__snapshots__/test-body-coverage-sourcefile.js.snap index 1f37403..570bc9a 100644 --- a/src/__tests__/react-components/__snapshots__/test-body-coverage-sourcefile.js.snap +++ b/src/__tests__/react-components/__snapshots__/test-body-coverage-sourcefile.js.snap @@ -170,17 +170,21 @@ exports[` 1`] = ` > diff --git a/src/__tests__/react-components/__snapshots__/test-body-coverage-summary.js.snap b/src/__tests__/react-components/__snapshots__/test-body-coverage-summary.js.snap index 9cd3ce1..1d5d11c 100644 --- a/src/__tests__/react-components/__snapshots__/test-body-coverage-summary.js.snap +++ b/src/__tests__/react-components/__snapshots__/test-body-coverage-summary.js.snap @@ -310,17 +310,21 @@ exports[` 1`] = ` > @@ -638,17 +642,21 @@ exports[` 2`] = ` > diff --git a/src/__tests__/react-components/__snapshots__/test-footer.js.snap b/src/__tests__/react-components/__snapshots__/test-footer.js.snap index 1f236a1..f448731 100644 --- a/src/__tests__/react-components/__snapshots__/test-footer.js.snap +++ b/src/__tests__/react-components/__snapshots__/test-footer.js.snap @@ -3,17 +3,21 @@ exports[` 1`] = ` diff --git a/src/__tests__/react-components/__snapshots__/test-html-report-page.js.snap b/src/__tests__/react-components/__snapshots__/test-html-report-page.js.snap index d476fd0..7a1a444 100644 --- a/src/__tests__/react-components/__snapshots__/test-html-report-page.js.snap +++ b/src/__tests__/react-components/__snapshots__/test-html-report-page.js.snap @@ -316,17 +316,21 @@ exports[` 1`] = ` > diff --git a/src/__tests__/react-components/common.js b/src/__tests__/react-components/common.js index 128f9d9..e26bc94 100644 --- a/src/__tests__/react-components/common.js +++ b/src/__tests__/react-components/common.js @@ -1,3 +1,3 @@ 'use babel'; -export const BASE_DIR = '../../lib/components'; // eslint-disable-line import/prefer-default-export +export const BASE_DIR = '../../lib/components'; diff --git a/src/__tests__/react-components/test-body-coverage-sourcefile.js b/src/__tests__/react-components/test-body-coverage-sourcefile.js index d86cab8..2ac0447 100644 --- a/src/__tests__/react-components/test-body-coverage-sourcefile.js +++ b/src/__tests__/react-components/test-body-coverage-sourcefile.js @@ -1,7 +1,5 @@ 'use babel'; -/* eslint-disable react/jsx-filename-extension, import/no-dynamic-require */ - import React from 'react'; import renderer from 'react-test-renderer'; diff --git a/src/__tests__/react-components/test-body-coverage-summary.js b/src/__tests__/react-components/test-body-coverage-summary.js index 766a65d..4276229 100644 --- a/src/__tests__/react-components/test-body-coverage-summary.js +++ b/src/__tests__/react-components/test-body-coverage-summary.js @@ -1,7 +1,5 @@ 'use babel'; -/* eslint-disable react/jsx-filename-extension, import/no-dynamic-require */ - import React from 'react'; import renderer from 'react-test-renderer'; diff --git a/src/__tests__/react-components/test-coverage-file-table-head.js b/src/__tests__/react-components/test-coverage-file-table-head.js index 797c31f..3261c3b 100644 --- a/src/__tests__/react-components/test-coverage-file-table-head.js +++ b/src/__tests__/react-components/test-coverage-file-table-head.js @@ -1,7 +1,5 @@ 'use babel'; -/* eslint-disable react/jsx-filename-extension, import/no-dynamic-require */ - import React from 'react'; import renderer from 'react-test-renderer'; diff --git a/src/__tests__/react-components/test-coverage-file-table-row.js b/src/__tests__/react-components/test-coverage-file-table-row.js index fcd9c3c..2e9e9bf 100644 --- a/src/__tests__/react-components/test-coverage-file-table-row.js +++ b/src/__tests__/react-components/test-coverage-file-table-row.js @@ -1,7 +1,5 @@ 'use babel'; -/* eslint-disable react/jsx-filename-extension, import/no-dynamic-require */ - import React from 'react'; import renderer from 'react-test-renderer'; diff --git a/src/__tests__/react-components/test-coverage-meter-bar.js b/src/__tests__/react-components/test-coverage-meter-bar.js index 2311df4..13473d1 100644 --- a/src/__tests__/react-components/test-coverage-meter-bar.js +++ b/src/__tests__/react-components/test-coverage-meter-bar.js @@ -1,7 +1,5 @@ 'use babel'; -/* eslint-disable react/jsx-filename-extension, import/no-dynamic-require */ - import React from 'react'; import renderer from 'react-test-renderer'; diff --git a/src/__tests__/react-components/test-coverage-summary-table.js b/src/__tests__/react-components/test-coverage-summary-table.js index 08312c6..9eb76f3 100644 --- a/src/__tests__/react-components/test-coverage-summary-table.js +++ b/src/__tests__/react-components/test-coverage-summary-table.js @@ -1,7 +1,5 @@ 'use babel'; -/* eslint-disable react/jsx-filename-extension, import/no-dynamic-require */ - import React from 'react'; import renderer from 'react-test-renderer'; diff --git a/src/__tests__/react-components/test-footer.js b/src/__tests__/react-components/test-footer.js index 40ef299..28b4ff1 100644 --- a/src/__tests__/react-components/test-footer.js +++ b/src/__tests__/react-components/test-footer.js @@ -1,7 +1,5 @@ 'use babel'; -/* eslint-disable react/jsx-filename-extension, import/no-dynamic-require */ - import React from 'react'; import renderer from 'react-test-renderer'; diff --git a/src/__tests__/react-components/test-head.js b/src/__tests__/react-components/test-head.js index 239b145..29405a5 100644 --- a/src/__tests__/react-components/test-head.js +++ b/src/__tests__/react-components/test-head.js @@ -1,7 +1,5 @@ 'use babel'; -/* eslint-disable react/jsx-filename-extension, import/no-dynamic-require */ - import React from 'react'; import renderer from 'react-test-renderer'; diff --git a/src/__tests__/react-components/test-html-report-page.js b/src/__tests__/react-components/test-html-report-page.js index 4c3fe82..c3a26af 100644 --- a/src/__tests__/react-components/test-html-report-page.js +++ b/src/__tests__/react-components/test-html-report-page.js @@ -1,7 +1,5 @@ 'use babel'; -/* eslint-disable react/jsx-filename-extension, import/no-dynamic-require */ - import React from 'react'; import renderer from 'react-test-renderer'; @@ -12,7 +10,7 @@ import {BASE_DIR} from './common'; const REACT_COMPONENT = `${BASE_DIR}/html-report-page`; test('', () => { - const HTMLReportSummaryPage = require(REACT_COMPONENT).HTMLReportSummaryPage; + const {HTMLReportSummaryPage} = require(REACT_COMPONENT); const props = { coverageSummaryData: {...FLOW_COVERAGE_SUMMARY_DATA, threshold: 40} }; diff --git a/src/__tests__/test-flow.js b/src/__tests__/test-flow.js index 7d8ec77..baa7cdb 100644 --- a/src/__tests__/test-flow.js +++ b/src/__tests__/test-flow.js @@ -10,8 +10,8 @@ const LIB_PROMISIFIED = '../lib/promisified'; const NPM_FLOW_ANNOTATION_CHECK = 'flow-annotation-check'; const NPM_TEMP = 'temp'; -const tmpDirPath = '/tmp/fake-tmp-path'; -const tmpFilePath = `${tmpDirPath}/fake-tmp-file.json`; +const temporaryDirPath = '/tmp/fake-tmp-path'; +const temporaryFilePath = `${temporaryDirPath}/fake-tmp-file.json`; beforeEach(() => { jest.resetModules(); @@ -20,37 +20,38 @@ beforeEach(() => { it('checkFlowStatus does not catch arbitrary errors', async () => { const mockExec = jest.fn(); const mockWriteFile = jest.fn(); - const mockTempPath = jest.fn(); + const mockTemporaryPath = jest.fn(); jest.mock(NPM_TEMP, () => ({ - path: mockTempPath + path: mockTemporaryPath })); jest.mock(LIB_PROMISIFIED, () => ({ exec: mockExec, writeFile: mockWriteFile })); - mockTempPath.mockReturnValueOnce(tmpFilePath); + mockTemporaryPath.mockReturnValueOnce(temporaryFilePath); mockExec.mockReturnValueOnce(Promise.resolve({ err: new Error('Fake flow status error') })); const flow = require(LIB_FLOW); - expect(mockTempPath.mock.calls.length).toBe(0); + expect(mockTemporaryPath.mock.calls.length).toBe(0); let exception; try { - await flow.checkFlowStatus('flow', '/fake/projectDir/', tmpDirPath); - } catch (err) { - exception = err; + await flow.checkFlowStatus('flow', '/fake/projectDir/', temporaryDirPath); + } catch (error) { + exception = error; } + expect(exception && exception.message).toMatch( 'Fake flow status error' ); expect(mockExec.mock.calls.length).toBe(1); - expect(mockExec.mock.calls[0][0]).toBe(`flow status --json`); + expect(mockExec.mock.calls[0][0]).toBe('flow status --json'); expect(mockExec.mock.calls[0][1]).toEqual({ cwd: '/fake/projectDir/', maxBuffer: Infinity @@ -59,7 +60,7 @@ it('checkFlowStatus does not catch arbitrary errors', async () => { // No file should be created if the VERBOSE and // DEBUG_DUMP_JSON env var are not set - expect(mockTempPath.mock.calls.length).toBe(0); + expect(mockTemporaryPath.mock.calls.length).toBe(0); expect(mockWriteFile.mock.calls.length).toBe(0); }); @@ -68,10 +69,10 @@ it( async () => { const mockExec = jest.fn(); const mockWriteFile = jest.fn(); - const mockTempPath = jest.fn(); + const mockTemporaryPath = jest.fn(); jest.mock(NPM_TEMP, () => ({ - path: mockTempPath + path: mockTemporaryPath })); jest.mock(LIB_PROMISIFIED, () => ({ exec: mockExec, @@ -84,7 +85,7 @@ it( errors: [] }; - mockTempPath.mockReturnValueOnce(tmpFilePath); + mockTemporaryPath.mockReturnValueOnce(temporaryFilePath); mockExec.mockReturnValueOnce(Promise.resolve({ err: {code: 2}, stdout: JSON.stringify(fakeJSONStatusReply) @@ -93,16 +94,17 @@ it( const flow = require(LIB_FLOW); - const res = await flow.checkFlowStatus('flow', '/fake/projectDir/', tmpDirPath); + const result = await flow.checkFlowStatus('flow', '/fake/projectDir/', temporaryDirPath); - expect(res).toEqual(fakeJSONStatusReply); + expect(result).toEqual(fakeJSONStatusReply); let exception; try { - await flow.checkFlowStatus('flow', '/fake/projectDir/', tmpDirPath); - } catch (err) { - exception = err; + await flow.checkFlowStatus('flow', '/fake/projectDir/', temporaryDirPath); + } catch (error) { + exception = error; } + expect(exception && exception.message).toMatch( /Parsing error on Flow status JSON result: SyntaxError: Unexpected end/ ); @@ -113,10 +115,10 @@ it( 'checkFlowStatus rejects on invalid flow status json format', async () => { const mockExec = jest.fn(); - const mockTempPath = jest.fn(); + const mockTemporaryPath = jest.fn(); jest.mock(NPM_TEMP, () => ({ - path: mockTempPath + path: mockTemporaryPath })); jest.mock(LIB_PROMISIFIED, () => ({ exec: mockExec @@ -134,9 +136,10 @@ it( let exception; try { await flow.checkFlowStatus('flow', '/fake/projectDir/'); - } catch (err) { - exception = err; + } catch (error) { + exception = error; } + expect(exception && exception.message).toMatch( 'Invalid Flow status JSON format' ); @@ -147,11 +150,11 @@ it( 'collectFlowCoverageForFile collects flow command exit errors', async () => { const mockExec = jest.fn(); - const mockTempPath = jest.fn(); + const mockTemporaryPath = jest.fn(); const mockWriteFile = jest.fn(); jest.mock(NPM_TEMP, () => ({ - path: mockTempPath + path: mockTemporaryPath })); jest.mock(LIB_PROMISIFIED, () => ({ exec: mockExec, @@ -172,8 +175,8 @@ it( const filename = 'src/fakeFilename.js'; const collectData = await flow.collectFlowCoverageForFile( - {flowCommandPath: 'flow', projectDir: '/fake/projectDir/'}, filename, tmpDirPath - ); + {flowCommandPath: 'flow', projectDir: '/fake/projectDir/'}, filename, temporaryDirPath + ); // Expect a flow coverage exception in the collected data. expect(collectData.isError).toBe(true); @@ -195,11 +198,11 @@ it( it('collectFlowCoverageForFile collects parsing errors', async () => { const mockExec = jest.fn(); - const mockTempPath = jest.fn(); + const mockTemporaryPath = jest.fn(); const mockWriteFile = jest.fn(); jest.mock(NPM_TEMP, () => ({ - path: mockTempPath + path: mockTemporaryPath })); jest.mock(LIB_PROMISIFIED, () => ({ exec: mockExec, @@ -214,14 +217,14 @@ it('collectFlowCoverageForFile collects parsing errors', async () => { const filename = 'src/fakeFilename.js'; const collectData = await flow.collectFlowCoverageForFile( - {flowCommandPath: 'flow', projectDir: '/fake/projectDir/'}, filename, tmpDirPath - ); + {flowCommandPath: 'flow', projectDir: '/fake/projectDir/'}, filename, temporaryDirPath + ); let expectedParsingError; try { JSON.parse('{'); - } catch (err) { - expectedParsingError = err; + } catch (error) { + expectedParsingError = error; } // Expect a flow coverage exception in the collected data. @@ -243,11 +246,11 @@ it('collectFlowCoverageForFile collects parsing errors', async () => { it('collectFlowCoverageForFile collects coverage errors', async () => { const mockExec = jest.fn(); - const mockTempPath = jest.fn(); + const mockTemporaryPath = jest.fn(); const mockWriteFile = jest.fn(); jest.mock(NPM_TEMP, () => ({ - path: mockTempPath + path: mockTemporaryPath })); jest.mock(LIB_PROMISIFIED, () => ({ exec: mockExec, @@ -262,8 +265,8 @@ it('collectFlowCoverageForFile collects coverage errors', async () => { const filename = 'src/fakeFilename.js'; const collectData = await flow.collectFlowCoverageForFile( - {flowCommandPath: 'flow', projectDir: '/fake/projectDir/'}, filename, tmpDirPath - ); + {flowCommandPath: 'flow', projectDir: '/fake/projectDir/'}, filename, temporaryDirPath + ); // Expect a flow coverage exception in the collected data. expect(collectData.isError).toBe(true); @@ -285,11 +288,11 @@ it('collectFlowCoverageForFile collects coverage errors', async () => { it('collectFlowCoverageForFile resolve coverage data', async () => { const mockExec = jest.fn(); const mockWriteFile = jest.fn(); - const mockTempPath = jest.fn(); + const mockTemporaryPath = jest.fn(); const mockGenCheckFlowStatus = jest.fn(); jest.mock(NPM_TEMP, () => ({ - path: mockTempPath + path: mockTemporaryPath })); jest.mock(LIB_PROMISIFIED, () => ({ exec: mockExec, @@ -307,7 +310,7 @@ it('collectFlowCoverageForFile resolve coverage data', async () => { } }; - mockTempPath.mockReturnValueOnce(tmpFilePath); + mockTemporaryPath.mockReturnValueOnce(temporaryFilePath); mockExec.mockReturnValueOnce(Promise.resolve({ stdout: Buffer.from(JSON.stringify(fakeFlowCoverageData)) })); @@ -315,7 +318,7 @@ it('collectFlowCoverageForFile resolve coverage data', async () => { const flow = require(LIB_FLOW); - const res = await flow.collectFlowCoverageForFile( + const result = await flow.collectFlowCoverageForFile( {flowCommandPath: 'flow', flowCommandTimeout: DEFAULT_FLOW_TIMEOUT, projectDir: '/fake/projectDir'}, filename ); @@ -325,7 +328,7 @@ it('collectFlowCoverageForFile resolve coverage data', async () => { expect(mockExec.mock.calls[0][1]).toEqual({ cwd: '/fake/projectDir', maxBuffer: Infinity, timeout: DEFAULT_FLOW_TIMEOUT }); - expect(res).toEqual({ + expect(result).toEqual({ ...fakeFlowCoverageData, annotation: 'flow', isFlow: true @@ -337,12 +340,12 @@ const testCollectFlowCoverage = async ({ } = {}) => { const mockExec = jest.fn(); const mockWriteFile = jest.fn(); - const mockTempPath = jest.fn(); + const mockTemporaryPath = jest.fn(); const mockGlob = jest.fn(); const mockGenCheckFlowStatus = jest.fn(); jest.mock(NPM_TEMP, () => ({ - path: mockTempPath + path: mockTemporaryPath })); jest.mock(LIB_PROMISIFIED, () => ({ exec: mockExec, @@ -423,7 +426,7 @@ const testCollectFlowCoverage = async ({ 'test/**' ]; - const res = await flow.collectFlowCoverage({ + const result = await flow.collectFlowCoverage({ flowCommandPath: 'flow', flowCommandTimeout: DEFAULT_FLOW_TIMEOUT, projectDir: '/projectDir', @@ -435,17 +438,17 @@ const testCollectFlowCoverage = async ({ excludeNonFlow }, '/tmp/fakeTmpDir'); - expect(typeof res.generatedAt).toBe('string'); - delete res.generatedAt; + expect(typeof result.generatedAt).toBe('string'); + delete result.generatedAt; - const resFiles = res.files; - delete res.files; + const resultFiles = result.files; + delete result.files; const filteredFiles = allFiles.filter(file => { return !minimatch(file, globExcludePatterns[0]); }).sort(); - expect(res).toEqual({ + expect(result).toEqual({ flowStatus: {...fakeFlowStatus}, flowAnnotations: { passed: false, @@ -473,9 +476,9 @@ const testCollectFlowCoverage = async ({ const flowFilteredFiles = filteredFiles.filter(file => { return expectedFlowAnnotations[file] !== 'no flow'; }); - expect(Object.keys(resFiles).sort()).toEqual(flowFilteredFiles); + expect(Object.keys(resultFiles).sort()).toEqual(flowFilteredFiles); } else { - expect(Object.keys(resFiles).sort()).toEqual(filteredFiles); + expect(Object.keys(resultFiles).sort()).toEqual(filteredFiles); } for (const filename of filteredFiles) { @@ -483,7 +486,8 @@ const testCollectFlowCoverage = async ({ expectedFlowAnnotations[filename] === 'no flow') { continue; } - expect(resFiles[filename].expressions.uncovered_locs).toEqual([{ + + expect(resultFiles[filename].expressions.uncovered_locs).toEqual([{ start: { line: 1, column: 1, @@ -495,19 +499,19 @@ const testCollectFlowCoverage = async ({ offset: 30 } }]); - delete resFiles[filename].expressions.uncovered_locs; + delete resultFiles[filename].expressions.uncovered_locs; // Detect if the single file coverage is expected to be 0. const forceNoCoverage = !(!strictCoverage || [ 'flow', 'flow strict', 'flow strict-local' - ].indexOf(expectedFlowAnnotations[filename]) !== -1); + ].includes(expectedFlowAnnotations[filename])); if (excludeNonFlow && expectedFlowAnnotations[filename] === 'no flow') { - expect(resFiles[filename]).toEqual(undefined); + expect(resultFiles[filename]).toEqual(undefined); } else { - expect(resFiles[filename]).toEqual({ + expect(resultFiles[filename]).toEqual({ percent: forceNoCoverage ? 0 : 50, filename, annotation: expectedFlowAnnotations[filename], diff --git a/src/__tests__/test-index.js b/src/__tests__/test-index.js index dc56de8..4ff4c19 100644 --- a/src/__tests__/test-index.js +++ b/src/__tests__/test-index.js @@ -50,9 +50,9 @@ it('generateFlowCoverageReport', async () => { threshold: 80 }; - const res = await generateFlowCoverageReport(options); + const result = await generateFlowCoverageReport(options); - expect(res).toEqual([fakeData, options]); + expect(result).toEqual([fakeData, options]); expect(mockCollectFlowCoverage.mock.calls.length).toBe(1); expect(mockGenerateText.mock.calls.length).toBe(1); expect(mockGenerateHTML.mock.calls.length).toBe(0); @@ -89,9 +89,10 @@ it('generateFlowCoverageReport', async () => { try { await generateFlowCoverageReport({...options, projectDir: null}); - } catch (err) { - exception = err; + } catch (error) { + exception = error; } + expect(exception && exception.message).toMatch( /projectDir option is mandatory/ ); @@ -100,9 +101,10 @@ it('generateFlowCoverageReport', async () => { try { await generateFlowCoverageReport({...options, globIncludePatterns: null}); - } catch (err) { - exception2 = err; + } catch (error) { + exception2 = error; } + expect(exception2 && exception2.message).toMatch( /empty globIncludePatterns option/ ); @@ -110,9 +112,10 @@ it('generateFlowCoverageReport', async () => { let exception3; try { await generateFlowCoverageReport({...options, globIncludePatterns: []}); - } catch (err) { - exception3 = err; + } catch (error) { + exception3 = error; } + expect(exception3 && exception3.message).toMatch( /empty globIncludePatterns option/ ); diff --git a/src/__tests__/test-promisified-exec.js b/src/__tests__/test-promisified-exec.js index 5121ddc..8fbfe54 100644 --- a/src/__tests__/test-promisified-exec.js +++ b/src/__tests__/test-promisified-exec.js @@ -1,7 +1,5 @@ 'use babel'; -import {Buffer} from 'buffer'; - const LIB_PROMISIFIED = '../lib/promisified'; beforeEach(() => { @@ -48,9 +46,10 @@ test('promisified exec throws', async () => { let exception; try { await promisified.exec('fake-executable --fake', {cwd: '/fake/dir'}); - } catch (err) { - exception = err; + } catch (error) { + exception = error; } + expect({message: exception.message}).toMatchObject({message: mockErrorMessage}); }); diff --git a/src/__tests__/test-promisified-file.js b/src/__tests__/test-promisified-file.js index fafc0e3..d325eb7 100644 --- a/src/__tests__/test-promisified-file.js +++ b/src/__tests__/test-promisified-file.js @@ -34,9 +34,10 @@ it('promised readFile', async () => { try { await promisified.readFile('/my/fake/file'); - } catch (err) { - exception = err; + } catch (error) { + exception = error; } + expect(exception && exception.message).toMatch( 'Fake readFile error' ); @@ -60,8 +61,8 @@ it('promised writeFile', async () => { try { await promisified.writeFile('/my/fake/dir'); - } catch (err) { - exception = err; + } catch (error) { + exception = error; } expect(exception).toBe(undefined); @@ -74,8 +75,8 @@ it('promised writeFile', async () => { exception = undefined; try { await promisified.writeFile('/my/fake/file', 'Fake data'); - } catch (err) { - exception = err; + } catch (error) { + exception = error; } expect(`${exception}`).toMatch(/Fake writeFile error/); diff --git a/src/__tests__/test-promisified-glob.js b/src/__tests__/test-promisified-glob.js index ce14a5e..ad4291e 100644 --- a/src/__tests__/test-promisified-glob.js +++ b/src/__tests__/test-promisified-glob.js @@ -27,9 +27,10 @@ it('promisified glob', async () => { let exception; try { await promisified.glob('**/*.js', {}); - } catch (err) { - exception = err; + } catch (error) { + exception = error; } + expect(exception && exception.message).toMatch( 'Fake glob error' ); diff --git a/src/lib/cli/args.js b/src/lib/cli/args.js index 279b002..dd97963 100644 --- a/src/lib/cli/args.js +++ b/src/lib/cli/args.js @@ -37,13 +37,14 @@ export default function processArgv(argv: Array): any { // $FlowIgnoreMe: allow value to be coerced to a string. throw new TypeError(`Unexpected non-string value: ${value}`); } + return value.slice(0, 2) === './' ? path.resolve(value) : value; }, describe: `path to the flow executable (defaults to "${defaultConfig.flowCommandPath}")` }) .option('flow-command-timeout', { type: 'number', - describe: `maximum number of milliseconds to wait for a flow response (defaults to 15 seconds)` + describe: 'maximum number of milliseconds to wait for a flow response (defaults to 15 seconds)' }) // --type text .option('type', { diff --git a/src/lib/cli/config.js b/src/lib/cli/config.js index 785c165..08ecbf0 100644 --- a/src/lib/cli/config.js +++ b/src/lib/cli/config.js @@ -11,7 +11,7 @@ export type HTMLTemplateOptions = {| export type ReportType = 'json' | 'text' | 'badge' |'html'; -export type ConfigParams = {| +export type ConfigParameters = {| reportTypes?: Array, flowCommandPath: string, flowCommandTimeout: number, @@ -33,8 +33,8 @@ export type ConfigParams = {| type?: ?Array, |} -export type DefaultConfigParams = { - ...ConfigParams, +export type DefaultConfigParameters = { + ...ConfigParameters, reportTypes: Array, concurrentFiles: number, } @@ -51,7 +51,7 @@ const toArray = (value: any): Array => Array.isArray(value) ? value : [valu // Default timeout for flow coverage commands. export const DEFAULT_FLOW_TIMEOUT = 15 * 1000; -export const defaultConfig: DefaultConfigParams = { +export const defaultConfig: DefaultConfigParameters = { reportTypes: ['text'], flowCommandPath: 'flow', flowCommandTimeout: DEFAULT_FLOW_TIMEOUT, @@ -91,7 +91,7 @@ const getProjectDir = (config: Object): string => { * * @param {object} config */ -function normalizedConfig(config: ConfigParams): ConfigParams { +function normalizedConfig(config: ConfigParameters): ConfigParameters { if (typeof config.includeGlob !== 'undefined') { console.warn('WARN: "includeGlob" config file property has been renamed to "globIncludePatterns"'); config.globIncludePatterns = toArray(config.includeGlob); @@ -161,7 +161,7 @@ export function loadConfig(args: Object): Object { try { packageJSONPath = path.resolve(path.join(getProjectDir(args), 'package.json')); // $FlowIgnoreMe: the following dynamic require loads only the package.json file. - const pkg = require(packageJSONPath); // eslint-disable-line import/no-dynamic-require + const pkg = require(packageJSONPath); if (pkg['flow-coverage-report']) { if (process.env.VERBOSE) { console.log('Loaded config from package.json', pkg['flow-coverage-report']); @@ -173,9 +173,9 @@ export function loadConfig(args: Object): Object { ...args }; } - } catch (err) { + } catch (error) { if (process.env.VERBOSE) { - console.error('Unable to load config from project package.json', packageJSONPath, err); + console.error('Unable to load config from project package.json', packageJSONPath, error); } } @@ -195,9 +195,9 @@ export function loadConfig(args: Object): Object { ...normalizedConfig(projectConfigData), ...args }; - } catch (err) { + } catch (error) { if (process.env.VERBOSE) { - console.error('Unable to load config from file', projectConfigPath, err); + console.error('Unable to load config from file', projectConfigPath, error); } } @@ -214,9 +214,9 @@ export function loadConfig(args: Object): Object { */ export function validateConfig(args: Object): Object { - function raiseErrorIfArray(value, msg) { + function raiseErrorIfArray(value, message) { if (Array.isArray(value)) { - throw new UsageError(`ERROR: Only one ${msg} can be specified.`); + throw new UsageError(`ERROR: Only one ${message} can be specified.`); } } @@ -229,8 +229,8 @@ export function validateConfig(args: Object): Object { }; for (const option of Object.keys(preventDuplicatedOptions)) { - const msg = preventDuplicatedOptions[option]; - raiseErrorIfArray(args[option], msg); + const message = preventDuplicatedOptions[option]; + raiseErrorIfArray(args[option], message); } const {globIncludePatterns} = args; diff --git a/src/lib/cli/index.js b/src/lib/cli/index.js index 5270e0b..0271b71 100644 --- a/src/lib/cli/index.js +++ b/src/lib/cli/index.js @@ -4,22 +4,24 @@ import generateFlowCoverageReport from '../../lib'; import processArgv from './args'; import {loadConfig, validateConfig, UsageError} from './config'; -exports.run = () => { +exports.run = async () => { let args = processArgv(process.argv); try { args = loadConfig(args); validateConfig(args); - } catch (err) { - if (err instanceof UsageError) { - console.error('Configuration error:', err.message); + } catch (error) { + if (error instanceof UsageError) { + console.error('Configuration error:', error.message); } else { - console.error('Unexpected exception: ' + err + ' ' + err.stack); + console.error('Unexpected exception: ' + error + ' ' + error.stack); } + process.exit(255); // eslint-disable-line unicorn/no-process-exit } - generateFlowCoverageReport({...args}).then(([coverageSummaryData]) => { + try { + const [coverageSummaryData] = await generateFlowCoverageReport({...args}); const {percent, threshold} = coverageSummaryData; if (percent < threshold) { console.error( @@ -27,8 +29,8 @@ exports.run = () => { ); process.exit(2); // eslint-disable-line unicorn/no-process-exit } - }).catch(err => { - console.error('Error while generating Flow Coverage Report: ' + err + ' ' + err.stack); + } catch (error) { + console.error('Error while generating Flow Coverage Report: ' + error + ' ' + error.stack); process.exit(255); // eslint-disable-line unicorn/no-process-exit - }); + } }; diff --git a/src/lib/components/body-coverage-sourcefile.jsx b/src/lib/components/body-coverage-sourcefile.jsx index ae44a9e..62ab65e 100644 --- a/src/lib/components/body-coverage-sourcefile.jsx +++ b/src/lib/components/body-coverage-sourcefile.jsx @@ -1,10 +1,8 @@ 'use strict'; - // @flow import React from 'react'; -/* eslint-disable import/no-unresolved */ import HTMLReportFooter from './footer'; import FlowCoverageFileTableHead from './coverage-file-table-head'; import FlowCoverageFileTableRow from './coverage-file-table-row'; @@ -14,10 +12,9 @@ import type { FlowCoverageSourceFileReportProps, FlowUncoveredLocsProps } from './html-report-page'; -/* eslint-enable */ -function FlowCoverageLocsForm(props: FlowUncoveredLocsProps) { - const uncovered_locs = props.uncovered_locs; // eslint-disable-line camelcase +const FlowCoverageLocsForm = (props: FlowUncoveredLocsProps) => { + const {uncovered_locs} = props; // eslint-disable-line camelcase return (
@@ -56,9 +53,9 @@ function FlowCoverageLocsForm(props: FlowUncoveredLocsProps) {
); -} +}; -export default function HTMLReportBodySourceFile(props: FlowCoverageSourceFileReportProps) { +const HTMLReportBodySourceFile = (props: FlowCoverageSourceFileReportProps) => { const {fileName, fileContent} = props; if (!fileName) { throw new Error('Missing fileName in props'); @@ -68,9 +65,10 @@ export default function HTMLReportBodySourceFile(props: FlowCoverageSourceFileRe if (!coverageData || !coverageSummaryData) { throw new Error('Missing coverage data props'); } + const {percent} = coverageData; - const threshold = coverageSummaryData.threshold; + const {threshold} = coverageSummaryData; if (!threshold) { throw new Error('Missing threshold in coverageSummaryData'); @@ -122,21 +120,19 @@ export default function HTMLReportBodySourceFile(props: FlowCoverageSourceFileRe uncovered_count /* eslint-enable camelcase */ }} - /> + /> - { - meterBar - } + {meterBar}
+ {/* eslint-disable camelcase */} + uncovered_locs={uncovered_locs} + /> + {/* eslint-enable */}