Skip to content

Commit

Permalink
fix: rankItem in match-sorter-utils use threshold when using accessors (
Browse files Browse the repository at this point in the history
#4417)

- rankItem was not using the accessor specific threshold and neither the general threshold
- rankItem did not set `passed` to true when using accessors
  • Loading branch information
lucasra1 authored Oct 3, 2022
1 parent 4fc9895 commit 07d75ec
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 2 deletions.
103 changes: 103 additions & 0 deletions packages/match-sorter-utils/__tests__/match-sorter-utils.test.ts
Original file line number Diff line number Diff line change
@@ -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);
})
})
})
})
5 changes: 3 additions & 2 deletions packages/match-sorter-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export function rankItem<TItem>(

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
Expand All @@ -122,8 +122,9 @@ export function rankItem<TItem>(

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
Expand Down

0 comments on commit 07d75ec

Please sign in to comment.