From 0d6742be394f4f2fd5535f0564af6a7d9cdabe29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dandelion=20Man=C3=A9?=
Date: Thu, 10 May 2018 11:41:19 -0700
Subject: [PATCH] Add `parent()` relationships for GitHub porcelain (#255)
Test plan: Unit tests were added.
(Note: I haven't tested the error case, when there are an invalid number
of parents. I think this is OK for now, but I'm disclosing this so
reviewers can easily take issue with it. I'm planning to re-organize the
test code to be by method rather than by wrapper type (so the wrappers
section doesn't keep being a kitchen sink) and will hopefully
put that test in.)
---
src/plugins/github/porcelain.js | 38 ++++++++++++++++++++++++++++
src/plugins/github/porcelain.test.js | 7 +++++
2 files changed, 45 insertions(+)
diff --git a/src/plugins/github/porcelain.js b/src/plugins/github/porcelain.js
index c63612e..62f1623 100644
--- a/src/plugins/github/porcelain.js
+++ b/src/plugins/github/porcelain.js
@@ -266,6 +266,7 @@ export class Author extends GithubEntity {
assertEntityType(e, AUTHOR_NODE_TYPE);
return (e: any);
}
+
login(): string {
return this.node().payload.login;
}
@@ -280,12 +281,15 @@ export class PullRequest extends Commentable {
assertEntityType(e, PULL_REQUEST_NODE_TYPE);
return (e: any);
}
+
number(): number {
return this.node().payload.number;
}
+
title(): string {
return this.node().payload.title;
}
+
reviews(): PullRequestReview[] {
return this.graph
.neighborhood(this.nodeAddress, {
@@ -294,6 +298,11 @@ export class PullRequest extends Commentable {
})
.map(({neighbor}) => new PullRequestReview(this.graph, neighbor));
}
+
+ parent(): Repository {
+ return (_parent(this): any);
+ }
+
mergeCommitHash(): ?string {
const mergeEdge = this.graph
.neighborhood(this.nodeAddress, {
@@ -320,12 +329,18 @@ export class Issue extends Commentable {
assertEntityType(e, ISSUE_NODE_TYPE);
return (e: any);
}
+
number(): number {
return this.node().payload.number;
}
+
title(): string {
return this.node().payload.title;
}
+
+ parent(): Repository {
+ return (_parent(this): any);
+ }
}
export class Comment extends Post {
@@ -333,6 +348,10 @@ export class Comment extends Post {
assertEntityType(e, COMMENT_NODE_TYPE);
return (e: any);
}
+
+ parent(): Issue | PullRequest {
+ return (_parent(this): any);
+ }
}
export class PullRequestReview extends Post {
@@ -340,10 +359,15 @@ export class PullRequestReview extends Post {
assertEntityType(e, PULL_REQUEST_REVIEW_NODE_TYPE);
return (e: any);
}
+
state(): PullRequestReviewState {
return this.node().payload.state;
}
+ parent(): PullRequest {
+ return (_parent(this): any);
+ }
+
comments(): PullRequestReviewComment[] {
return this.graph
.neighborhood(this.nodeAddress, {
@@ -361,4 +385,18 @@ export class PullRequestReviewComment extends Post<
assertEntityType(e, PULL_REQUEST_REVIEW_COMMENT_NODE_TYPE);
return (e: any);
}
+ parent(): PullRequestReview {
+ return (_parent(this): any);
+ }
+}
+
+function _parent(x: Entity): Entity {
+ const parents = x.graph.neighborhood(x.address(), {
+ edgeType: "CONTAINS",
+ direction: "IN",
+ });
+ if (parents.length !== 1) {
+ throw new Error(`Bad parent relationships for ${stringify(x.address())}`);
+ }
+ return asEntity(x.graph, parents[0].neighbor);
}
diff --git a/src/plugins/github/porcelain.test.js b/src/plugins/github/porcelain.test.js
index 913c455..dabcef4 100644
--- a/src/plugins/github/porcelain.test.js
+++ b/src/plugins/github/porcelain.test.js
@@ -73,6 +73,7 @@ describe("GitHub porcelain", () => {
expect(repo.name()).toBe("example-github");
expect(repo).toEqual(asEntity(graph, repo.address()));
});
+
it("Issues", () => {
const issue = issueOrPRByNumber(1);
expect(issue.title()).toBe("An example issue.");
@@ -86,7 +87,9 @@ describe("GitHub porcelain", () => {
expect(issue.address()).toEqual(issue.node().address);
expect(issue.authors().map((x) => x.login())).toEqual(["decentralion"]);
expect(issue).toEqual(asEntity(graph, issue.address()));
+ expect(issue.parent()).toEqual(repo);
});
+
describe("PullRequests", () => {
it("Merged", () => {
const pullRequest = PullRequest.from(issueOrPRByNumber(3));
@@ -103,6 +106,7 @@ describe("GitHub porcelain", () => {
"0a223346b4e6dec0127b1e6aa892c4ee0424b66a"
);
expect(pullRequest).toEqual(asEntity(graph, pullRequest.address()));
+ expect(pullRequest.parent()).toEqual(repo);
});
it("Unmerged", () => {
const pullRequest = PullRequest.from(issueOrPRByNumber(9));
@@ -117,6 +121,7 @@ describe("GitHub porcelain", () => {
expect(reviews[0].state()).toBe("CHANGES_REQUESTED");
expect(reviews[1].state()).toBe("APPROVED");
expect(reviews[0]).toEqual(asEntity(graph, reviews[0].address()));
+ expect(reviews[0].parent()).toEqual(pr);
});
it("Pull Request Review Comments", () => {
@@ -126,6 +131,7 @@ describe("GitHub porcelain", () => {
const comments = reviews[0].comments();
expect(comments).toHaveLength(1);
const comment = comments[0];
+ expect(comment.parent()).toEqual(reviews[0]);
expect(comment.url()).toBe(
"https://github.com/sourcecred/example-github/pull/5#discussion_r171460198"
);
@@ -148,6 +154,7 @@ describe("GitHub porcelain", () => {
expect(comment.address()).toEqual(comment.node().address);
expect(comment.authors().map((x) => x.login())).toEqual(["decentralion"]);
expect(comment).toEqual(asEntity(graph, comment.address()));
+ expect(comment.parent()).toEqual(issue);
});
it("Authors", () => {