Add `RelationalView.match` (#438)

`match` implements pattern matching over `Entity`

Test plan:
Unit tests included.
This commit is contained in:
Dandelion Mané 2018-06-28 14:57:23 -07:00 committed by GitHub
parent e239fdfeeb
commit 40db3cdfa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 0 deletions

View File

@ -690,6 +690,36 @@ function* getAuthors(
}
}
export type MatchHandlers<T> = {|
+repo: (x: Repo) => T,
+issue: (x: Issue) => T,
+pull: (x: Pull) => T,
+review: (x: Review) => T,
+comment: (x: Comment) => T,
+userlike: (x: Userlike) => T,
|};
export function match<T>(handlers: MatchHandlers<T>, x: Entity): T {
if (x instanceof Repo) {
return handlers.repo(x);
}
if (x instanceof Issue) {
return handlers.issue(x);
}
if (x instanceof Pull) {
return handlers.pull(x);
}
if (x instanceof Review) {
return handlers.review(x);
}
if (x instanceof Comment) {
return handlers.comment(x);
}
if (x instanceof Userlike) {
return handlers.userlike(x);
}
throw new Error(`Unexpected entity ${x}`);
}
export type Entity = Repo | Issue | Pull | Review | Comment | Userlike;
export type AuthoredEntity = Issue | Pull | Review | Comment;
export type TextContentEntity = Issue | Pull | Review | Comment;

View File

@ -138,6 +138,25 @@ describe("plugins/github/relationalView", () => {
has("url", () => entity.url());
});
describe("match", () => {
const handlers = {
// Return the address so we know it was actually called on the entity,
// and a hardcoded string so we know the right function was called.
repo: (x: R.Repo) => [x.address(), "REPO"],
issue: (x: R.Issue) => [x.address(), "ISSUE"],
pull: (x: R.Pull) => [x.address(), "PULL"],
review: (x: R.Review) => [x.address(), "REVIEW"],
comment: (x: R.Comment) => [x.address(), "COMMENT"],
userlike: (x: R.Userlike) => [x.address(), "USERLIKE"],
};
const instances = [repo, issue, pull, review, comment, userlike];
for (const instance of instances) {
const [actualAddress, functionType] = R.match(handlers, instance);
expect(actualAddress.type).toEqual(functionType);
}
});
describe("comment parent differentiation", () => {
function hasCorrectParent(name, parent) {
it(name, () => {