From 714881ad99fc82f833d359b9886a166f2df3303e Mon Sep 17 00:00:00 2001 From: zadam Date: Fri, 22 May 2020 19:08:06 +0200 Subject: [PATCH] more search tests + numeric label comparison --- spec/search.spec.js | 82 ++++++++++++++++++++++- src/services/search/comparator_builder.js | 19 ++++-- src/services/search/note_set.js | 2 +- 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/spec/search.spec.js b/spec/search.spec.js index 907e74e0a..19eb70345 100644 --- a/spec/search.spec.js +++ b/spec/search.spec.js @@ -61,6 +61,85 @@ describe("Search", () => { expect(searchResults.length).toEqual(1); expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); }); + + it("numeric label comparison", async () => { + rootNote.child( + note("Europe") + .label('country', '', true) + .child( + note("Austria") + .label('population', '8859000') + ) + .child( + note("Czech Republic") + .label('population', '10650000') + ) + ); + + const parsingContext = new ParsingContext(); + + const searchResults = await searchService.findNotesWithQuery('#country #population >= 10000000', parsingContext); + expect(searchResults.length).toEqual(1); + expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); + }); + + it("logical or", async () => { + rootNote.child( + note("Europe") + .label('country', '', true) + .child( + note("Austria") + .label('languageFamily', 'germanic') + ) + .child( + note("Czech Republic") + .label('languageFamily', 'slavic') + ) + .child( + note("Hungary") + .label('languageFamily', 'finnougric') + ) + ); + + const parsingContext = new ParsingContext(); + + const searchResults = await searchService.findNotesWithQuery('#languageFamily = slavic OR #languageFamily = germanic', parsingContext); + expect(searchResults.length).toEqual(2); + expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy(); + expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); + }); + + it("fuzzy attribute search", async () => { + rootNote.child( + note("Europe") + .label('country', '', true) + .child( + note("Austria") + .label('languageFamily', 'germanic') + ) + .child( + note("Czech Republic") + .label('languageFamily', 'slavic') + ) + ); + + let parsingContext = new ParsingContext({fuzzyAttributeSearch: false}); + + let searchResults = await searchService.findNotesWithQuery('#language', parsingContext); + expect(searchResults.length).toEqual(0); + + searchResults = await searchService.findNotesWithQuery('#languageFamily=ger', parsingContext); + expect(searchResults.length).toEqual(0); + + parsingContext = new ParsingContext({fuzzyAttributeSearch: true}); + + searchResults = await searchService.findNotesWithQuery('#language', parsingContext); + expect(searchResults.length).toEqual(2); + + searchResults = await searchService.findNotesWithQuery('#languageFamily=ger', parsingContext); + expect(searchResults.length).toEqual(1); + expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy(); + }); }); /** @return {Note} */ @@ -75,11 +154,12 @@ class NoteBuilder { this.note = note; } - label(name, value) { + label(name, value, isInheritable = false) { new Attribute(noteCache, { attributeId: id(), noteId: this.note.noteId, type: 'label', + isInheritable, name, value }); diff --git a/src/services/search/comparator_builder.js b/src/services/search/comparator_builder.js index 72c1103a8..ef589aacf 100644 --- a/src/services/search/comparator_builder.js +++ b/src/services/search/comparator_builder.js @@ -1,6 +1,6 @@ const dayjs = require("dayjs"); -const comparators = { +const stringComparators = { "=": comparedValue => (val => val === comparedValue), "!=": comparedValue => (val => val !== comparedValue), ">": comparedValue => (val => val > comparedValue), @@ -10,7 +10,14 @@ const comparators = { "*=": comparedValue => (val => val.endsWith(comparedValue)), "=*": comparedValue => (val => val.startsWith(comparedValue)), "*=*": comparedValue => (val => val.includes(comparedValue)), -} +}; + +const numericComparators = { + ">": comparedValue => (val => parseFloat(val) > comparedValue), + ">=": comparedValue => (val => parseFloat(val) >= comparedValue), + "<": comparedValue => (val => parseFloat(val) < comparedValue), + "<=": comparedValue => (val => parseFloat(val) <= comparedValue) +}; const smartValueRegex = /^(NOW|TODAY|WEEK|MONTH|YEAR) *([+\-] *\d+)?$/i; @@ -58,8 +65,12 @@ function buildComparator(operator, comparedValue) { comparedValue = calculateSmartValue(comparedValue); - if (operator in comparators) { - return comparators[operator](comparedValue); + if (operator in numericComparators && !isNaN(comparedValue)) { + return numericComparators[operator](parseFloat(comparedValue)); + } + + if (operator in stringComparators) { + return stringComparators[operator](comparedValue); } } diff --git a/src/services/search/note_set.js b/src/services/search/note_set.js index 287f2f6bd..ad22d5487 100644 --- a/src/services/search/note_set.js +++ b/src/services/search/note_set.js @@ -19,7 +19,7 @@ class NoteSet { } mergeIn(anotherNoteSet) { - this.notes = this.notes.concat(anotherNoteSet.arr); + this.notes = this.notes.concat(anotherNoteSet.notes); } minus(anotherNoteSet) {