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.)
This commit is contained in:
Dandelion Mané 2018-05-10 11:41:19 -07:00 committed by GitHub
parent 04390e5609
commit 0d6742be39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 0 deletions

View File

@ -266,6 +266,7 @@ export class Author extends GithubEntity<AuthorNodePayload> {
assertEntityType(e, AUTHOR_NODE_TYPE); assertEntityType(e, AUTHOR_NODE_TYPE);
return (e: any); return (e: any);
} }
login(): string { login(): string {
return this.node().payload.login; return this.node().payload.login;
} }
@ -280,12 +281,15 @@ export class PullRequest extends Commentable<PullRequestNodePayload> {
assertEntityType(e, PULL_REQUEST_NODE_TYPE); assertEntityType(e, PULL_REQUEST_NODE_TYPE);
return (e: any); return (e: any);
} }
number(): number { number(): number {
return this.node().payload.number; return this.node().payload.number;
} }
title(): string { title(): string {
return this.node().payload.title; return this.node().payload.title;
} }
reviews(): PullRequestReview[] { reviews(): PullRequestReview[] {
return this.graph return this.graph
.neighborhood(this.nodeAddress, { .neighborhood(this.nodeAddress, {
@ -294,6 +298,11 @@ export class PullRequest extends Commentable<PullRequestNodePayload> {
}) })
.map(({neighbor}) => new PullRequestReview(this.graph, neighbor)); .map(({neighbor}) => new PullRequestReview(this.graph, neighbor));
} }
parent(): Repository {
return (_parent(this): any);
}
mergeCommitHash(): ?string { mergeCommitHash(): ?string {
const mergeEdge = this.graph const mergeEdge = this.graph
.neighborhood(this.nodeAddress, { .neighborhood(this.nodeAddress, {
@ -320,12 +329,18 @@ export class Issue extends Commentable<IssueNodePayload> {
assertEntityType(e, ISSUE_NODE_TYPE); assertEntityType(e, ISSUE_NODE_TYPE);
return (e: any); return (e: any);
} }
number(): number { number(): number {
return this.node().payload.number; return this.node().payload.number;
} }
title(): string { title(): string {
return this.node().payload.title; return this.node().payload.title;
} }
parent(): Repository {
return (_parent(this): any);
}
} }
export class Comment extends Post<CommentNodePayload> { export class Comment extends Post<CommentNodePayload> {
@ -333,6 +348,10 @@ export class Comment extends Post<CommentNodePayload> {
assertEntityType(e, COMMENT_NODE_TYPE); assertEntityType(e, COMMENT_NODE_TYPE);
return (e: any); return (e: any);
} }
parent(): Issue | PullRequest {
return (_parent(this): any);
}
} }
export class PullRequestReview extends Post<PullRequestReviewNodePayload> { export class PullRequestReview extends Post<PullRequestReviewNodePayload> {
@ -340,10 +359,15 @@ export class PullRequestReview extends Post<PullRequestReviewNodePayload> {
assertEntityType(e, PULL_REQUEST_REVIEW_NODE_TYPE); assertEntityType(e, PULL_REQUEST_REVIEW_NODE_TYPE);
return (e: any); return (e: any);
} }
state(): PullRequestReviewState { state(): PullRequestReviewState {
return this.node().payload.state; return this.node().payload.state;
} }
parent(): PullRequest {
return (_parent(this): any);
}
comments(): PullRequestReviewComment[] { comments(): PullRequestReviewComment[] {
return this.graph return this.graph
.neighborhood(this.nodeAddress, { .neighborhood(this.nodeAddress, {
@ -361,4 +385,18 @@ export class PullRequestReviewComment extends Post<
assertEntityType(e, PULL_REQUEST_REVIEW_COMMENT_NODE_TYPE); assertEntityType(e, PULL_REQUEST_REVIEW_COMMENT_NODE_TYPE);
return (e: any); 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);
} }

View File

@ -73,6 +73,7 @@ describe("GitHub porcelain", () => {
expect(repo.name()).toBe("example-github"); expect(repo.name()).toBe("example-github");
expect(repo).toEqual(asEntity(graph, repo.address())); expect(repo).toEqual(asEntity(graph, repo.address()));
}); });
it("Issues", () => { it("Issues", () => {
const issue = issueOrPRByNumber(1); const issue = issueOrPRByNumber(1);
expect(issue.title()).toBe("An example issue."); expect(issue.title()).toBe("An example issue.");
@ -86,7 +87,9 @@ describe("GitHub porcelain", () => {
expect(issue.address()).toEqual(issue.node().address); expect(issue.address()).toEqual(issue.node().address);
expect(issue.authors().map((x) => x.login())).toEqual(["decentralion"]); expect(issue.authors().map((x) => x.login())).toEqual(["decentralion"]);
expect(issue).toEqual(asEntity(graph, issue.address())); expect(issue).toEqual(asEntity(graph, issue.address()));
expect(issue.parent()).toEqual(repo);
}); });
describe("PullRequests", () => { describe("PullRequests", () => {
it("Merged", () => { it("Merged", () => {
const pullRequest = PullRequest.from(issueOrPRByNumber(3)); const pullRequest = PullRequest.from(issueOrPRByNumber(3));
@ -103,6 +106,7 @@ describe("GitHub porcelain", () => {
"0a223346b4e6dec0127b1e6aa892c4ee0424b66a" "0a223346b4e6dec0127b1e6aa892c4ee0424b66a"
); );
expect(pullRequest).toEqual(asEntity(graph, pullRequest.address())); expect(pullRequest).toEqual(asEntity(graph, pullRequest.address()));
expect(pullRequest.parent()).toEqual(repo);
}); });
it("Unmerged", () => { it("Unmerged", () => {
const pullRequest = PullRequest.from(issueOrPRByNumber(9)); const pullRequest = PullRequest.from(issueOrPRByNumber(9));
@ -117,6 +121,7 @@ describe("GitHub porcelain", () => {
expect(reviews[0].state()).toBe("CHANGES_REQUESTED"); expect(reviews[0].state()).toBe("CHANGES_REQUESTED");
expect(reviews[1].state()).toBe("APPROVED"); expect(reviews[1].state()).toBe("APPROVED");
expect(reviews[0]).toEqual(asEntity(graph, reviews[0].address())); expect(reviews[0]).toEqual(asEntity(graph, reviews[0].address()));
expect(reviews[0].parent()).toEqual(pr);
}); });
it("Pull Request Review Comments", () => { it("Pull Request Review Comments", () => {
@ -126,6 +131,7 @@ describe("GitHub porcelain", () => {
const comments = reviews[0].comments(); const comments = reviews[0].comments();
expect(comments).toHaveLength(1); expect(comments).toHaveLength(1);
const comment = comments[0]; const comment = comments[0];
expect(comment.parent()).toEqual(reviews[0]);
expect(comment.url()).toBe( expect(comment.url()).toBe(
"https://github.com/sourcecred/example-github/pull/5#discussion_r171460198" "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.address()).toEqual(comment.node().address);
expect(comment.authors().map((x) => x.login())).toEqual(["decentralion"]); expect(comment.authors().map((x) => x.login())).toEqual(["decentralion"]);
expect(comment).toEqual(asEntity(graph, comment.address())); expect(comment).toEqual(asEntity(graph, comment.address()));
expect(comment.parent()).toEqual(issue);
}); });
it("Authors", () => { it("Authors", () => {