1 | 'use strict';
|
2 |
|
3 | const {visitIf} = require('enhance-visitors');
|
4 | const util = require('../util');
|
5 | const createAvaRule = require('../create-ava-rule');
|
6 |
|
7 | const MAX_ASSERTIONS_DEFAULT = 5;
|
8 |
|
9 | const notAssertionMethods = new Set(['plan', 'end']);
|
10 |
|
11 | const create = context => {
|
12 | const ava = createAvaRule();
|
13 |
|
14 |
|
15 | const maxAssertions = context.options[0] ?? MAX_ASSERTIONS_DEFAULT;
|
16 | let assertionCount = 0;
|
17 | let nodeToReport;
|
18 |
|
19 | return ava.merge({
|
20 | CallExpression: visitIf([
|
21 | ava.isInTestFile,
|
22 | ava.isInTestNode,
|
23 | ])(node => {
|
24 | const {callee} = node;
|
25 |
|
26 | if (callee.type !== 'MemberExpression') {
|
27 | return;
|
28 | }
|
29 |
|
30 | if (
|
31 | callee.property
|
32 | && !notAssertionMethods.has(callee.property.name)
|
33 | && util.getNameOfRootNodeObject(callee) === 't'
|
34 | ) {
|
35 | const firstNonSkipMember = util.getMembers(callee).find(name => name !== 'skip');
|
36 |
|
37 | if (!util.assertionMethods.has(firstNonSkipMember)) {
|
38 | return;
|
39 | }
|
40 |
|
41 | assertionCount++;
|
42 |
|
43 | if (assertionCount === maxAssertions + 1) {
|
44 | nodeToReport = node;
|
45 | }
|
46 | }
|
47 | }),
|
48 | 'CallExpression:exit': visitIf([ava.isTestNode])(() => {
|
49 |
|
50 | if (assertionCount > maxAssertions) {
|
51 | context.report({
|
52 | node: nodeToReport,
|
53 | message: `Expected at most ${maxAssertions} assertions, but found ${assertionCount}.`,
|
54 | });
|
55 | }
|
56 |
|
57 | assertionCount = 0;
|
58 | nodeToReport = undefined;
|
59 | }),
|
60 | });
|
61 | };
|
62 |
|
63 | const schema = [
|
64 | {
|
65 | type: 'integer',
|
66 | default: MAX_ASSERTIONS_DEFAULT,
|
67 | },
|
68 | ];
|
69 |
|
70 | module.exports = {
|
71 | create,
|
72 | meta: {
|
73 | type: 'suggestion',
|
74 | docs: {
|
75 | description: 'Enforce a limit on the number of assertions in a test.',
|
76 | url: util.getDocsUrl(__filename),
|
77 | },
|
78 | schema,
|
79 | },
|
80 | };
|