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", () => {