Repository: okonet/lint-staged (js)

Issue:
Possible false positive in the config validation 
Following config

```json
  "lint-staged": {
    "linters": {
      "*.js": [
        "npm run lint:js -- --fix",
        "git add"
      ],
      "*.json": [
        "npm run lint:js -- --fix",
        "git add"
      ],
      "*.md": [
        "npm run lint:md -- -o",
        "git add"
      ]
    },
    "verbose": true,
    "concurrent": false
  },
```

causes the following error when running lint-staged:

```
Running lint-staged with the following config:
{
	linters: {
		'*.js': [
			'npm run lint:js -- --fix',
			'git add'
		],
		'*.json': [
			'npm run lint:js -- --fix',
			'git add'
		],
		'*.md': [
			'npm run lint:md -- -o',
			'git add'
		]
	},
	verbose: true,
	concurrent: false,
	chunkSize: 9007199254740991,
	gitDir: '.',
	globOptions: {
		matchBase: true,
		dot: true
	},
	subTaskConcurrency: 1,
	renderer: 'verbose'
}

Could not parse lint-staged config.
Make sure you have created it. See https://github.com/okonet/lint-staged#readme.

Error: Invalid config provided to runAll! Use getConfig instead.


husky > pre-commit hook failed (add --no-verify to bypass)
```

Then config is changed to following error disappears:

```json
  "lint-staged": {
    "linters": {
      "*.js": [
        "npm run lint:js -- --fix",
        "git add"
      ],
      "*.json": [
        "npm run lint:js -- --fix",
        "git add"
      ],
      "*.md": [
        "npm run lint:md -- -o",
        "git add"
      ]
    },
    "verbose": true
  },
```


Pull request:
fix: Use lodash `has` to check config keys presence
Closes #263

Patch:
diff --git a/src/runAll.js b/src/runAll.js
index a9f331e..fe31afa 100644
--- a/src/runAll.js
+++ b/src/runAll.js
@@ -2,6 +2,7 @@
 
 const sgf = require('staged-git-files')
 const Listr = require('listr')
+const has = require('lodash/has')
 const runScript = require('./runScript')
 const generateTasks = require('./generateTasks')
 const resolveGitDir = require('./resolveGitDir')
@@ -9,12 +10,12 @@ const resolveGitDir = require('./resolveGitDir')
 /**
  * Executes all tasks and either resolves or rejects the promise
  * @param packageJson
- * @param config
+ * @param config {Object}
  * @returns {Promise}
  */
 module.exports = function runAll(packageJson, config) {
   // Config validation
-  if (!config || !config.gitDir || !config.concurrent || !config.renderer) {
+  if (!config || !has(config, 'gitDir') || !has(config, 'concurrent') || !has(config, 'renderer')) {
     throw new Error('Invalid config provided to runAll! Use getConfig instead.')
   }
 


Test patch:
diff --git a/test/runAll.spec.js b/test/runAll.spec.js
index 74be6d6..534ecaf 100644
--- a/test/runAll.spec.js
+++ b/test/runAll.spec.js
@@ -15,6 +15,13 @@ describe('runAll', () => {
     expect(() => runAll(packageJson)).toThrowErrorMatchingSnapshot()
   })
 
+  it('should not throw when a valid config is provided', () => {
+    const config = getConfig({
+      concurrent: false
+    })
+    expect(() => runAll(packageJson, config)).not.toThrow()
+  })
+
   it('should return a promise', () => {
     expect(runAll(packageJson, getConfig({}))).toBeInstanceOf(Promise)
   })