簡體   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