GH: Add a description method for entities (#439)

This commit adds a `description` method that takes a GitHub entity, and
returns a description of that entity. Based on the work in #261.

In contrast to the implementation in #261:
- It won't crash on entities without an author (although we don't have a
test case for this; see #389).
- It handles multi-authors reasonably (although we can't test that, as
we haven't implemented multi-authorship yet; see #218).

Test plan:
Inspect snapshot to see some examples.
This commit is contained in:
Dandelion Mané 2018-06-28 16:53:52 -07:00 committed by GitHub
parent 40db3cdfa3
commit 607adeca29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 0 deletions

View File

@ -0,0 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`plugins/github/render descriptions are as expected 1`] = `
Object {
"comment": "comment by @wchargin on review by @wchargin of #5: This pull request will be more contentious. I can feel it...",
"issue": "#2: A referencing issue.",
"pull": "#5: This pull request will be more contentious. I can feel it...",
"repo": "sourcecred/example-github",
"review": "review by @wchargin of #5: This pull request will be more contentious. I can feel it...",
"userlike": "@wchargin",
}
`;

View File

@ -17,3 +17,21 @@ export function exampleRelationalView(): RelationalView {
export function exampleGraph(): Graph {
return createGraph(exampleRelationalView());
}
export function exampleEntities() {
const view = exampleRelationalView();
const repo = Array.from(view.repos())[0];
const issue = Array.from(repo.issues())[1];
const pull = Array.from(repo.pulls())[1];
const review = Array.from(pull.reviews())[0];
const comment = Array.from(review.comments())[0];
const userlike = Array.from(review.authors())[0];
return {
repo,
issue,
pull,
review,
comment,
userlike,
};
}

View File

@ -0,0 +1,23 @@
// @flow
import * as R from "./relationalView";
export function description(e: R.Entity) {
const withAuthors = (x: R.AuthoredEntity) => {
const authors = Array.from(x.authors());
if (authors.length === 0) {
// ghost author - probably a deleted account
return "";
}
return "by " + authors.map((x) => description(x)).join(" & ") + " ";
};
const handlers = {
repo: (x) => `${x.owner()}/${x.name()}`,
issue: (x) => `#${x.number()}: ${x.title()}`,
pull: (x) => `#${x.number()}: ${x.title()}`,
review: (x) => `review ${withAuthors(x)}of ${description(x.parent())}`,
comment: (x) => `comment ${withAuthors(x)}on ${description(x.parent())}`,
userlike: (x) => `@${x.login()}`,
};
return R.match(handlers, e);
}

View File

@ -0,0 +1,16 @@
// @flow
import {exampleEntities} from "./example/example";
import {description} from "./render";
describe("plugins/github/render", () => {
it("descriptions are as expected", () => {
const examples = exampleEntities();
const withDescriptions = {};
for (const name of Object.keys(exampleEntities())) {
const entity = examples[name];
withDescriptions[name] = description(entity);
}
expect(withDescriptions).toMatchSnapshot();
});
});