繁体   English   中英

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

[英]Asynchronous code in custom ESLint rules

故事和动机:

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

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

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

目前的方法:

目前,我正在尝试使用自定义ESLint规则jira ESLint 模块Q来解决它。 自定义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规则中的ESLint吗? 如果没有,我的选择是什么?

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

将不胜感激任何见解或替代方法。

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

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

有关eslint devs的一些见解,请参阅我们在其邮件列表中的对话

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

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

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

Jasmine允许使用xit()将规范标记为挂起。 我不确定pending()虽然在Protractor中很奇怪。 此外, Jasmine允许在规范中调用pending() ,因此它将被标记为pending,但它尚未针对Protractor实现( 请参阅问题 )。 知道这一点,我会使用自定义助手来定义“待定规范”,应该检查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 异步API )。 在所有情况下,您仍然会在报告结果中将此规范重复为待处理。 当希望实现规范中的pending()功能时,我希望它可以得到改进。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM