diff --git a/src/v3/plugins/github/urlIdParse.js b/src/v3/plugins/github/urlIdParse.js new file mode 100644 index 0000000..abaaf0e --- /dev/null +++ b/src/v3/plugins/github/urlIdParse.js @@ -0,0 +1,44 @@ +// @flow + +// Includes base github url, and the repo owner and repo name with trailing slash +const baseGithubRegex = /^https:\/\/github.com\/(?:[a-zA-Z0-9_-]+)\/(?:[a-zA-Z0-9_-]+)\//; + +export function reviewUrlToId(url: string): string { + const suffix = /pull\/\d+#pullrequestreview-(\d+)$/; + const regex = new RegExp(baseGithubRegex.source + suffix.source); + const result = regex.exec(url); + if (result == null) { + throw new Error(`Error parsing review url ${url}`); + } + return result[1]; +} + +export function issueCommentUrlToId(url: string): string { + const suffix = /issues\/\d+#issuecomment-(\d+)$/; + const regex = new RegExp(baseGithubRegex.source + suffix.source); + const result = regex.exec(url); + if (result == null) { + throw new Error(`Error parsing issue comment url ${url}`); + } + return result[1]; +} + +export function pullCommentUrlToId(url: string): string { + const suffix = /pull\/\d+#issuecomment-(\d+)$/; + const regex = new RegExp(baseGithubRegex.source + suffix.source); + const result = regex.exec(url); + if (result == null) { + throw new Error(`Error parsing pull comment url ${url}`); + } + return result[1]; +} + +export function reviewCommentUrlToId(url: string): string { + const suffix = /pull\/\d+#discussion_r(\d+)/; + const regex = new RegExp(baseGithubRegex.source + suffix.source); + const result = regex.exec(url); + if (result == null) { + throw new Error(`Error parsing review comment url ${url}`); + } + return result[1]; +} diff --git a/src/v3/plugins/github/urlIdParse.test.js b/src/v3/plugins/github/urlIdParse.test.js new file mode 100644 index 0000000..8346921 --- /dev/null +++ b/src/v3/plugins/github/urlIdParse.test.js @@ -0,0 +1,77 @@ +// @flow + +import { + issueCommentUrlToId, + pullCommentUrlToId, + reviewCommentUrlToId, + reviewUrlToId, +} from "./urlIdParse"; + +describe("plugins/github/urlToId", () => { + const issueComment = + "https://github.com/example-owner/example-repo0/issues/350#issuecomment-394939349"; + const pullComment = + "https://github.com/example-owner/example-repo0/pull/363#issuecomment-395836900"; + const reviewComment = + "https://github.com/example-owner/example-repo0/pull/380#discussion_r194816899"; + const review = + "https://github.com/example-owner/example-repo0/pull/383#pullrequestreview-128199239"; + + describe("works correctly", () => { + it("for issueComment", () => { + expect(issueCommentUrlToId(issueComment)).toEqual("394939349"); + }); + it("for pullComment", () => { + expect(pullCommentUrlToId(pullComment)).toEqual("395836900"); + }); + it("for reviewComment", () => { + expect(reviewCommentUrlToId(reviewComment)).toEqual("194816899"); + }); + it("for review", () => { + expect(reviewUrlToId(review)).toEqual("128199239"); + }); + }); + describe("errors on", () => { + const issueCommentNamed = {instance: issueComment, name: "issue comment"}; + const reviewCommentNamed = { + instance: reviewComment, + name: "review comment", + }; + const pullCommentNamed = {instance: pullComment, name: "pull comment"}; + const reviewNamed = {instance: review, name: "review"}; + const withWrongTypes = [ + { + f: issueCommentUrlToId, + instances: [pullCommentNamed, reviewCommentNamed, reviewNamed], + }, + { + f: pullCommentUrlToId, + instances: [issueCommentNamed, reviewCommentNamed, reviewNamed], + }, + { + f: reviewCommentUrlToId, + instances: [pullCommentNamed, issueCommentNamed, reviewNamed], + }, + { + f: reviewUrlToId, + instances: [pullCommentNamed, issueCommentNamed, reviewCommentNamed], + }, + ]; + const nullNamed = {instance: null, name: "null"}; + const undefinedNamed = {instance: undefined, name: "undefined"}; + const nonsenseNamed = {instance: "nonsense", name: "nonsense"}; + const garbage = [nullNamed, undefinedNamed, nonsenseNamed]; + + withWrongTypes.forEach(({f, instances}) => { + describe(f.name, () => { + const examples = [...instances, ...garbage]; + examples.forEach(({instance, name}) => { + it(`recieving ${name}`, () => { + // $ExpectFlowError + expect(() => f(instance)).toThrow("Error parsing"); + }); + }); + }); + }); + }); +});