[英]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代碼修改為異步非常困難,但同時保證事件將以正確的順序發出。 我認為您唯一的選擇可能是編寫一個同步規則,將足夠的信息輸出到錯誤消息中,然后使用其中一個可解析的格式化程序(如JSON
或UNIX
,然后創建另一個應用程序,您可以將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.