fuzzy-rater
Version:
Tooling for fuzzily rating text according to some query
144 lines • 16.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const FuzzyMultiWordMatcher_1 = require("../FuzzyMultiWordMatcher");
/**
* Retrieves the distances for all matches for each of the inputs under the given matcher
* @param matcher The matcher to use
* @param inputs The inputs to match
* @returns The distances for all matches
*/
function getDistances(matcher, inputs) {
return inputs.map(text => {
const match = matcher.getMatch(text);
return match.map(d => d.distance);
});
}
/**
* Maps a constant value over an input array
* @param list The list of inputs to map the constants over
* @param value The value to map to
* @returns The list of values
*/
function map(list, value) {
return list.map(() => value);
}
/**
* Converts a string of alteration codes into the proper alteration types array
* @param alterations The alterations string
* @returns The alterations array
*/
function createAlterations(alterations) {
const t = {
i: "ignore",
m: "match",
r: "replace",
a: "insert",
s: "skip",
};
return Array.from(alterations).map(s => { var _a; return (_a = t[s]) !== null && _a !== void 0 ? _a : ""; });
}
describe("FuzzyMultiWordMatcher", () => {
describe("new FuzzyMultiWordMatcher", () => {
it("Doesn't error", () => {
new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("oranges", 2);
});
});
describe("FuzzyMultiWordMatcher.getMatch", () => {
it("Should find whether text contains exact matches", () => {
const matcher = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("oranges", 2);
const match = matcher.getMatch("I like oranges and all oranges");
const noMatch = matcher.getMatch("Potatoes are amazing");
expect(match).toEqual([
{ distance: 0, endIndex: 14 },
{ endIndex: 30, distance: 0 },
]);
expect(noMatch).toEqual([]);
});
it("Should find matches at most n characters away", () => {
const matcher0 = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("oranges", 0);
const matcher1 = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("oranges", 1);
const matcher2 = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("oranges", 2);
const matcher3 = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("oranges", 3);
const matches = ["I like oranges", "oranges are nice"];
const with1mistake = [
"I like orange",
"I like ornges",
"orangles are nice",
"oronges are cool",
];
const with2mistakes = [
"I like ornge",
"I like orngaes",
"orlangles are nice",
"orongkes are cool",
];
const with3mistakes = [
"I like orne",
"I like orngaees",
"orflangles are nice",
"orlongkes are cool",
];
const noMatches = [
"I like potaters",
"hockey is cool sport",
"That will be 4 bux baby",
];
expect(getDistances(matcher0, matches)).toEqual(map(matches, [0]));
expect(getDistances(matcher0, with1mistake)).toEqual(map(with1mistake, []));
expect(getDistances(matcher0, with2mistakes)).toEqual(map(with2mistakes, []));
expect(getDistances(matcher0, with3mistakes)).toEqual(map(with3mistakes, []));
expect(getDistances(matcher0, noMatches)).toEqual(map(noMatches, []));
expect(getDistances(matcher1, matches)).toEqual(map(matches, [0]));
expect(getDistances(matcher1, with1mistake)).toEqual(map(with1mistake, [1]));
expect(getDistances(matcher1, with2mistakes)).toEqual(map(with2mistakes, []));
expect(getDistances(matcher1, with3mistakes)).toEqual(map(with3mistakes, []));
expect(getDistances(matcher1, noMatches)).toEqual(map(noMatches, []));
expect(getDistances(matcher2, matches)).toEqual(map(matches, [0]));
expect(getDistances(matcher2, with1mistake)).toEqual(map(with1mistake, [1]));
expect(getDistances(matcher2, with2mistakes)).toEqual(map(with2mistakes, [2]));
expect(getDistances(matcher2, with3mistakes)).toEqual(map(with3mistakes, []));
expect(getDistances(matcher2, noMatches)).toEqual(map(noMatches, []));
expect(getDistances(matcher3, matches)).toEqual(map(matches, [0]));
expect(getDistances(matcher3, with1mistake)).toEqual(map(with1mistake, [1]));
expect(getDistances(matcher3, with2mistakes)).toEqual(map(with2mistakes, [2]));
expect(getDistances(matcher3, with3mistakes)).toEqual(map(with3mistakes, [3]));
expect(getDistances(matcher3, noMatches)).toEqual(map(noMatches, []));
});
it("Should find all the matches", () => {
const matcher = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("oranges", 2);
const match = matcher.getMatch("I like orangs with oranges and some orans");
expect(match).toEqual([
{ endIndex: 13, distance: 1 },
{ endIndex: 26, distance: 0 },
{ endIndex: 41, distance: 2 },
]);
});
it("Should obtain the right distances", () => {
const matcher = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("stragled", 2);
const match = matcher.getMatch("where they sprawled amongst the tough stalks");
const match2 = matcher.getMatch("wedding guests straggled in pairs and groups");
expect(match.map(({ distance }) => distance)).toEqual([2]);
expect(match2.map(({ distance }) => distance)).toEqual([1]);
});
});
describe("FuzzyMultiWordMatcher.getMatchData", () => {
it("Should retrieve the change data", () => {
const matcher = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("potatlers", 2);
const match = matcher.getMatchData("I like potatoes in germany are freaking potaltles you know?");
expect(match.alterations.map(({ type }) => type)).toEqual(createAlterations("iiiiiiimmmmmrmsmiiiiiiiiiiiiiiiiiiiiiiiiimmmmammmsmiiiiiiiiii"));
expect(match.distances).toEqual([2, 2]);
const match2 = matcher.getMatchData("I like potatoes with poetatlers and potatlers");
expect(match2.alterations.map(({ type }) => type)).toEqual(createAlterations("iiiiiiimmmmmrmsmiiiiiimmammmmmmmiiiiimmmmmmmmm"));
expect(match2.distances).toEqual([2, 1, 0]);
const matcher2 = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("oranne", 2);
const match3 = matcher2.getMatchData("manner");
expect(match3.alterations.map(({ type }) => type)).toEqual(createAlterations("srmmmmi"));
});
it("Shouldn't match unfinished words", () => {
const matcher = new FuzzyMultiWordMatcher_1.FuzzyMultiWordMatcher("something", 2);
const match = matcher.getMatchData("I like to do so");
expect(match.alterations.map(({ type }) => type)).toEqual(createAlterations("iiiiiiiiiiiiiii"));
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRnV6enlNdWx0aVdvcmRNYXRjaGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2Z1enp5UmF0ZS93b3JkTWF0Y2hlci9fdGVzdHMvRnV6enlNdWx0aVdvcmRNYXRjaGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsb0VBQStEO0FBRS9EOzs7OztHQUtHO0FBQ0gsU0FBUyxZQUFZLENBQUMsT0FBOEIsRUFBRSxNQUFnQjtJQUNsRSxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDckIsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyQyxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdEMsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLEdBQUcsQ0FBSSxJQUFXLEVBQUUsS0FBUTtJQUNqQyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLGlCQUFpQixDQUFDLFdBQW1CO0lBQzFDLE1BQU0sQ0FBQyxHQUFHO1FBQ04sQ0FBQyxFQUFFLFFBQVE7UUFDWCxDQUFDLEVBQUUsT0FBTztRQUNWLENBQUMsRUFBRSxTQUFTO1FBQ1osQ0FBQyxFQUFFLFFBQVE7UUFDWCxDQUFDLEVBQUUsTUFBTTtLQUNaLENBQUM7SUFDRixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLHdCQUFDLENBQUMsQ0FBQyxDQUFtQixDQUFDLG1DQUFJLEVBQUUsR0FBQSxDQUFDLENBQUM7QUFDMUUsQ0FBQztBQUVELFFBQVEsQ0FBQyx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7SUFDbkMsUUFBUSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtRQUN2QyxFQUFFLENBQUMsZUFBZSxFQUFFLEdBQUcsRUFBRTtZQUNyQixJQUFJLDZDQUFxQixDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUMsQ0FBQyxDQUFDO0lBQ0gsUUFBUSxDQUFDLGdDQUFnQyxFQUFFLEdBQUcsRUFBRTtRQUM1QyxFQUFFLENBQUMsaURBQWlELEVBQUUsR0FBRyxFQUFFO1lBQ3ZELE1BQU0sT0FBTyxHQUFHLElBQUksNkNBQXFCLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3hELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztZQUNqRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDLENBQUM7WUFDekQsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQztnQkFDbEIsRUFBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUM7Z0JBQzNCLEVBQUMsUUFBUSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFDO2FBQzlCLENBQUMsQ0FBQztZQUNILE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxFQUFFLENBQUMsK0NBQStDLEVBQUUsR0FBRyxFQUFFO1lBQ3JELE1BQU0sUUFBUSxHQUFHLElBQUksNkNBQXFCLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sUUFBUSxHQUFHLElBQUksNkNBQXFCLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sUUFBUSxHQUFHLElBQUksNkNBQXFCLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sUUFBUSxHQUFHLElBQUksNkNBQXFCLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sT0FBTyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztZQUN2RCxNQUFNLFlBQVksR0FBRztnQkFDakIsZUFBZTtnQkFDZixlQUFlO2dCQUNmLG1CQUFtQjtnQkFDbkIsa0JBQWtCO2FBQ3JCLENBQUM7WUFDRixNQUFNLGFBQWEsR0FBRztnQkFDbEIsY0FBYztnQkFDZCxnQkFBZ0I7Z0JBQ2hCLG9CQUFvQjtnQkFDcEIsbUJBQW1CO2FBQ3RCLENBQUM7WUFDRixNQUFNLGFBQWEsR0FBRztnQkFDbEIsYUFBYTtnQkFDYixpQkFBaUI7Z0JBQ2pCLHFCQUFxQjtnQkFDckIsb0JBQW9CO2FBQ3ZCLENBQUM7WUFDRixNQUFNLFNBQVMsR0FBRztnQkFDZCxpQkFBaUI7Z0JBQ2pCLHNCQUFzQjtnQkFDdEIseUJBQXlCO2FBQzVCLENBQUM7WUFDRixNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM1RSxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUUsTUFBTSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlFLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN0RSxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0UsTUFBTSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlFLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RSxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdEUsTUFBTSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRSxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdFLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxDQUFD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