From d8fad78b96fb704fdd765d0dbd74770554a07913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Mon, 5 Aug 2019 19:46:57 +0300 Subject: [PATCH] fix: validateConfig validates function task return values --- src/validateConfig.js | 43 +++++++++++++------ .../__snapshots__/validateConfig.spec.js.snap | 16 ++++++- test/validateConfig.spec.js | 17 +++++++- 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/validateConfig.js b/src/validateConfig.js index 795199c24..0c5b8db68 100644 --- a/src/validateConfig.js +++ b/src/validateConfig.js @@ -46,40 +46,55 @@ module.exports = function validateConfig(config) { if (!config || typeof config !== 'object') { errors.push('Configuration should be an object!') } else { - const globs = Object.keys(config) + const entries = Object.entries(config) - if (globs.length === 0) { + if (entries.length === 0) { errors.push('Configuration should not be empty!') } - globs.forEach(key => { - if (TEST_DEPRECATED_KEYS.has(key)) { - const testFn = TEST_DEPRECATED_KEYS.get(key) - if (testFn(config[key])) { + entries.forEach(([pattern, task]) => { + if (TEST_DEPRECATED_KEYS.has(pattern)) { + const testFn = TEST_DEPRECATED_KEYS.get(pattern) + if (testFn(task)) { errors.push( createError( - key, + pattern, 'Advanced configuration has been deprecated. For more info, please visit: https://github.com/okonet/lint-staged', - config[key] + task ) ) } } if ( - (!Array.isArray(config[key]) || - config[key].some(item => typeof item !== 'string' && typeof item !== 'function')) && - typeof config[key] !== 'string' && - typeof config[key] !== 'function' + (!Array.isArray(task) || + task.some(item => typeof item !== 'string' && typeof item !== 'function')) && + typeof task !== 'string' && + typeof task !== 'function' ) { errors.push( createError( - key, + pattern, 'Should be a string, a function, or an array of strings and functions', - config[key] + task ) ) } + + entries.forEach(([, task]) => { + if (typeof task !== 'function') return + const resolved = task(['[filename]']) + if (typeof resolved === 'string') return + if (!Array.isArray(resolved) || resolved.some(subtask => typeof subtask !== 'string')) { + errors.push( + createError( + task, + 'Function task should return a string or an array of strings', + resolved + ) + ) + } + }) }) } diff --git a/test/__snapshots__/validateConfig.spec.js.snap b/test/__snapshots__/validateConfig.spec.js.snap index 3026e73f7..fe5213fd6 100644 --- a/test/__snapshots__/validateConfig.spec.js.snap +++ b/test/__snapshots__/validateConfig.spec.js.snap @@ -1,9 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`validateConfig should not throw and should print nothing for function linter 1`] = `""`; +exports[`validateConfig should not throw and should print nothing for function task 1`] = `""`; exports[`validateConfig should not throw and should print nothing for valid config 1`] = `""`; +exports[`validateConfig should not throw when config contains deprecated key but with valid task 1`] = `""`; + exports[`validateConfig should throw and should print validation errors for invalid config 1`] = ` "● Validation Error: @@ -148,3 +150,15 @@ Please refer to https://github.com/okonet/lint-staged#configuration for more inf `; exports[`validateConfig should throw when detecting deprecated advanced configuration 2`] = `""`; + +exports[`validateConfig should throw when function task returns incorrect values 1`] = ` +"● Validation Error: + + Invalid value for 'filenames => filenames.map(file => [\`eslint --fix \${file}\`, \`git add \${file}\`])'. + + Function task should return a string or an array of strings. + + Configured value is: [['eslint --fix [filename]', 'git add [filename]']] + +Please refer to https://github.com/okonet/lint-staged#configuration for more information..." +`; diff --git a/test/validateConfig.spec.js b/test/validateConfig.spec.js index 992f9e09e..c1949ea27 100644 --- a/test/validateConfig.spec.js +++ b/test/validateConfig.spec.js @@ -36,7 +36,7 @@ describe('validateConfig', () => { expect(console.printHistory()).toMatchSnapshot() }) - it('should not throw and should print nothing for function linter', () => { + it('should not throw and should print nothing for function task', () => { expect(() => validateConfig({ '*.js': filenames => { @@ -49,6 +49,13 @@ describe('validateConfig', () => { expect(console.printHistory()).toMatchSnapshot() }) + it('should throw when function task returns incorrect values', () => { + const invalidConfig = { + '*.js': filenames => filenames.map(file => [`eslint --fix ${file}`, `git add ${file}`]) + } + expect(() => validateConfig(invalidConfig)).toThrowErrorMatchingSnapshot() + }) + it('should throw when detecting deprecated advanced configuration', () => { const advancedConfig = { chunkSize: 10, @@ -66,4 +73,12 @@ describe('validateConfig', () => { expect(() => validateConfig(advancedConfig)).toThrowErrorMatchingSnapshot() expect(console.printHistory()).toMatchSnapshot() }) + + it('should not throw when config contains deprecated key but with valid task', () => { + const stillValidConfig = { + concurrent: 'my command' + } + expect(() => validateConfig(stillValidConfig)).not.toThrow() + expect(console.printHistory()).toMatchSnapshot() + }) })