UniRef: add urlReferenceMap to RelationalView (#1542)

RelationalView provides easy access to ReferentEntities, which we
can use for reference detection. The map produced by
urlReferenceMap can be used easily by a MappedReferenceDetector.

As discussed in #1532 we'll use RelationalView for this before
deprecating it.
This commit is contained in:
Robin van Boven 2020-01-13 14:09:19 +01:00 committed by GitHub
parent d7cacf7173
commit f16119af43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 0 deletions

View File

@ -824,3 +824,48 @@ Array [
},
]
`;
exports[`plugins/github/relationalView urlReferenceMap should match example snapshot 1`] = `
Array [
Array [
"https://github.com/credbot",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"USERLIKE\\",\\"BOT\\",\\"credbot\\"]",
],
Array [
"https://github.com/decentralion",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"USERLIKE\\",\\"USER\\",\\"decentralion\\"]",
],
Array [
"https://github.com/sourcecred-test/example-github",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"REPO\\",\\"sourcecred-test\\",\\"example-github\\"]",
],
Array [
"https://github.com/sourcecred-test/example-github/commit/0a223346b4e6dec0127b1e6aa892c4ee0424b66a",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"COMMIT\\",\\"MDY6Q29tbWl0MTIzMjU1MDA2OjBhMjIzMzQ2YjRlNmRlYzAxMjdiMWU2YWE4OTJjNGVlMDQyNGI2NmE=\\"]",
],
Array [
"https://github.com/sourcecred-test/example-github/issues/1",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"ISSUE\\",\\"sourcecred-test\\",\\"example-github\\",\\"1\\"]",
],
Array [
"https://github.com/sourcecred-test/example-github/issues/2#issuecomment-373768703",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"COMMENT\\",\\"ISSUE\\",\\"sourcecred-test\\",\\"example-github\\",\\"2\\",\\"373768703\\"]",
],
Array [
"https://github.com/sourcecred-test/example-github/pull/3",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"PULL\\",\\"sourcecred-test\\",\\"example-github\\",\\"3\\"]",
],
Array [
"https://github.com/sourcecred-test/example-github/pull/3#issuecomment-369162222",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"COMMENT\\",\\"PULL\\",\\"sourcecred-test\\",\\"example-github\\",\\"3\\",\\"369162222\\"]",
],
Array [
"https://github.com/sourcecred-test/example-github/pull/5#discussion_r171460198",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"COMMENT\\",\\"REVIEW\\",\\"sourcecred-test\\",\\"example-github\\",\\"5\\",\\"100313899\\",\\"171460198\\"]",
],
Array [
"https://github.com/sourcecred-test/example-github/pull/5#pullrequestreview-100313899",
"NodeAddress[\\"sourcecred\\",\\"github\\",\\"REVIEW\\",\\"sourcecred-test\\",\\"example-github\\",\\"5\\",\\"100313899\\"]",
],
]
`;

View File

@ -1,5 +1,7 @@
// @flow
import {type URL} from "../../core/references";
import {NodeAddress, type NodeAddressT} from "../../core/graph";
import {toCompat, fromCompat, type Compatible} from "../../util/compat";
import stringify from "json-stable-stringify";
import {parseReferences} from "./parseReferences";
@ -515,6 +517,30 @@ export class RelationalView {
}
}
/**
* Creates a Map<URL, NodeAddressT> for each ReferentEntity in this view.
* Note: duplicates are accepted within one view. However for any URL, the
* corresponding N.RawAddress should be the same, or we'll throw an error.
*/
urlReferenceMap(): Map<URL, NodeAddressT> {
const refToAddress: Map<URL, NodeAddressT> = new Map();
for (const e: ReferentEntity of this.referentEntities()) {
const addr = N.toRaw(e.address());
const url = e.url();
const existing = refToAddress.get(url);
if (existing && existing != addr) {
throw new Error(dedent`\
An entry for ${url} already existed, but with a different NodeAddressT.
This is probably a bug with SourceCred. Please report it on GitHub.
Old: ${NodeAddress.toString(existing)}
New: ${NodeAddress.toString(addr)}
`);
}
refToAddress.set(url, addr);
}
return refToAddress;
}
_addReferences() {
// TODO(perf): _addReferences regenerates all refs from scratch
this._mapReferences = new Map();

View File

@ -1,5 +1,6 @@
// @flow
import {NodeAddress} from "../../core/graph";
import * as R from "./relationalView";
import * as N from "./nodes";
import {exampleRepository, exampleRelationalView} from "./example/example";
@ -390,6 +391,40 @@ describe("plugins/github/relationalView", () => {
});
});
describe("urlReferenceMap", () => {
it("should match example snapshot", () => {
// Given
const rv = exampleRelationalView();
// When
const map = rv.urlReferenceMap();
// Then
const snapshotMapWith = (urls: string[]): [string, ?string][] => {
// Sort, for less test flakes.
// Remove null bytes from NodeAddress.
// Generate selective [key, value] tuples.
urls.sort();
const maybeString = (a) => (a ? NodeAddress.toString(a) : a);
return urls.map((url) => [url, maybeString(map.get(url))]);
};
expect(
snapshotMapWith([
"https://github.com/decentralion",
"https://github.com/credbot",
"https://github.com/sourcecred-test/example-github",
"https://github.com/sourcecred-test/example-github/issues/1",
"https://github.com/sourcecred-test/example-github/pull/3",
"https://github.com/sourcecred-test/example-github/pull/5#pullrequestreview-100313899",
"https://github.com/sourcecred-test/example-github/issues/2#issuecomment-373768703",
"https://github.com/sourcecred-test/example-github/pull/3#issuecomment-369162222",
"https://github.com/sourcecred-test/example-github/pull/5#discussion_r171460198",
"https://github.com/sourcecred-test/example-github/commit/0a223346b4e6dec0127b1e6aa892c4ee0424b66a",
])
).toMatchSnapshot();
});
});
describe("expectAllNonNull", () => {
it("returns non-null elements unscathed, with no warnings", () => {
jest.spyOn(console, "warn").mockImplementation(() => {});