diff --git a/packages/match-sorter-utils/__tests__/match-sorter-utils.test.ts b/packages/match-sorter-utils/__tests__/match-sorter-utils.test.ts new file mode 100644 index 0000000000..407b59f43c --- /dev/null +++ b/packages/match-sorter-utils/__tests__/match-sorter-utils.test.ts @@ -0,0 +1,103 @@ +import {rankings, rankItem} from "../src"; + +interface Person { + firstName: string; + lastName: string; + email: string; +} + + +const testPerson: Person = { + firstName: "John", + lastName: "Doe", + email: "j.doe@email.com" +} + +describe("match-sorter-utils", () => { + describe("rankItem", () => { + describe("with accessorFn", () => { + it("CASE_SENSITIVE_EQUAL", () => { + const ranking = rankItem(testPerson, "John", {accessors: [item => item.firstName, item => item.lastName, item => item.email]}) + expect(ranking.rank).toBe(rankings.CASE_SENSITIVE_EQUAL); + expect(ranking.passed).toBe(true); + expect(ranking.rankedValue).toBe(testPerson.firstName); + expect(ranking.accessorIndex).toBe(0); + expect(ranking.accessorThreshold).toBe(1); + }) + + it("NO_MATCH", () => { + const ranking = rankItem(testPerson, "Tom", {accessors: [item => item.firstName, item => item.lastName, item => item.email]}) + expect(ranking.rank).toBe(rankings.NO_MATCH); + expect(ranking.passed).toBe(false); + expect(ranking.rankedValue).toBe(testPerson); + expect(ranking.accessorIndex).toBe(-1); + expect(ranking.accessorThreshold).toBe(1); + }) + }) + + describe("with accessorOptions and custom Threshold", () => { + it("CASE_SENSITIVE_EQUAL", () => { + const ranking = rankItem(testPerson, "John", { + accessors: [{ + accessor: item => item.firstName, + threshold: rankings.CONTAINS + }, { + accessor: item => item.lastName, + threshold: rankings.CONTAINS + }, { + accessor: item => item.email, + threshold: rankings.MATCHES + }] + }) + expect(ranking.rank).toBe(rankings.CASE_SENSITIVE_EQUAL); + expect(ranking.passed).toBe(true); + expect(ranking.rankedValue).toBe(testPerson.firstName); + expect(ranking.accessorIndex).toBe(0); + expect(ranking.accessorThreshold).toBe(rankings.CONTAINS); + }) + + it("ACRONYM but threshold is CONTAINS", () => { + const ranking = rankItem(testPerson, "jd", { + threshold: rankings.ACRONYM, + accessors: [{ + accessor: item => item.firstName, + threshold: rankings.CONTAINS + }, { + accessor: item => item.lastName, + threshold: rankings.CONTAINS + }, { + accessor: item => `${item.firstName} ${item.lastName}`, + threshold: rankings.CONTAINS + }, { + accessor: item => item.email, + threshold: rankings.CONTAINS + }] + }) + expect(ranking.rank).toBe(rankings.NO_MATCH); + expect(ranking.passed).toBe(false); + expect(ranking.rankedValue).toBe(testPerson); + expect(ranking.accessorIndex).toBe(-1); + expect(ranking.accessorThreshold).toBe(rankings.ACRONYM); + }) + + it("NO_MATCH", () => { + const ranking = rankItem(testPerson, "Tom", { + accessors: [{ + accessor: item => item.firstName, + threshold: rankings.CONTAINS + }, { + accessor: item => item.lastName, + threshold: rankings.CONTAINS + }, { + accessor: item => item.email, + threshold: rankings.MATCHES + }]}) + expect(ranking.rank).toBe(rankings.NO_MATCH); + expect(ranking.passed).toBe(false); + expect(ranking.rankedValue).toBe(testPerson); + expect(ranking.accessorIndex).toBe(-1); + expect(ranking.accessorThreshold).toBe(1); + }) + }) + }) +}) diff --git a/packages/match-sorter-utils/src/index.ts b/packages/match-sorter-utils/src/index.ts index 4c91e1c9b4..3b8805e9ca 100755 --- a/packages/match-sorter-utils/src/index.ts +++ b/packages/match-sorter-utils/src/index.ts @@ -112,7 +112,7 @@ export function rankItem( let newRank = getMatchRanking(rankValue.itemValue, value, options) - const { minRanking, maxRanking, threshold } = rankValue.attributes + const { minRanking, maxRanking, threshold = options.threshold } = rankValue.attributes if (newRank < minRanking && newRank >= rankings.MATCHES) { newRank = minRanking @@ -122,8 +122,9 @@ export function rankItem( newRank = Math.min(newRank, maxRanking) as Ranking - if (newRank > rankingInfo.rank) { + if (newRank >= threshold && newRank > rankingInfo.rank) { rankingInfo.rank = newRank + rankingInfo.passed = true rankingInfo.accessorIndex = i rankingInfo.accessorThreshold = threshold rankingInfo.rankedValue = rankValue.itemValue