UniRef: adding TranslatingReferenceDetector implementation (#1511)

The TranslatingReferenceDetector is an abstraction particularly useful for the
Initiatives reference detector. Which should use the Discourse reference
detector as it's base and translate the node address of the returned discourse
topic to the initiative's node address.
This commit is contained in:
Robin van Boven 2020-01-07 13:48:25 +01:00 committed by GitHub
parent 953cbfaac2
commit 579b01ed46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 0 deletions

View File

@ -3,3 +3,4 @@
export type {URL, ReferenceDetector} from "./referenceDetector"; export type {URL, ReferenceDetector} from "./referenceDetector";
export {MappedReferenceDetector} from "./mappedReferenceDetector"; export {MappedReferenceDetector} from "./mappedReferenceDetector";
export {CascadingReferenceDetector} from "./cascadingReferenceDetector"; export {CascadingReferenceDetector} from "./cascadingReferenceDetector";
export {TranslatingReferenceDetector} from "./translatingReferenceDetector";

View File

@ -0,0 +1,26 @@
// @flow
import type {NodeAddressT} from "../graph";
import type {ReferenceDetector, URL} from "./referenceDetector";
type TranslateFunction = (NodeAddressT) => ?NodeAddressT;
/**
* A ReferenceDetector which takes a base ReferenceDetector and applies a
* translate function to any results.
*/
export class TranslatingReferenceDetector implements ReferenceDetector {
translate: TranslateFunction;
base: ReferenceDetector;
constructor(base: ReferenceDetector, translate: TranslateFunction) {
this.base = base;
this.translate = translate;
}
addressFromUrl(url: URL): ?NodeAddressT {
const baseAddr = this.base.addressFromUrl(url);
if (!baseAddr) return;
return this.translate(baseAddr);
}
}

View File

@ -0,0 +1,56 @@
// @flow
import {type NodeAddressT, NodeAddress} from "../graph";
import type {URL, ReferenceDetector} from "./referenceDetector";
import {MappedReferenceDetector} from "./mappedReferenceDetector";
import {TranslatingReferenceDetector} from "./translatingReferenceDetector";
const nodeA = NodeAddress.fromParts(["test", "A"]);
const nodeB = NodeAddress.fromParts(["test", "B"]);
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/translatingReferenceDetector", () => {
describe("TranslatingReferenceDetector", () => {
it("should implement the ReferenceDetector interface", () => {
const _unused_toReferenceDetector = (
x: TranslatingReferenceDetector
): ReferenceDetector => x;
});
it("should not call translate function when base has no hit", () => {
// Given
const base = exampleDetector();
const translate = jest.fn().mockImplementation(() => nodeB);
// When
const refs = new TranslatingReferenceDetector(base, translate);
const n1 = refs.addressFromUrl("http://foo.bar/miss");
// Then
expect(base.addressFromUrl).toBeCalledWith("http://foo.bar/miss");
expect(translate).toBeCalledTimes(0);
expect(n1).toEqual(undefined);
});
it("should call translate function when base has a hit", () => {
// Given
const base = exampleDetector([["http://foo.bar/a", nodeA]]);
const translate = jest.fn().mockImplementation(() => nodeB);
// When
const refs = new TranslatingReferenceDetector(base, translate);
const n1 = refs.addressFromUrl("http://foo.bar/a");
// Then
expect(base.addressFromUrl).toBeCalledWith("http://foo.bar/a");
expect(translate).toBeCalledWith(nodeA);
expect(n1).toEqual(nodeB);
});
});
});