From e81ed5dd9ef5dac1a1f2f6dc26a07abb6c05d709 Mon Sep 17 00:00:00 2001 From: "Benjamin E. Coe" Date: Thu, 30 Dec 2021 15:25:01 +0000 Subject: [PATCH] fix(config): support configuration inheritance (#343) --- lib/parse-args.js | 6 ++- test/fixtures/config/.c8rc-base.json | 4 ++ test/fixtures/config/.c8rc.json | 3 +- test/integration.js_10.snap | 66 ++++++++-------------------- test/parse-args.js | 6 +++ 5 files changed, 35 insertions(+), 50 deletions(-) create mode 100644 test/fixtures/config/.c8rc-base.json diff --git a/lib/parse-args.js b/lib/parse-args.js index 9e5ceade..0266923a 100644 --- a/lib/parse-args.js +++ b/lib/parse-args.js @@ -3,6 +3,7 @@ const defaultExtension = require('@istanbuljs/schema/default-extension') const findUp = require('find-up') const { readFileSync } = require('fs') const Yargs = require('yargs/yargs') +const { applyExtends } = require('yargs/helpers') const parser = require('yargs-parser') const { resolve } = require('path') @@ -13,7 +14,10 @@ function buildYargs (withCommands = false) { alias: 'c', config: true, describe: 'path to JSON configuration file', - configParser: (path) => JSON.parse(readFileSync(path)), + configParser: (path) => { + const config = JSON.parse(readFileSync(path)) + return applyExtends(config, process.cwd(), true) + }, default: () => findUp.sync(['.c8rc', '.c8rc.json', '.nycrc', '.nycrc.json']) }) .option('reporter', { diff --git a/test/fixtures/config/.c8rc-base.json b/test/fixtures/config/.c8rc-base.json new file mode 100644 index 00000000..d314f753 --- /dev/null +++ b/test/fixtures/config/.c8rc-base.json @@ -0,0 +1,4 @@ +{ + "extends": "./test/fixtures/config/.c8rc.json", + "branches": 55 +} diff --git a/test/fixtures/config/.c8rc.json b/test/fixtures/config/.c8rc.json index 1d481b7f..7676378b 100644 --- a/test/fixtures/config/.c8rc.json +++ b/test/fixtures/config/.c8rc.json @@ -1,4 +1,5 @@ { "temp-directory": "./foo", - "lines": 101 + "lines": 101, + "functions": 24 } diff --git a/test/integration.js_10.snap b/test/integration.js_10.snap index 5e69d488..07c4afb0 100644 --- a/test/integration.js_10.snap +++ b/test/integration.js_10.snap @@ -144,21 +144,6 @@ All files | 83.33 | 85.71 | 66.66 | 83.33 | ," `; -exports[`c8 ESM Modules collects coverage for ESM modules 1`] = ` -",----------|---------|----------|---------|---------|------------------- -File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s -----------|---------|----------|---------|---------|------------------- -All files | 0 | 0 | 0 | 0 | -----------|---------|----------|---------|---------|------------------- -,Error [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension: /Users/bencoe/oss/c8/test/fixtures/export.cjs - at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:93:13) - at Loader.resolve (internal/modules/esm/loader.js:58:33) - at Loader.getModuleJob (internal/modules/esm/loader.js:113:40) - at ModuleWrap.promises.module.link (internal/modules/esm/module_job.js:32:40) - at link (internal/modules/esm/module_job.js:31:36) -" -`; - exports[`c8 check-coverage --100 1`] = ` ",hey i am a line of code @@ -194,12 +179,12 @@ hey --------------------------|---------|----------|---------|---------|-------------------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s --------------------------|---------|----------|---------|---------|-------------------------------- -All files | 73.6 | 59.03 | 62.5 | 73.6 | +All files | 73.72 | 59.03 | 62.5 | 73.72 | bin | 78.84 | 60 | 66.66 | 78.84 | c8.js | 78.84 | 60 | 66.66 | 78.84 | 22,27-29,32-33,41-43,50-51 - lib | 78.19 | 54.38 | 72 | 78.19 | + lib | 78.32 | 54.38 | 72 | 78.32 | is-cjs-esm-bridge.js | 90 | 25 | 100 | 90 | 9 - parse-args.js | 97.19 | 58.33 | 100 | 97.19 | 155-156,177-178,191-192 + parse-args.js | 97.24 | 58.33 | 100 | 97.24 | 159-160,181-182,195-196 report.js | 75.47 | 58.33 | 78.57 | 75.47 | ...251,278-279,285-287,308-313 source-map-from-file.js | 45 | 100 | 0 | 45 | 39-50,52-67,69-77,81-98 lib/commands | 41.44 | 66.66 | 16.66 | 41.44 | @@ -209,9 +194,9 @@ All files | 73.6 | 59.03 | 62.5 | 73.6 | async.js | 100 | 100 | 100 | 100 | normal.js | 75 | 66.66 | 33.33 | 75 | 14-16,18-20 --------------------------|---------|----------|---------|---------|-------------------------------- -,ERROR: Coverage for lines (73.6%) does not meet global threshold (101%) +,ERROR: Coverage for lines (73.72%) does not meet global threshold (101%) ERROR: Coverage for branches (59.03%) does not meet global threshold (82%) -ERROR: Coverage for statements (73.6%) does not meet global threshold (95%) +ERROR: Coverage for statements (73.72%) does not meet global threshold (95%) " `; @@ -227,7 +212,7 @@ ERROR: Coverage for statements (80.48%) does not meet threshold (95%) for lib/co ERROR: Coverage for lines (90%) does not meet threshold (101%) for lib/is-cjs-esm-bridge.js ERROR: Coverage for branches (25%) does not meet threshold (82%) for lib/is-cjs-esm-bridge.js ERROR: Coverage for statements (90%) does not meet threshold (95%) for lib/is-cjs-esm-bridge.js -ERROR: Coverage for lines (97.19%) does not meet threshold (101%) for lib/parse-args.js +ERROR: Coverage for lines (97.24%) does not meet threshold (101%) for lib/parse-args.js ERROR: Coverage for branches (58.33%) does not meet threshold (82%) for lib/parse-args.js ERROR: Coverage for lines (75.47%) does not meet threshold (101%) for lib/report.js ERROR: Coverage for branches (58.33%) does not meet threshold (82%) for lib/report.js @@ -242,19 +227,19 @@ ERROR: Coverage for statements (75%) does not meet threshold (95%) for test/fixt `; exports[`c8 check-coverage check-coverage command with --100 1`] = ` -",,ERROR: Coverage for lines (77.4%) does not meet global threshold (100%) +",,ERROR: Coverage for lines (77.51%) does not meet global threshold (100%) ERROR: Coverage for functions (66.66%) does not meet global threshold (100%) ERROR: Coverage for branches (62.35%) does not meet global threshold (100%) -ERROR: Coverage for statements (77.4%) does not meet global threshold (100%) +ERROR: Coverage for statements (77.51%) does not meet global threshold (100%) " `; exports[`c8 check-coverage exits with 0 if coverage within threshold 1`] = `",,"`; exports[`c8 check-coverage exits with 1 if coverage is below threshold 1`] = ` -",,ERROR: Coverage for lines (73.6%) does not meet global threshold (101%) +",,ERROR: Coverage for lines (73.72%) does not meet global threshold (101%) ERROR: Coverage for branches (59.03%) does not meet global threshold (82%) -ERROR: Coverage for statements (73.6%) does not meet global threshold (95%) +ERROR: Coverage for statements (73.72%) does not meet global threshold (95%) " `; @@ -337,12 +322,12 @@ exports[`c8 report generates report from existing temporary files 1`] = ` ",--------------------------|---------|----------|---------|---------|-------------------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s --------------------------|---------|----------|---------|---------|-------------------------------- -All files | 73.6 | 59.03 | 62.5 | 73.6 | +All files | 73.72 | 59.03 | 62.5 | 73.72 | bin | 78.84 | 60 | 66.66 | 78.84 | c8.js | 78.84 | 60 | 66.66 | 78.84 | 22,27-29,32-33,41-43,50-51 - lib | 78.19 | 54.38 | 72 | 78.19 | + lib | 78.32 | 54.38 | 72 | 78.32 | is-cjs-esm-bridge.js | 90 | 25 | 100 | 90 | 9 - parse-args.js | 97.19 | 58.33 | 100 | 97.19 | 155-156,177-178,191-192 + parse-args.js | 97.24 | 58.33 | 100 | 97.24 | 159-160,181-182,195-196 report.js | 75.47 | 58.33 | 78.57 | 75.47 | ...251,278-279,285-287,308-313 source-map-from-file.js | 45 | 100 | 0 | 45 | 39-50,52-67,69-77,81-98 lib/commands | 41.44 | 66.66 | 16.66 | 41.44 | @@ -359,12 +344,12 @@ exports[`c8 report supports --check-coverage, when generating reports 1`] = ` ",--------------------------|---------|----------|---------|---------|-------------------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s --------------------------|---------|----------|---------|---------|-------------------------------- -All files | 73.6 | 59.03 | 62.5 | 73.6 | +All files | 73.72 | 59.03 | 62.5 | 73.72 | bin | 78.84 | 60 | 66.66 | 78.84 | c8.js | 78.84 | 60 | 66.66 | 78.84 | 22,27-29,32-33,41-43,50-51 - lib | 78.19 | 54.38 | 72 | 78.19 | + lib | 78.32 | 54.38 | 72 | 78.32 | is-cjs-esm-bridge.js | 90 | 25 | 100 | 90 | 9 - parse-args.js | 97.19 | 58.33 | 100 | 97.19 | 155-156,177-178,191-192 + parse-args.js | 97.24 | 58.33 | 100 | 97.24 | 159-160,181-182,195-196 report.js | 75.47 | 58.33 | 78.57 | 75.47 | ...251,278-279,285-287,308-313 source-map-from-file.js | 45 | 100 | 0 | 45 | 39-50,52-67,69-77,81-98 lib/commands | 41.44 | 66.66 | 16.66 | 41.44 | @@ -374,9 +359,9 @@ All files | 73.6 | 59.03 | 62.5 | 73.6 | async.js | 100 | 100 | 100 | 100 | normal.js | 75 | 66.66 | 33.33 | 75 | 14-16,18-20 --------------------------|---------|----------|---------|---------|-------------------------------- -,ERROR: Coverage for lines (73.6%) does not meet global threshold (101%) +,ERROR: Coverage for lines (73.72%) does not meet global threshold (101%) ERROR: Coverage for branches (59.03%) does not meet global threshold (82%) -ERROR: Coverage for statements (73.6%) does not meet global threshold (95%) +ERROR: Coverage for statements (73.72%) does not meet global threshold (95%) " `; @@ -612,18 +597,3 @@ All files | 83.33 | 85.71 | 66.66 | 83.33 | -----------|---------|----------|---------|---------|------------------- ," `; - -exports[`c8 ts-node reads source-map from cache, and applies to coverage 1`] = ` -",covered -covered -covered -covered -covered -------------------|---------|----------|---------|---------|------------------- -File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s -------------------|---------|----------|---------|---------|------------------- -All files | 79.41 | 85.71 | 66.67 | 79.41 | - ts-node-basic.ts | 79.41 | 85.71 | 66.67 | 79.41 | 15-17,29-32 -------------------|---------|----------|---------|---------|------------------- -," -`; diff --git a/test/parse-args.js b/test/parse-args.js index 57271a05..ab8f4d99 100644 --- a/test/parse-args.js +++ b/test/parse-args.js @@ -57,5 +57,11 @@ describe('parse-args', () => { const argv = buildYargs().parse(['node', 'c8', '--lines', '100', '--config', require.resolve('./fixtures/config/.c8rc.json')]) argv.lines.should.be.equal(100) }) + it('should allow config files to extend each other', () => { + const argv = buildYargs().parse(['node', 'c8', '--lines', '100', '--config', require.resolve('./fixtures/config/.c8rc-base.json')]) + argv.branches.should.be.equal(55) + argv.lines.should.be.equal(100) + argv.functions.should.be.equal(24) + }) }) })