Coder Social home page Coder Social logo

eslint-plugin-jest's Introduction

eslint-plugin-jest

ESLint plugin for Jest

Actions Status

Installation

yarn add --dev eslint eslint-plugin-jest

Note: If you installed ESLint globally then you must also install eslint-plugin-jest globally.

Usage

Note

eslint.config.js is supported, though most of the plugin documentation still currently uses .eslintrc syntax.

Refer to the ESLint documentation on the new configuration file format for more.

Add jest to the plugins section of your .eslintrc configuration file. You can omit the eslint-plugin- prefix:

{
  "plugins": ["jest"]
}

Then configure the rules you want to use under the rules section.

{
  "rules": {
    "jest/no-disabled-tests": "warn",
    "jest/no-focused-tests": "error",
    "jest/no-identical-title": "error",
    "jest/prefer-to-have-length": "warn",
    "jest/valid-expect": "error"
  }
}

You can also tell ESLint about the environment variables provided by Jest by doing:

{
  "env": {
    "jest/globals": true
  }
}

This is included in all configs shared by this plugin, so can be omitted if extending them.

Aliased Jest globals

You can tell this plugin about any global Jests you have aliased using the globalAliases setting:

{
  "settings": {
    "jest": {
      "globalAliases": {
        "describe": ["context"],
        "fdescribe": ["fcontext"],
        "xdescribe": ["xcontext"]
      }
    }
  }
}

Aliased @jest/globals

You can tell this plugin to treat a different package as the source of Jest globals using the globalPackage setting:

{
  "settings": {
    "jest": {
      "globalPackage": "bun:test"
    }
  }
}

Warning

While this can be used to apply rules when using alternative testing libraries and frameworks like bun, vitest and node, there's no guarantee the semantics this plugin assumes will hold outside of Jest

Running rules only on test-related files

The rules provided by this plugin assume that the files they are checking are test-related. This means it's generally not suitable to include them in your top-level configuration as that applies to all files being linted which can include source files.

For .eslintrc configs you can use overrides to have ESLint apply additional rules to specific files:

{
  "extends": ["eslint:recommended"],
  "overrides": [
    {
      "files": ["test/**"],
      "plugins": ["jest"],
      "extends": ["plugin:jest/recommended"],
      "rules": { "jest/prefer-expect-assertions": "off" }
    }
  ],
  "rules": {
    "indent": ["error", 2]
  }
}

For eslint.config.js you can use files and ignores:

const jest = require('eslint-plugin-jest');

module.exports = [
  ...require('@eslint/js').configs.recommended,
  {
    files: ['test/**'],
    ...jest.configs['flat/recommended'],
    rules: {
      ...jest.configs['flat/recommended'].rules,
      'jest/prefer-expect-assertions': 'off',
    },
  },
  // you can also configure jest rules in other objects, so long as some of the `files` match
  {
    files: ['test/**'],
    rules: { 'jest/prefer-expect-assertions': 'off' },
  },
];

Jest version setting

The behaviour of some rules (specifically no-deprecated-functions) change depending on the version of Jest being used.

By default, this plugin will attempt to determine to locate Jest using require.resolve, meaning it will start looking in the closest node_modules folder to the file being linted and work its way up.

Since we cache the automatically determined version, if you're linting sub-folders that have different versions of Jest, you may find that the wrong version of Jest is considered when linting. You can work around this by providing the Jest version explicitly in nested ESLint configs:

{
  "settings": {
    "jest": {
      "version": 27
    }
  }
}

To avoid hard-coding a number, you can also fetch it from the installed version of Jest if you use a JavaScript config file such as .eslintrc.js:

module.exports = {
  settings: {
    jest: {
      version: require('jest/package.json').version,
    },
  },
};

Shareable configurations

Note

eslint.config.js compatible versions of configs are available prefixed with flat/ and may be subject to small breaking changes while ESLint v9 is being finalized.

Recommended

This plugin exports a recommended configuration that enforces good testing practices.

To enable this configuration with .eslintrc, use the extends property:

{
  "extends": ["plugin:jest/recommended"]
}

To enable this configuration with eslint.config.js, use jest.configs['flat/recommended']:

const jest = require('eslint-plugin-jest');

module.exports = [
  {
    files: [
      /* glob matching your test files */
    ],
    ...jest.configs['flat/recommended'],
  },
];

Style

This plugin also exports a configuration named style, which adds some stylistic rules, such as prefer-to-be-null, which enforces usage of toBeNull over toBe(null).

To enable this configuration use the extends property in your .eslintrc config file:

{
  "extends": ["plugin:jest/style"]
}

To enable this configuration with eslint.config.js, use jest.configs['flat/style']:

const jest = require('eslint-plugin-jest');

module.exports = [
  {
    files: [
      /* glob matching your test files */
    ],
    ...jest.configs['flat/style'],
  },
];

All

If you want to enable all rules instead of only some you can do so by adding the all configuration to your .eslintrc config file:

{
  "extends": ["plugin:jest/all"]
}

To enable this configuration with eslint.config.js, use jest.configs['flat/all']:

const jest = require('eslint-plugin-jest');

module.exports = [
  {
    files: [
      /* glob matching your test files */
    ],
    ...jest.configs['flat/all'],
  },
];

While the recommended and style configurations only change in major versions the all configuration may change in any release and is thus unsuited for installations requiring long-term consistency.

Rules

πŸ’Ό Configurations enabled in.
⚠️ Configurations set to warn in.
βœ… Set in the recommended configuration.
🎨 Set in the style configuration.
πŸ”§ Automatically fixable by the --fix CLI option.
πŸ’‘ Manually fixable by editor suggestions.

NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  Description πŸ’Ό ⚠️ πŸ”§ πŸ’‘
consistent-test-it Enforce test and it usage conventions πŸ”§
expect-expect Enforce assertion to be made in a test body βœ…
max-expects Enforces a maximum number assertion calls in a test body
max-nested-describe Enforces a maximum depth to nested describe calls
no-alias-methods Disallow alias methods βœ… 🎨 πŸ”§
no-commented-out-tests Disallow commented out tests βœ…
no-conditional-expect Disallow calling expect conditionally βœ…
no-conditional-in-test Disallow conditional logic in tests
no-confusing-set-timeout Disallow confusing usages of jest.setTimeout
no-deprecated-functions Disallow use of deprecated functions βœ… πŸ”§
no-disabled-tests Disallow disabled tests βœ…
no-done-callback Disallow using a callback in asynchronous tests and hooks βœ… πŸ’‘
no-duplicate-hooks Disallow duplicate setup and teardown hooks
no-export Disallow using exports in files containing tests βœ…
no-focused-tests Disallow focused tests βœ… πŸ’‘
no-hooks Disallow setup and teardown hooks
no-identical-title Disallow identical titles βœ…
no-interpolation-in-snapshots Disallow string interpolation inside snapshots βœ…
no-jasmine-globals Disallow Jasmine globals βœ… πŸ”§
no-large-snapshots Disallow large snapshots
no-mocks-import Disallow manually importing from __mocks__ βœ…
no-restricted-jest-methods Disallow specific jest. methods
no-restricted-matchers Disallow specific matchers & modifiers
no-standalone-expect Disallow using expect outside of it or test blocks βœ…
no-test-prefixes Require using .only and .skip over f and x βœ… πŸ”§
no-test-return-statement Disallow explicitly returning from tests
no-untyped-mock-factory Disallow using jest.mock() factories without an explicit type parameter πŸ”§
prefer-called-with Suggest using toBeCalledWith() or toHaveBeenCalledWith()
prefer-comparison-matcher Suggest using the built-in comparison matchers πŸ”§
prefer-each Prefer using .each rather than manual loops
prefer-equality-matcher Suggest using the built-in equality matchers πŸ’‘
prefer-expect-assertions Suggest using expect.assertions() OR expect.hasAssertions() πŸ’‘
prefer-expect-resolves Prefer await expect(...).resolves over expect(await ...) syntax πŸ”§
prefer-hooks-in-order Prefer having hooks in a consistent order
prefer-hooks-on-top Suggest having hooks before any test cases
prefer-importing-jest-globals Prefer importing Jest globals πŸ”§
prefer-lowercase-title Enforce lowercase test names πŸ”§
prefer-mock-promise-shorthand Prefer mock resolved/rejected shorthands for promises πŸ”§
prefer-snapshot-hint Prefer including a hint with external snapshots
prefer-spy-on Suggest using jest.spyOn() πŸ”§
prefer-strict-equal Suggest using toStrictEqual() πŸ’‘
prefer-to-be Suggest using toBe() for primitive literals 🎨 πŸ”§
prefer-to-contain Suggest using toContain() 🎨 πŸ”§
prefer-to-have-length Suggest using toHaveLength() 🎨 πŸ”§
prefer-todo Suggest using test.todo πŸ”§
require-hook Require setup and teardown code to be within a hook
require-to-throw-message Require a message for toThrow()
require-top-level-describe Require test cases and hooks to be inside a describe block
valid-describe-callback Enforce valid describe() callback βœ…
valid-expect Enforce valid expect() usage βœ…
valid-expect-in-promise Require promises that have expectations in their chain to be valid βœ…
valid-title Enforce valid titles βœ… πŸ”§

Requires Type Checking

NameΒ Β Β Β Β Β Β Β Β Β  Description πŸ’Ό ⚠️ πŸ”§ πŸ’‘
unbound-method Enforce unbound methods are called with their expected scope

In order to use the rules powered by TypeScript type-checking, you must be using @typescript-eslint/parser & adjust your eslint config as outlined here.

Note that unlike the type-checking rules in @typescript-eslint/eslint-plugin, the rules here will fallback to doing nothing if type information is not available, meaning it's safe to include them in shared configs that could be used on JavaScript and TypeScript projects.

Also note that unbound-method depends on @typescript-eslint/eslint-plugin, as it extends the original unbound-method rule from that plugin.

Credit

Related Projects

eslint-plugin-jest-extended

This is a sister plugin to eslint-plugin-jest that provides support for the matchers provided by jest-extended.

https://github.com/jest-community/eslint-plugin-jest-extended

eslint-plugin-jest-formatting

This project aims to provide formatting rules (auto-fixable where possible) to ensure consistency and readability in jest test suites.

https://github.com/dangreenisrael/eslint-plugin-jest-formatting

eslint-plugin-istanbul

A set of rules to enforce good practices for Istanbul, one of the code coverage tools used by Jest.

https://github.com/istanbuljs/eslint-plugin-istanbul

eslint-plugin-jest's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eslint-plugin-jest's Issues

New rule proposal: disallow large snapshots (no-large-snapshots)

Hey all,

I've written a rule that I think would benefit the greater Jest community.

no-large-snapshots looks at all Jest snapshot files (files with .snap extension) and validates that each stored snapshot within those files does not exceed a certain number of lines (by default 35, though this is configurable and I am more than willing to change the default as is seen fit).

The reasoning for the rule is that as a matter of best practice snapshots should be limited in size in order to be more manageable and reviewable. A stored snapshot is only as good as its review and as such keeping it short, sweet, and readable is very important in my mind.

I already wrote the rule (and tests and docs) and it is being used internally by my team so if I was to open a PR to add it to eslint-plugin-jest would you consider it?

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


The push permission to the Git repository is required.

semantic-release cannot push the version tag to the branch master on remote Git repository.

Please refer to the authentication configuration documentation to configure the Git credentials on your CI environment.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Assert that async `expect`s are awaited or returned

valid-expect should check that if there's a rejects or resolves on an expect, that it's either awaited or returned.

Example where we should warn:

test('some test', () => {
  expect(Promise.resolve('hello')).resolves.toBe('hello');
});

Bug with valid-describe

I found this bug when converting some tests from another repo.

Sample test:

describe('test name', () =>
  test('some test', () => {...})
);

Will cause the following error:

/eslint-plugin-jest/rules/valid-describe.js:79
          callbackFunction.body.body.forEach(node => {
                                    ^

TypeError: Cannot read property 'forEach' of undefined
    at CallExpression (/eslint-plugin-jest/rules/valid-describe.js:79:37)
    at listeners.(anonymous function).forEach.listener (/eslint/lib/util/safe-emitter.js:47:58)
    at Array.forEach (native)
    at Object.emit (/eslint/lib/util/safe-emitter.js:47:38)
    at NodeEventGenerator.applySelector (/eslint/lib/util/node-event-generator.js:251:26)
    at NodeEventGenerator.applySelectors (/eslint/lib/util/node-event-generator.js:280:22)
    at NodeEventGenerator.enterNode (/eslint/lib/util/node-event-generator.js:294:14)
    at CodePathAnalyzer.enterNode (/eslint/lib/code-path-analysis/code-path-analyzer.js:606:23)
    at Traverser.enter (/eslint/lib/linter.js:955:32)
    at Traverser.__execute (/estraverse/estraverse.js:397:31)
    at Traverser.traverse (/node_modules/estraverse/estraverse.js:501:28)
"eslint": "4.9.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-import-resolver-babel-module": "^4.0.0",
"eslint-plugin-import": "^2.11.0",
"eslint-plugin-jest": "^21.15.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-promise": "^3.7.0",
"eslint-plugin-react": "^7.7.0"

Add rule to require assertion count assertion

I always try to add a expect.assertions(<number of assertions>) call to the top of every test I write. It helps me keep track of the assertions I am using, and prevents accidental adding and removing of assertions.

I was thinking a rule that requires that assertion for every test would be nice. There is also expect.hasAssertions(), maybe that should be included in a separate rule? Or maybe not at all, I've never used it because it seems better to specify the count of assertions.

If you guys think this sounds good I would like to give a try at implementing it.

Error when adding to project.

I get this error:

SyntaxError: Unexpected token )

/Users/....../node_modules/eslint-plugin-jest/rules/prefer_to_have_length.js:27
            );
            ^
SyntaxError: Unexpected token )
    at Object.exports.runInThisContext (vm.js:78:16)
    at Module._compile (module.js:545:28)
    at Object.Module._extensions..js (module.js:582:10)
    at Module.load (module.js:490:32)
    at tryModuleLoad (module.js:449:12)
    at Function.Module._load (module.js:441:3)
    at Module.require (module.js:500:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/..../node_modules/eslint-plugin-jest/index.js:6:28)
    at Module._compile (module.js:573:32)
Process finished with exit code -1

Are you open to support `context` as `describe` alias?

Up until around 1 year ago, context was an officially supported describe alias, but later got removed. Still, because of its value, some people (myself included) still want to use it, and as explained on that issue it's very easy to add it back.

Unfortunately, it's not compatible with using this ESLint plugin (and I really like this plugin :) ). Would you be open to merge a PR adding context (and derived context.only, …) to the describe aliases and other places where it would be needed?

I understand maybe you wouldn't want to have defaults that are different to what jest itself has in terms of globals, but if so, maybe adding it as a configurable option instead? Afaik, the plugin itself cannot receive a configuration though, so apparently that would need to be done by passing options to each applicable rule.

If you are open to this I can give a PR a try. Or if you have any other suggestion on how to use Β΄contextΒ΄ and this plugin at the same time, I would love to hear it.

Thanks for this plugin!

no-jest-import warns on fresh CRA eject

  • npx create-react-app foo
  • cd foo; npm run eject
  • npm test succeeds
  • eslint-plugin-jest warns that importing jest doesn't do anything so comment out const jest = require('jest') in ./scripts/test.js
  • npm test fails

Apparently it does do something? πŸ€·β€β™‚οΈ

Include globals and 'jest' plugin in recommended

I propose that the following be added to the "recommended" config option:

plugins: [
  'jest'
],
env: {
  'jest/globals': true
}

That way, when extending the recommended settings, a user does not have to include these manually. Both eslint-config-standard and eslint-plugin-vue (and probably others) do this as well. I'll submit the PR if this proposal is accepted.

error when extending from recommended

After adding plugin:jest/recommended to my eslintrc "extends", get this error in prefer-to-have-length:

[Error - 15:27:19] TypeError: context.getSourceCode(...).getFirstTokenBetween is not a function
    at EventEmitter.CallExpression (.../node_modules/eslint-plugin-jest/rules/prefer-to-have-length.js:33:14)```

Add a changelog

Should we go for semantic commits so we don't have to manually maintain it?

Should we use semantic release and just publish from CI?

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

suggestion: prefer `test` or `it`

Suggest using test or it (always-test-or-it)

For consistency in code, always use test or always use it.

Rule details

When test is preferred, this rule triggers a warning for any instances of it.
When it is preferred, this rule triggers a warning for any instances of test.

This rule is not set by default.

Default configuration

The following pattern is considered warning:

it('example 1', () => {
   expect(files).toHaveLength(1);
});

test('example 2', () => {
   expect(files).toHaveLength(1);
});

The following pattern is not warning when test is set:

test('example 1', () => {
   expect(files).toHaveLength(1);
});

test('example 2', () => {
   expect(files).toHaveLength(1);
});

The following pattern is not warning when it is set:

it('example 1', () => {
   expect(files).toHaveLength(1);
});

it('example 2', () => {
   expect(files).toHaveLength(1);
});

`require()` makes jest plugin crash

Hi, as I was working, I had a stray require() in my code and it made ESlint crash badly; that probably shouldn't happen. Here's the most trivial example that illustrates that:

simple.test.js

describe('simple test', () => {
  test('should not fail', () => {
      require()
  });
});

.eslintrc.js

module.exports = {
    "env": {
        "es6": true
    },
    "extends": ["eslint:recommended","plugin:jest/recommended"]
};

package.json

{
  "name": "jest-issue",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "eslint": "^4.19.1",
    "eslint-plugin-jest": "^21.15.2",
    "jest": "^23.0.0"
  }
}

Stack trace:

TypeError: Cannot read property 'value' of undefined
    at CallExpression (/Users/kopeckyj/tmp/jest/node_modules/eslint-plugin-jest/rules/no-jest-import.js:25:59)
    at listeners.(anonymous function).forEach.listener (/Users/kopeckyj/tmp/jest/node_modules/eslint/lib/util/safe-emitter.js:47:58)
    at Array.forEach (<anonymous>)
    at Object.emit (/Users/kopeckyj/tmp/jest/node_modules/eslint/lib/util/safe-emitter.js:47:38)
    at NodeEventGenerator.applySelector (/Users/kopeckyj/tmp/jest/node_modules/eslint/lib/util/node-event-generator.js:251:26)
    at NodeEventGenerator.applySelectors (/Users/kopeckyj/tmp/jest/node_modules/eslint/lib/util/node-event-generator.js:280:22)
    at NodeEventGenerator.enterNode (/Users/kopeckyj/tmp/jest/node_modules/eslint/lib/util/node-event-generator.js:294:14)
    at CodePathAnalyzer.enterNode (/Users/kopeckyj/tmp/jest/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:608:23)
    at Traverser.enter [as _enter] (/Users/kopeckyj/tmp/jest/node_modules/eslint/lib/linter.js:865:28)
    at Traverser._traverse (/Users/kopeckyj/tmp/jest/node_modules/eslint/lib/util/traverser.js:132:14)

Lint rule to indicate missing return staement when testing inside promise then or catch block.

[PORTING THIS ISSUE FROM JEST REPO]

Do you want to request a feature or report a bug?
Feature

What is the current behavior?
It is mentioned in the jest docs to return a promise when you want to test inside its then or catch block. In case, if a developer misses to add a return statement, then that expectation will not get executed and may result in test which is false positive.

What is the expected behavior?
A lint rule

Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.
jest: 21.2.1
node: 8.0.0
npm: 5.5.1
OS: Sierra (10.12.6)

New rule prefer-to-contain

Prefer expect(a).toContain(b) rather than expect(a.includes(b)).toBe(true).

The error messages are often times better.

This rule is similar to prefer-to-have-length.

[new rule] strict formatting for describe and test blocks

We would really like to enforce some strict formatting for the various parts of jest test syntax. I'm not sure if these would be general enough to be considered useful, but they seem like a nice way to help ensure test code is nicely structured. An example of my teams desired syntax is:

describe('some tests', () => {
  let varName

  beforeEach(() => {
    let varName = 'foo'
  })

  it('does something cool', () => {
    const result = callAFuncWith(varName)
    result.wow()

    expect(result).toBeAwesome()
  })
})

Seperate rules could enforce:

  • a blank line after describe level lets
  • a blank line after a beforeEach
  • a blank line between an expect and test setup statements

Another option would be a new 'eslint-jest-formatting' package.

Get to 100% test coverage

In #67 thresholds were added, but I was unable to set them at 100 as we don't have coverage. Help reaching it would be greatly appreciated!

Unhandled error with `prefer-to-be-null`

My linter crashes occasionally when using prefer-to-be-null with an expectation without a value.

Cannot read property 'value' of undefined
TypeError: Cannot read property 'value' of undefined
    at expectToEqualCase (/project/node_modules/eslint-plugin-jest/rules/util.js:40:17)
    at CallExpression (/project/node_modules/eslint-plugin-jest/rules/prefer_to_be_null.js:10:41)
    at listeners.(anonymous function).forEach.listener (/project/node_modules/eslint/lib/util/safe-emitter.js:47:58)
    at Array.forEach (native)
    at Object.emit (/project/node_modules/eslint/lib/util/safe-emitter.js:47:38)
    at NodeEventGenerator.applySelector (/project/node_modules/eslint/lib/util/node-event-generator.js:251:26)
    at NodeEventGenerator.applySelectors (/project/node_modules/eslint/lib/util/node-event-generator.js:280:22)
    at NodeEventGenerator.enterNode (/project/node_modules/eslint/lib/util/node-event-generator.js:294:14)
    at CodePathAnalyzer.enterNode (/project/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:608:23)
    at Traverser.enter (/project/node_modules/eslint/lib/linter.js:956:32)
expect(store.getFilters()).toEqual();

Padding between it and describe blocks.

I have been looking for a rule to enforce padding around all it and describe blocks. Is this the correct place for that? Maybe jest/padding-it-blocks and jest/padding-describe-blocks rules?

it('My awesome test.', () => {
  expect(true).toBe(true)
})
// Enforcing this line of padding between the it blocks below this comment...

it('My other awesome test.', () => {
  expect(false).toBe(false)
})

Prevent async `describe`

Thanks for this great plugin!

A mistake I've seen some people make is using an async function for describe, which then makes jest fail silently for a case like the following:

describe('sample case', () => {
  it('works', () => {
    expect(true).toEqual(true);
  });
  describe('async', async () => {
    await new Promise(setImmediate);
    it('breaks', () => {
      throw new Error('Fail');
    });
  });
});

It would be nice to have a rule that prevents this. Same would go for returning a promise (or any other value) inside describe.

describe('sample case', () => {
  it('works', () => {
    expect(true).toEqual(true);
  });
  describe('async', () => {
    return Promise.resolve().then(() => {
      it('breaks', () => {
        throw new Error('Fail');
      });
    });
  });
});

What do you guys think?

Refactor util.js

Various rule files consume util.js by requiring the file multiple times:

const expectCase = require('./util').expectCase;
const expectNotCase = require('./util').expectNotCase;
const expectResolveCase = require('./util').expectResolveCase;
const expectRejectCase = require('./util').expectRejectCase;
const method = require('./util').method;

I'm wondering if we could clean this up, either by how we require the files, or how we organize these util methods. Some options I can think of:

// require the util file once
const util = require('./util')

// use methods in the util namespace
util.expectCase()
util.expectNotCase()

or:

// extract functions out into their own files
const expectCase = require('./lib/expect-case')
const expectNotCase = require('./lib/expect-not-case')

I also wonder if we could have more specifically named util files, like is.js, which exports functions that take a node and return a boolean:

// is.js

function isFunction(node) {
  // ...
}

function isDescribe(node) {
  // ...
}

module.exports = {
  function: isFunction,
  describe: isDescribe,
}

// usage in another file

const is = require('./is')

if (is.describe(node)) {
  // do something
}

I'm just throwing out a few ideas that have different levels of difficulty in terms of the refactoring involved. Wondering what you think about these, if it's time to refactor any part of this, and (if so) how we can help make that happen. πŸ‘

`no-identical-title` maybe could be ignored for nested `describe` blocks...?

My scenario is that the linter is whining about no-identical-titles for nested describes where that nested title is actually what i want.

Imagine this:

describe("my component", () => {
  describe("west facing", () = {
    describe("when the sun is up", () => {  
       it("sees the sun", () => {});
    })
    describe("when the sun is down", () => {  
       it("sees the moon", () => {});
    });
  });
  describe("east facing", () = {
    describe("when the sun is up", () => {  
       it("does not see the sun", () => {});
    })
    describe("when the sun is down", () => {  
       it("sees whatever", () => {});
    });
  });
});

In this case... the linter doesn't like when the sun is up and when the sun is down because they are the same, but as nested describes, they seem like a valid use case.

What do you think of that? could there be a rule that looks at the full "nested" title to determine it's allowed "uniqueness"?

[new rule] prefer toHaveBeenCalledTimes()

This is a new rule suggestion; it would be nice to enforce toHaveBeenCalledTimes() over toHaveBeenCalled(), to ensure functions are only being executed a set amount of times. It's unlikely making this fixable would be useful, as we would have to make an assumption about the number of times, which could well be incorrect.

I'm happy to make a PR to support this, but don't have a definite timeframe. I thought it was worth opening the issue for discussion first.

New rule request: no-hooks

eslint-plugin-mocha has a rule called no-hooks that I think could be a good addition to this ESLint plugin. I think the mocha/no-hooks docs as well as this tweet help explain how using nested describe() and beforeEach() hook functions can result in harder to follow code / shared state between tests.

I think when combined with jest/consistent-test-it, you could enforce tests that look more like:

function setupFoo(options) { /* ... */ }
function setupBar(options) { /* ... */ }
function setupBaz(options) { /* ... */ }

test('foo does this', () => {
  const foo = setupFoo({ /* options */ })
  expect(foo).toEqual(/* expected */)
})

test('bar does this', () => {
  const bar = setupBar({ /* options */ })
  expect(bar).toEqual(/* expected */)
})

test('baz does this', () => {
  const baz = setupBaz({ /* options */ })
  expect(baz).toEqual(/* expected */)
})

instead of looking like this:

let foo
let bar
let baz

beforeEach(() => {
  foo = setupFoo()
  bar = setupBar()
  baz = setupBaz()
})

afterEach(() => {
  foo = null
  bar = null
  baz = null
})

test('foo does this', () => {
  expect(foo).toEqual(/* expected */)
})

test('bar does this', () => {
  expect(bar).toEqual(/* expected */)
})

test('baz does this', () => {
  expect(baz).toEqual(/* expected */)
})

I think there are times when using setup and teardown hooks are necessary, but I find that they can often be avoided. I could see this rule providing an option that would whitelist allowed hook function names, or the user could disable with // eslint-disable-next-line jest/no-hooks.

Thoughts on this rule? Would you accept a PR for this feature?

Warn about tests not run by jest

Ava has a cool rule called no-ignored-test-files. It would be great if we could port it.

It won't be as easy for us since we use globals. But looking for either describe, test or it which are not imported in any file not matched by Jest's testMatch (and the other ways of configuring where jest looks for tests) should be a good start.

Jest has a flag called listTests, but I'm not sure if we're able to call it programmatically (or if we'd want to).

Hopefully this is doable πŸ™‚

Add support for spyOn() as a valid global

I am trying to use the spyOn() method in my Jest tests. Although this is a valid global Jest function, it is still causing the following ESLint error:

error  'spyOn' is not defined

I have followed the instructions to setup this plugin, including installing it as a devDependency, adding "jest" to my eslintrc plugins and adding "jest/globals" to the env object. ESLint still throws an error. I even tried extending "plugin:jest/recommended", but that still throws the error.

What I find interesting is that there was a past commit (2984eb50c) that introduced support for spyOn as a valid global. However, there was soon after another commit (491271aaa) that reverted the previous one, so that support for spyOn was removed. I am curious to understand more about the intent of these commits. It seems like the former commit, which includes support for spyOn as a valid global, would fix my issue.

In the meanwhile, I am getting around this my adding a /* global spyOn */ comment to each file that uses spyOn(). Ideally, this project can make ESLint smart enough to know that spyOn is a valid global method.

Thank you.

Enforce it block to begin with lower case test decription

Some projects prefer that descriptions in it blocks beginning with lowercase letters. Is this something that can be enforced as a rule in eslint-plugin-jest

eg:

The following patterns are considered warnings:

it('Adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

These patterns would not be considered warnings:

it('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

New Rule: Prefer mock resolved/rejected shorthands

Simple sugar function for:

jest.fn().mockReturnValue(Promise.resolve(value));

Useful to mock async functions in async tests:

test('async test', async () => {
  const asyncMock = jest.fn().mockResolvedValue(43);

  await asyncMock(); // 43
});

Refs:

valid-describe blows up on template strings (backticks)

I have a pattern where I prefer backticks for test/describe names (makes apostrophes easier to juggle, and helps call out strings that are user-visible vs those that aren't)

However, valid-describe blows up on 'em:

describe(`foo`, () => { … }); // Error: First argument must be name
describe('foo', () => { … }); // OK

Manual extend without using "extends"

Unfortunately I cannot use the recommended "extends": ["plugin:jest/recommended"] method because I'm using glob override config and extends is not supported, see eslint/eslint#8813

With ESLint v4 that wasn't a problem I just did some "manual" extend like that:

import { configs } from "eslint-plugin-jest";

export default {
  plugins : configs.recommended.plugins,
  env     : configs.recommended.env,
  "extends": [
    "plugin:jest/recommended"
  ]
  rules   : {
    ...configs.recommended.rules,
    ...OVERRIDES
  }
};

The problem came with ESLint v5 where I get the same error as #44

Environment key "jest/globals" is unknown

And I cannot @pauloborges use answer because of the glob override config and extends issue.

Is there a workaround? Why is this Environment key "jest/globals" is unknown appearing with ESLint v5? Is there a way to manually register jest/globals?

I'm a bit stuck πŸ€”

Add rule disallowing importing `jest`

See jestjs/jest#4613, this is apparently a footgun.

We might take it one step further an yell at all assignments to a jest object as it might mess up static analysis, thus negating hoisting of jest.mock?

But at least a rule for not importing jest (as it doesn't export anything) makes sense.

Update eslint dependency to version 5.x

The version of eslint that this package uses is 4.10.0, which was released in October, 2017. The latest version as of filing this issue is 5.1.0. There have been at least 9 updates to the 4.x version, so at a minimum it should be updated to the lastest 4.x release, though moving to the 5.x version would be preferred.

New Rule named-snapshot

I was wondering if this repo would be open to a rule to enforce naming of snapshots. Options would be always | mutli | never

  • always - Enforce naming of snapshots even if there is only a singular snapshot.
  • multi - Enforce naming only if there are multiple snapshots in a test. naming from curly rule
  • never - Disallow naming of snapshots

I would be more than happy to contribute this rule. I plan to write it for one of my projects, and I wanted to check to make sure that this repo would be open to adding it before I open a PR.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.