Skip to content

Commit

Permalink
Add prefer-to-have-length rule
Browse files Browse the repository at this point in the history
  • Loading branch information
xfumihiro committed Oct 26, 2017
1 parent cfbda80 commit 85f03b9
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* `[jest-config]` Include error message for `preset` json ([#4766](https://github.com/facebook/jest/pull/4766))

### Features
* `[eslint-plugin-jest]` Add `prefer-to-have-length` lint rule. ([#4771](https://github.com/facebook/jest/pull/4771))
* `[jest-environment-jsdom]` [**BREAKING**] Upgrade to JSDOM@11 ([#4770](https://github.com/facebook/jest/pull/4770))
* `[jest-environment-*]` [**BREAKING**] Add Async Test Environment APIs, dispose is now teardown ([#4506](https://github.com/facebook/jest/pull/4506))
* `[jest-cli]` Add an option to clear the cache ([#4430](https://github.com/facebook/jest/pull/4430))
Expand Down
27 changes: 27 additions & 0 deletions packages/eslint-plugin-jest/docs/rules/prefer-to-have-length.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Suggest using `toHaveLength()` (prefer-to-have-length)

In order to have a better failure message, `toHaveLength()` should be used upon asserting expections on object's length property.

## Rule details

This rule triggers a warning if `toBe()` is used to assert object's length property.

```js
expect(files.length).toBe(1);
```

This rule is enabled by default.

### Default configuration

The following pattern is considered warning:

```js
expect(files.length).toBe(1);
```

The following pattern is not warning:

```js
expect(files).toHaveLength(1);
```
3 changes: 3 additions & 0 deletions packages/eslint-plugin-jest/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import noDisabledTests from './rules/no_disabled_tests';
import noFocusedTests from './rules/no_focused_tests';
import noIdenticalTitle from './rules/no_identical_title';
import preferToHaveLength from './rules/prefer_to_have_length';
import validExpect from './rules/valid_expect';

module.exports = {
Expand All @@ -19,6 +20,7 @@ module.exports = {
'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',
},
},
Expand Down Expand Up @@ -50,6 +52,7 @@ module.exports = {
'no-disabled-tests': noDisabledTests,
'no-focused-tests': noFocusedTests,
'no-identical-title': noIdenticalTitle,
'prefer-to-have-length': preferToHaveLength,
'valid-expect': validExpect,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

/* eslint-disable sort-keys */

'use strict';

import {RuleTester} from 'eslint';
const {rules} = require('../../');

const ruleTester = new RuleTester();

ruleTester.run('prefer_to_have_length', rules['prefer-to-have-length'], {
valid: ['expect(files).toHaveLength(1);', "expect(files.name).toBe('file');"],

invalid: [
{
code: 'expect(files.length).toBe(1);',
errors: [
{
message: 'Use toHaveLength() instead',
column: 22,
line: 1,
},
],
},
],
});
39 changes: 39 additions & 0 deletions packages/eslint-plugin-jest/src/rules/prefer_to_have_length.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {EslintContext, CallExpression} from './types';

export default (context: EslintContext) => {
return {
CallExpression(node: CallExpression) {
const calleeName = node.callee.name;

if (
calleeName === 'expect' &&
node.arguments.length == 1 &&
node.parent &&
node.parent.type === 'MemberExpression' &&
node.parent.parent
) {
const parentProperty = node.parent.property;
const propertyName = parentProperty.name;

if (
propertyName === 'toBe' &&
node.arguments[0].property.name === 'length'
) {
context.report({
message: 'Use toHaveLength() instead',
node: parentProperty,
});
}
}
},
};
};
1 change: 1 addition & 0 deletions packages/eslint-plugin-jest/src/rules/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Literal = {
value?: string,
rawValue?: string,
parent: ParentNode,
property: Identifier,
loc: NodeLocation,
};

Expand Down

0 comments on commit 85f03b9

Please sign in to comment.