6

I'm trying to run tests on the staged files in a pre-commit hook with jest. So far, so good. Got it working with the pre-commit and lint-staged NPM packages.

Snippet from the package.json:

{
  // ...
  "scripts": {
    "hook": "lint-staged",
    // ...
  },
  "devDependencies": {
    "eslint": "^4.12.1",
    "eslint-config-airbnb-base": "^12.1.0",
    "eslint-config-prettier": "^2.9.0",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-prettier": "^2.3.1",
    "jest": "^22.0.3",
    "jest-junit": "^3.4.0",
    "lint-staged": "^6.0.1",
    "pre-commit": "^1.2.2",
    "prettier": "^1.9.1"
  },
  "jest": {
    "collectCoverageFrom": ["src/**/*.js"],
    "coveragePathIgnorePatterns": ["<rootDir>/src/models/"],
    "coverageThreshold": {
      "global": {
        "branches": 80,
        "functions": 80,
        "lines": 80,
        "statements": 80
      }
    }
  },
  "pre-commit": ["hook"],
  "lint-staged": {
    "*.js": ["eslint --fix", "git add", "jest --bail --passWithNoTests --coverage"]
  },
  // ...
}

There is more in there but I think these are the important parts.

The problem I'm having is that if I stage files that don't have any tests or are ignored b/c of the "coveragePathIgnorePatterns": ["<rootDir>/src/models/"], jest exits with 1 - so no commit. Found a way around that by adding --passWithNoTests. Great. But now I also want to check the coverage - and this also fails when there are no tests (and therefore no coverage data):

----------|----------|----------|----------|----------|----------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
----------|----------|----------|----------|----------|----------------|
All files |  Unknown |  Unknown |  Unknown |  Unknown |                |
----------|----------|----------|----------|----------|----------------|

            Jest: Coverage data for global was not found.

Is there another flag I could use to also ignore this for the coverage (like --passWithNoTests for the actual tests)? Or does someone have better idea how to do this?

Or should I skip coverage for these pre-commit tests?

Philipp Kyeck
  • 18,402
  • 15
  • 86
  • 123
  • Run all the tests ? Not sure you can make your threasholds relative to the staged files anyway. – Gabriel Bleu Jan 19 '18 at 17:00
  • @GabrielBleu I thought about stashing and then running all the test. But then found an article mentioning the `lint-staged` that can handle the staged files ... maybe that is just too complicated. Running all test and include the changed but not staged files could give you a wrong result - where it should mirror the exact tests that would run on CI after the push. – Philipp Kyeck Jan 20 '18 at 07:18

1 Answers1

0

You can break it down using husky and lint-staged, as shown below:

 "lint-staged": {
    "src/**/*.(spec|test).ts": [
      "npm run test"
    ],
    "src/**/*.{ts,vue}": [
      "eslint --fix",
      "prettier --write"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },

This way, if there's no staged file in the test directory it just skips the test and goes to the next item which is eslint --fix and prettier --write

Chukwuma Nwaugha
  • 575
  • 8
  • 17