mirror of
https://github.com/status-im/sourcecred.git
synced 2025-02-26 19:20:35 +00:00
Create github.Porcelain
: whole-graph porcelain (#230)
Now that we have repository nodes (#171), it makes sense that the Github porcelain should provide a way to wrap the entire graph, and provide easy access for the various repositories. This adds a `Porcelain` class to fulfill that need. The `Porcelain` is very straightforward: it takes in the whole graph, and gives a way to get all the Repositories, or to request a particular Repository by owner/name. In the odd case wherein a graph contains multiple repository nodes with the same owner and name, an error is thrown. Per standard JS map semantics (bleh), it can return undefined if there is no matching repository. Test plan: See that the unit tests now use the standard behavior, and a test verifies behavior for non-existant repositories. I don't have a test case where there are multiple repo nodes, but that itself would be an error, so throwing an error in that case is just defensive programming.
This commit is contained in:
parent
f219636a56
commit
9b3019434d
@ -31,6 +31,7 @@ import {
|
||||
PULL_REQUEST_NODE_TYPE,
|
||||
PULL_REQUEST_REVIEW_COMMENT_NODE_TYPE,
|
||||
PULL_REQUEST_REVIEW_NODE_TYPE,
|
||||
REPOSITORY_NODE_TYPE,
|
||||
REFERENCES_EDGE_TYPE,
|
||||
} from "./types";
|
||||
|
||||
@ -53,6 +54,34 @@ function assertEntityType(e: Entity, t: NodeType) {
|
||||
}
|
||||
}
|
||||
|
||||
export class Porcelain {
|
||||
graph: Graph<NodePayload, EdgePayload>;
|
||||
|
||||
constructor(graph: Graph<NodePayload, EdgePayload>) {
|
||||
this.graph = graph;
|
||||
}
|
||||
|
||||
/* Return all the repositories in the graph */
|
||||
repositories(): Repository[] {
|
||||
return this.graph
|
||||
.nodes({type: REPOSITORY_NODE_TYPE})
|
||||
.map((n) => new Repository(this.graph, n.address));
|
||||
}
|
||||
|
||||
/* Return the repository with the given owner and name */
|
||||
repository(owner: string, name: string): Repository {
|
||||
const repo = this.repositories().filter(
|
||||
(r) => r.owner() === owner && r.name() === name
|
||||
);
|
||||
if (repo.length > 1) {
|
||||
throw new Error(
|
||||
`Unexpectedly found multiple repositories named ${owner}/${name}`
|
||||
);
|
||||
}
|
||||
return repo[0];
|
||||
}
|
||||
}
|
||||
|
||||
class GithubEntity<T: NodePayload> {
|
||||
graph: Graph<NodePayload, EdgePayload>;
|
||||
nodeAddress: Address;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import {parse} from "./parser";
|
||||
import exampleRepoData from "./demoData/example-github.json";
|
||||
import {Repository, Issue, PullRequest, Comment, Author} from "./api";
|
||||
import {Porcelain, Issue, PullRequest, Comment, Author} from "./api";
|
||||
import {
|
||||
AUTHOR_NODE_TYPE,
|
||||
COMMENT_NODE_TYPE,
|
||||
@ -11,11 +11,11 @@ import {
|
||||
PULL_REQUEST_REVIEW_NODE_TYPE,
|
||||
PULL_REQUEST_REVIEW_COMMENT_NODE_TYPE,
|
||||
} from "./types";
|
||||
|
||||
describe("GitHub porcelain API", () => {
|
||||
const graph = parse(exampleRepoData);
|
||||
// TODO: Create a higher level API that contains all the repositories
|
||||
const repoNode = graph.nodes({type: "REPOSITORY"})[0];
|
||||
const repo = new Repository(graph, repoNode.address);
|
||||
const porcelain = new Porcelain(graph);
|
||||
const repo = porcelain.repository("sourcecred", "example-github");
|
||||
function issueOrPRByNumber(n: number): Issue | PullRequest {
|
||||
const result = repo.issueOrPRByNumber(n);
|
||||
if (result == null) {
|
||||
@ -23,6 +23,18 @@ describe("GitHub porcelain API", () => {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
describe("has repository finding", () => {
|
||||
it("which works for an existing repository", () => {
|
||||
expect(porcelain.repository("sourcecred", "example-github")).toEqual(
|
||||
expect.anything()
|
||||
);
|
||||
});
|
||||
|
||||
it("which returns undefined when asking for a nonexistent repo", () => {
|
||||
expect(porcelain.repository("sourcecred", "bad-repo")).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe("has wrappers for", () => {
|
||||
it("Repositories", () => {
|
||||
expect(repo.url()).toBe("https://github.com/sourcecred/example-github");
|
||||
|
Loading…
x
Reference in New Issue
Block a user