自定义ESLint规则中的异步代码

时间:2015-11-23 22:17:44

标签: javascript protractor static-code-analysis eslint

故事和动机:

我们有一个相当庞大的端到端Protractor测试代码库。有时,测试会等待实现特定修复 - 通常作为TDD方法的一部分,并演示如何重现问题以及预期的行为是什么。我们目前正在做的是使用Jasmine的pending()里面有一个Jira问题编号。例如:

pending("Missing functionality (AP-1234)", function () {
    // some testing is done here
});

现在,我们想知道何时可以将pending()重命名为it()并运行测试。或者,换句话说,当问题AP-1234被解决或发送到测试时。

当前方法:

目前,我正在尝试使用custom ESLint rulejira NodeJS moduleQ解决此问题。自定义ESLint规则会搜索至少包含一个参数的pending()个调用。以AP-后跟4位数的格式提取故障单编号,并使用jira.findIssue()检查其在Jira中的状态。如果状态为Resolved - 报告错误。

这是我到目前为止所得到的:

"use strict";

var JiraApi = require("jira").JiraApi,
    Q = require('q');
var jira = new JiraApi("https",
    "jira.url.com",
    "443",
    "user",
    "password",
    "2");

module.exports = function (context) {
    var jiraTicketRegex = /AP\-\d+/g;

    return {
        CallExpression: function (node) {
            if (node.callee.name === "pending" && node.arguments.length > 0) {
                var match = node.arguments[0].value.match(jiraTicketRegex);

                if (match) {
                    match.forEach(function(ticket) {
                        console.log(ticket);  // I see the ticket numbers printed
                        getTicket(ticket).then(function (status) {
                            console.log(status);  // I don't see statuses printed
                            if (status === "Resolved") {
                                context.report(node, 'Ticket {{ticket}} is already resolved.', {
                                    ticket: ticket
                                })
                            }
                        });
                    });

                }
            }
        }
    }
};

getTicket()定义为:

function getTicket(ticket) {
    var deferred = Q.defer();

    jira.findIssue(ticket, function(error, issue) {
        if (error) {
            deferred.reject(new Error(error));
        } else {
            deferred.resolve(issue.fields.status.name);
        }
    });

    return deferred.promise;
}

问题是:目前,它成功从pending()电话中提取票号,但不打印票证状态。虽然没有错误。

问题:

我想,一般的问题是:我可以使用异步代码块,等待回调,解决自定义ESLint规则中的承诺吗?如果没有,我的选择是什么?

更具体的问题是:我做错了什么以及如何将Node.js jira模块与ESLint一起使用?

会欣赏任何见解或替代方法。

3 个答案:

答案 0 :(得分:5)

简短的回答是 - 不,你不能在规则中使用异步代码。 ESLint是同步的,并且在它走过AST时严重依赖EventEmitter。将ESLint代码修改为异步非常困难,但同时保证事件将以正确的顺序发出。 我认为您唯一的选择可能是编写一个同步规则,将足够的信息输出到错误消息中,然后使用其中一个可解析的格式化程序,如JSONUNIX,然后创建另一个可以管道ESLint的应用程序根据错误消息输出到Jira并在Jira中执行异步查找。

答案 1 :(得分:2)

这些答案在2018年仍然有效。

有关eslint开发者的一些见解,请参阅我们在邮件列表中的this conversation

对于一个工作示例,在我的"pseudo eslint plugin"中,我选择使用昂贵但同步的API,并警告用户如何最好地在其CI流程中使用“插件”。

答案 2 :(得分:1)

注意:它没有回答有关在ESLint自定义规则中支持异步代码的原始问题,但提供了该问题的替代解决方案。

在这种情况下,我个人不会使用 ESLint ,它应该用于检查您的代码是否写得正确以及是否遵循样式指南;从我的观点来看,缺少测试不是代码检查的一部分,它更像是团队内部流程。此外,这种请求可能会显着减慢您的 ESLint 执行速度,如果有人在他们的编辑器中实时运行它,则会经常进行调用并且会减慢整个检查速度。我会让 JIRA 检查 Protractor 流程的一部分,因此如果故障单已解决,您将获得一个失败的 Protractor 规范。 (从comment复制以完成答案)

Jasmine 允许使用xit()将规范标记为待处理。我不确定pending(),但它在 Protractor 中很奇怪。此外, Jasmine 允许在规范中调用pending(),因此它将被标记为暂挂,但尚未为 Protractor 实现({{3} })。知道这一点,我会使用自定义助手来定义“待定规范”,应该检查 JIRA 问题状态。我猜你仍然可以使用 Q 来处理promises,我只是使用 WebDriver promises发布一个替代方案而没有外部依赖。以下是getTicket()的修改版本:

function getTicketStatus(ticket) {

    // Using WebDriver promises
    var deferred = protractor.promise.defer();

    jira.findIssue(ticket, function(error, issue) {
        if (error) {
            deferred.reject(new Error(error));
        } else {
            deferred.fulfill(issue.fields.status.name);
        }
    });

    return deferred.promise;
}

然后有一个自定义帮助函数:

function jira(name) {
    // Display as pending in reporter results, remove when pending() is supported
    xit(name);

    // Using Jasmine Async API because Jira request is not a part of Control Flow
    it(name, function (done) {

        getTicketStatus().then(function (status) {
            if (status === 'Resolved') {
                done.fail('Ticket "' + name + '" is already resolved.');
            } else {
                done();
                // pending() is not supported yet https://github.com/angular/protractor/issues/2454
                // pending();
            }
        }, function (error) {
            done.fail(error);
        });
    });

}

用法示例:

jira('Missing functionality (AP-1234)', function () {
    //
});

jira('Missing functionality (AP-1235)');

如果对 JIRA 的请求失败或问题状态已解决,您将获得失败的规范(使用 Jasmine {{3 }})。在所有情况下,您仍然会在报告结果中将此规范重复为待处理。我希望当规范中的pending()功能为see issue时,可以对其进行改进。

相关问题