UniRef: add CascadingReferenceDetector implementation (#1510)
The CascadingReferenceDetector is an abstraction we can use for combining multiple ReferenceDetector instances and giving them a priority.
This commit is contained in:
parent
821be0b46e
commit
953cbfaac2
|
@ -0,0 +1,23 @@
|
|||
//@flow
|
||||
|
||||
import type {NodeAddressT} from "../graph";
|
||||
import type {ReferenceDetector, URL} from "./referenceDetector";
|
||||
|
||||
/**
|
||||
* A class for composing ReferenceDetectors. Calls ReferenceDetectors in the order
|
||||
* they're given in the constructor, returning the first NodeAddressT it encounters.
|
||||
*/
|
||||
export class CascadingReferenceDetector implements ReferenceDetector {
|
||||
refs: $ReadOnlyArray<ReferenceDetector>;
|
||||
|
||||
constructor(refs: $ReadOnlyArray<ReferenceDetector>) {
|
||||
this.refs = refs;
|
||||
}
|
||||
|
||||
addressFromUrl(url: URL): ?NodeAddressT {
|
||||
for (const ref of this.refs) {
|
||||
const addr = ref.addressFromUrl(url);
|
||||
if (addr) return addr;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
// @flow
|
||||
|
||||
import {type NodeAddressT, NodeAddress} from "../graph";
|
||||
import type {URL, ReferenceDetector} from "./referenceDetector";
|
||||
import {MappedReferenceDetector} from "./mappedReferenceDetector";
|
||||
import {CascadingReferenceDetector} from "./cascadingReferenceDetector";
|
||||
|
||||
const nodeA = NodeAddress.fromParts(["test", "A"]);
|
||||
const nodeB = NodeAddress.fromParts(["test", "B"]);
|
||||
const nodeC = NodeAddress.fromParts(["test", "C"]);
|
||||
|
||||
function exampleDetector(pairs?: [URL, NodeAddressT][]): ReferenceDetector {
|
||||
const map: Map<URL, NodeAddressT> = new Map(pairs);
|
||||
const refs = new MappedReferenceDetector(map);
|
||||
jest.spyOn(refs, "addressFromUrl");
|
||||
return refs;
|
||||
}
|
||||
|
||||
describe("core/references/cascadingReferenceDetector", () => {
|
||||
describe("CascadingReferenceDetector", () => {
|
||||
it("should implement the ReferenceDetector interface", () => {
|
||||
const _unused_toReferenceDetector = (
|
||||
x: CascadingReferenceDetector
|
||||
): ReferenceDetector => x;
|
||||
});
|
||||
|
||||
it("should try all ReferenceDetectors to look for a hit", () => {
|
||||
// Given
|
||||
const refs1 = exampleDetector();
|
||||
const refs2 = exampleDetector();
|
||||
const refs3 = exampleDetector();
|
||||
|
||||
// When
|
||||
const refs = new CascadingReferenceDetector([refs1, refs2, refs3]);
|
||||
const n1 = refs.addressFromUrl("http://foo.bar/miss");
|
||||
|
||||
// Then
|
||||
expect(refs1.addressFromUrl.mock.calls).toEqual([
|
||||
["http://foo.bar/miss"],
|
||||
]);
|
||||
expect(refs2.addressFromUrl.mock.calls).toEqual([
|
||||
["http://foo.bar/miss"],
|
||||
]);
|
||||
expect(refs3.addressFromUrl.mock.calls).toEqual([
|
||||
["http://foo.bar/miss"],
|
||||
]);
|
||||
expect(n1).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should return the first ReferenceDetector's value that provides a hit", () => {
|
||||
// Given
|
||||
const refs1 = exampleDetector([["http://foo.bar/1", nodeA]]);
|
||||
const refs2 = exampleDetector([
|
||||
["http://foo.bar/1", nodeB],
|
||||
["http://foo.bar/2", nodeB],
|
||||
]);
|
||||
const refs3 = exampleDetector([
|
||||
["http://foo.bar/1", nodeC],
|
||||
["http://foo.bar/2", nodeC],
|
||||
["http://foo.bar/3", nodeC],
|
||||
]);
|
||||
|
||||
// When
|
||||
const refs = new CascadingReferenceDetector([refs1, refs2, refs3]);
|
||||
const n1 = refs.addressFromUrl("http://foo.bar/1");
|
||||
const n2 = refs.addressFromUrl("http://foo.bar/2");
|
||||
const n3 = refs.addressFromUrl("http://foo.bar/3");
|
||||
|
||||
// Then
|
||||
expect(refs1.addressFromUrl.mock.calls).toEqual([
|
||||
["http://foo.bar/1"],
|
||||
["http://foo.bar/2"],
|
||||
["http://foo.bar/3"],
|
||||
]);
|
||||
expect(refs2.addressFromUrl.mock.calls).toEqual([
|
||||
["http://foo.bar/2"],
|
||||
["http://foo.bar/3"],
|
||||
]);
|
||||
expect(refs3.addressFromUrl.mock.calls).toEqual([["http://foo.bar/3"]]);
|
||||
expect(n1).toEqual(nodeA);
|
||||
expect(n2).toEqual(nodeB);
|
||||
expect(n3).toEqual(nodeC);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
export type {URL, ReferenceDetector} from "./referenceDetector";
|
||||
export {MappedReferenceDetector} from "./mappedReferenceDetector";
|
||||
export {CascadingReferenceDetector} from "./cascadingReferenceDetector";
|
||||
|
|
Loading…
Reference in New Issue