1
0
Fork 0
mirror of synced 2024-10-02 10:08:09 +13:00

Update test lucene builder and add more tests

This commit is contained in:
Peter Clement 2024-03-04 09:48:47 +00:00
parent 2933571c62
commit e3c514e45a
2 changed files with 116 additions and 69 deletions

View file

@ -391,43 +391,32 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
)
const docMatch = (doc: any) => {
// Determine active filters based on query object
const activeFilterKeys = Object.entries(query || {})
const filterFunctions = {
string: stringMatch,
fuzzy: fuzzyMatch,
range: rangeMatch,
equal: equalMatch,
notEqual: notEqualMatch,
empty: emptyMatch,
notEmpty: notEmptyMatch,
oneOf: oneOf,
contains: contains,
containsAny: containsAny,
notContains: notContains,
}
const activeFilterKeys: (keyof typeof filterFunctions)[] = Object.entries(
query
)
.filter(
([key, value]) =>
([key, value]: [string, any]) =>
!["allOr", "onEmptyFilter"].includes(key) &&
Object.keys(value).length > 0
Object.keys(value as Record<string, any>).length > 0
)
.map(([key]) => key)
.map(([key]) => key as keyof typeof filterFunctions)
// Apply filters dynamically based on activeFilterKeys
const results = activeFilterKeys.map(filterKey => {
switch (filterKey) {
case "string":
return stringMatch(doc)
case "fuzzy":
return fuzzyMatch(doc)
case "range":
return rangeMatch(doc)
case "equal":
return equalMatch(doc)
case "notEqual":
return notEqualMatch(doc)
case "empty":
return emptyMatch(doc)
case "notEmpty":
return notEmptyMatch(doc)
case "oneOf":
return oneOf(doc)
case "contains":
return contains(doc)
case "containsAny":
return containsAny(doc)
case "notContains":
return notContains(doc)
default:
return true // If the filter type is not recognized, default to true (assuming pass)
}
const results: boolean[] = activeFilterKeys.map(filterKey => {
const filterFunction = filterFunctions[filterKey]
return filterFunction ? filterFunction(doc) : true
})
if (query!.allOr) {
@ -436,7 +425,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
return results.every(result => result === true)
}
}
// Process all docs
return docs.filter(docMatch)
}

View file

@ -47,10 +47,7 @@ describe("runLuceneQuery", () => {
},
]
function buildQuery(
filterKey: string,
value: { [key: string]: any }
): SearchQuery {
function buildQuery(filters: { [filterKey: string]: any }): SearchQuery {
const query: SearchQuery = {
string: {},
fuzzy: {},
@ -63,8 +60,13 @@ describe("runLuceneQuery", () => {
notContains: {},
oneOf: {},
containsAny: {},
allOr: false,
}
query[filterKey as SearchQueryOperators] = value
for (const filterKey in filters) {
query[filterKey as SearchQueryOperators] = filters[filterKey]
}
return query
}
@ -73,16 +75,17 @@ describe("runLuceneQuery", () => {
})
it("should return matching rows for equal filter", () => {
const query = buildQuery("equal", {
order_status: 4,
const query = buildQuery({
equal: { order_status: 4 },
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([1, 2])
})
it("should return matching row for notEqual filter", () => {
const query = buildQuery("notEqual", {
order_status: 4,
const query = buildQuery({
notEqual: { order_status: 4 },
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([3])
})
@ -90,48 +93,56 @@ describe("runLuceneQuery", () => {
expect(
runLuceneQuery(
docs,
buildQuery("fuzzy", {
description: "sm",
buildQuery({
fuzzy: { description: "sm" },
})
).map(row => row.description)
).toEqual(["Small box"])
expect(
runLuceneQuery(
docs,
buildQuery("string", {
description: "SM",
buildQuery({
string: { description: "SM" },
})
).map(row => row.description)
).toEqual(["Small box"])
})
it("should return rows within a range filter", () => {
const query = buildQuery("range", {
customer_id: {
low: 500,
high: 1000,
const query = buildQuery({
range: {
customer_id: {
low: 500,
high: 1000,
},
},
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([3])
})
it("should return rows with numeric strings within a range filter", () => {
const query = buildQuery("range", {
customer_id: {
low: "500",
high: "1000",
const query = buildQuery({
range: {
customer_id: {
low: "500",
high: "1000",
},
},
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([3])
})
it("should return rows with ISO date strings within a range filter", () => {
const query = buildQuery("range", {
order_date: {
low: "2016-01-04T00:00:00.000Z",
high: "2016-01-11T00:00:00.000Z",
const query = buildQuery({
range: {
order_date: {
low: "2016-01-04T00:00:00.000Z",
high: "2016-01-11T00:00:00.000Z",
},
},
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([2])
})
@ -150,40 +161,87 @@ describe("runLuceneQuery", () => {
label: "",
},
]
const query = buildQuery("range", {
order_date: {
low: "2016-01-04T00:00:00.000Z",
high: "2016-01-11T00:00:00.000Z",
const query = buildQuery({
range: {
order_date: {
low: "2016-01-04T00:00:00.000Z",
high: "2016-01-11T00:00:00.000Z",
},
},
})
expect(runLuceneQuery(docs, query)).toEqual(docs)
})
it("should return rows with matches on empty filter", () => {
const query = buildQuery("empty", {
label: null,
const query = buildQuery({
empty: {
label: null,
},
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([1])
})
it("should return rows with matches on notEmpty filter", () => {
const query = buildQuery("notEmpty", {
label: null,
const query = buildQuery({
notEmpty: {
label: null,
},
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([2, 3])
})
test.each([[523, 259], "523,259"])(
"should return rows with matches on numeric oneOf filter",
input => {
let query = buildQuery("oneOf", {
customer_id: input,
const query = buildQuery({
oneOf: {
customer_id: input,
},
})
expect(runLuceneQuery(docs, query).map(row => row.customer_id)).toEqual([
259, 523,
])
}
)
it("should return matching results if allOr is true and only one filter matches", () => {
const query = buildQuery({
allOr: true,
oneOf: { staff_id: [10] },
contains: { description: ["box"] },
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([
1, 2, 3,
])
})
// what should the name of this test be if it's the same test as above but with different operands
it("should return matching results if allOr is true and only one filter matches with different operands", () => {
const query = buildQuery({
allOr: true,
equal: { order_status: 4 },
oneOf: { label: ["FRAGILE"] },
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([1, 2])
})
it("should return nothing if allOr is false and only one filter matches", () => {
const query = buildQuery({
allOr: false,
oneOf: { staff_id: [10] },
contains: { description: ["box"] },
})
expect(runLuceneQuery(docs, query).map(row => row.order_id)).toEqual([])
})
})
describe("buildLuceneQuery", () => {