• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

platinumazure / eslint-plugin-qunit / 4748569255

pending completion
4748569255

push

github

GitHub
Upgrade: Bump eslint from 8.36.0 to 8.38.0 (#335)

653 of 653 branches covered (100.0%)

878 of 878 relevant lines covered (100.0%)

82.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/lib/rules/no-arrow-tests.js
1
/**
2
 * @fileoverview Forbid arrow functions as QUnit test/module callbacks.
3
 * @author Kevin Partington
4
 * @copyright 2016 Kevin Partington. All rights reserved.
5
 * See LICENSE file in root directory for full license.
6
 */
7
"use strict";
8

9
//------------------------------------------------------------------------------
10
// Requirements
11
//------------------------------------------------------------------------------
12

13
const utils = require("../utils.js");
1✔
14

15
//------------------------------------------------------------------------------
16
// Rule Definition
17
//------------------------------------------------------------------------------
18

19
/** @type {import('eslint').Rule.RuleModule} */
20
module.exports = {
1✔
21
    meta: {
22
        type: "problem",
23
        docs: {
24
            description: "disallow arrow functions as QUnit test/module callbacks",
25
            category: "Best Practices",
26
            url: "https://github.com/platinumazure/eslint-plugin-qunit/blob/master/docs/rules/no-arrow-tests.md"
27
        },
28
        fixable: "code",
29
        messages: {
30
            noArrowFunction: "Arrow function should not be used as test callback."
31
        },
32
        schema: []
33
    },
34

35
    create: function (context) {
36
        //--------------------------------------------------------------------------
37
        // Helpers
38
        //--------------------------------------------------------------------------
39

40
        // Fixer adapted from https://github.com/lo1tuma/eslint-plugin-mocha (MIT)
41
        const sourceCode = context.getSourceCode();
71✔
42

43
        function extractSourceTextByRange(start, end) {
44
            return sourceCode.text.slice(start, end).trim();
81✔
45
        }
46

47
        function formatFunctionHead(fn) {
48
            const arrow = sourceCode.getTokenBefore(fn.body);
27✔
49
            const beforeArrowToken = sourceCode.getTokenBefore(arrow);
27✔
50
            let firstToken = sourceCode.getFirstToken(fn);
27✔
51

52
            let functionKeyword = "function";
27✔
53
            let params = extractSourceTextByRange(firstToken.range[0], beforeArrowToken.range[1]);
27✔
54
            if (fn.async) {
27✔
55
                // When 'async' specified strip the token from the params text
56
                // and prepend it to the function keyword
57
                params = params.slice(firstToken.range[1] - firstToken.range[0]).trim();
1✔
58
                functionKeyword = "async function";
1✔
59

60
                // Advance firstToken pointer
61
                firstToken = sourceCode.getTokenAfter(firstToken);
1✔
62
            }
63

64
            const beforeArrowComment = extractSourceTextByRange(beforeArrowToken.range[1], arrow.range[0]);
27✔
65
            const afterArrowComment = extractSourceTextByRange(arrow.range[1], fn.body.range[0]);
27✔
66
            const paramsFullText = firstToken.type === "Punctuator" ?
27✔
67
                `${params}${beforeArrowComment}${afterArrowComment}` :
68
                `(${params}${beforeArrowComment})${afterArrowComment}`;
69

70
            return `${functionKeyword}${paramsFullText} `;
27✔
71
        }
72

73
        function fixArrowFunction(fixer, fn) {
74
            if (fn.body.type === "BlockStatement") {
27✔
75
                // When it((...) => { ... }),
76
                // simply replace '(...) => ' with 'function () '
77
                return fixer.replaceTextRange(
26✔
78
                    [fn.range[0], fn.body.range[0]],
79
                    formatFunctionHead(fn)
80
                );
81
            }
82

83
            const bodyText = sourceCode.text.slice(fn.body.range[0], fn.body.range[1]);
1✔
84
            return fixer.replaceTextRange(
1✔
85
                [fn.range[0], fn.range[1]],
86
                `${formatFunctionHead(fn)}{ return ${bodyText}; }`
87
            );
88
        }
89

90
        function checkCallback(fn) {
91
            if (fn && fn.type === "ArrowFunctionExpression") {
70✔
92
                context.report({
27✔
93
                    node: fn,
94
                    messageId: "noArrowFunction",
95
                    fix: fixer => fixArrowFunction(fixer, fn)
27✔
96
                });
97
            }
98
        }
99

100
        function isPropertyInModule(propertyNode) {
101
            return propertyNode &&
28✔
102
                propertyNode.parent &&
103
                propertyNode.parent.type === "ObjectExpression" &&
104
                propertyNode.parent.parent &&
105
                propertyNode.parent.parent.type === "CallExpression" &&
106
                utils.isModule(propertyNode.parent.parent.callee);
107
        }
108

109
        function isModuleProperty(propertyNode) {
110
            return isPropertyInModule(propertyNode) &&
28✔
111
                utils.isModuleHookPropertyKey(propertyNode.key);
112
        }
113

114
        //--------------------------------------------------------------------------
115
        // Public
116
        //--------------------------------------------------------------------------
117

118
        return {
71✔
119
            "CallExpression": function (node) {
120
                if (utils.isTest(node.callee) && node.arguments && node.arguments.length > 1) {
116✔
121
                    checkCallback(node.arguments[1]);
46✔
122
                }
123
            },
124

125
            "Property": function (node) {
126
                if (isModuleProperty(node)) {
28✔
127
                    checkCallback(node.value);
24✔
128
                }
129
            }
130
        };
131
    }
132
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc