The Story and Motivation:
We have a rather huge end-to-end Protractor test codebase. Sometimes it happens that a test waits for a specific fix to be implemented - usually as a part of a TDD approach and to demonstrate how a problem is reproduced and what is the intended behavior. What we are currently doing is using Jasmine's pending()
with a Jira issue number inside. Example:
pending("Missing functionality (AP-1234)", function () {
// some testing is done here
});
Now, we'd like to know when we can rename the pending()
back to it()
and run the test. Or, in other words, when the issue AP-1234
is resolved or sent to testing.
The Current Approach:
At the moment, I'm trying to solve it with a custom ESLint
rule, jira
NodeJS module, and Q
. The custom ESLint
rule searches for pending()
calls with at least one argument. Extracts the ticket numbers in format of AP-
followed by 4 digits and uses jira.findIssue()
to check its status in Jira. If status is Resolved
- report an error.
Here is what I've got so far:
"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
})
}
});
});
}
}
}
}
};
Where getTicket()
is defined as:
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;
}
The problem is: currently, it successfully extracts the ticket numbers from the pending()
calls, but doesn't print ticket statuses. No errors though.
The Question:
The general question is, I guess, would be: can I use asynchronous code blocks, wait for callbacks, resolve promises in custom ESLint
rules? And, if not, what are my options?
A more specific question would be: what am I doing wrong and how can I use Node.js jira
module with ESLint
?
Would appreciate any insights or alternative approaches.
async and await Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
Keep in mind that we have over 200 rules, and that is daunting both for end users and the ESLint team (who has to maintain them).
The short answer is - no, you can't use asynchronous code inside of the rules. ESLint is synchronous and heavily relies on EventEmitter
when it walks AST. It would be very hard to modify ESLint code to be async, but at the same time guarantee that events will be emitted in the right order.
I think your only choice might be to write a sync rule that outputs enough information into the error message, then use one of the parsable formatters like JSON
or UNIX
and then create another application that you can pipe ESLint output to and do a async lookup in Jira based on the error message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With