From f6aaa6de58601dfd9352b553b7bdc29358b0fda5 Mon Sep 17 00:00:00 2001 From: "Patrik J. Braun" Date: Sun, 23 May 2021 18:05:12 +0200 Subject: [PATCH] Making "and" to be the default operator for search queries #309 --- src/common/SearchQueryParser.ts | 16 ++++++++-------- test/common/unit/SearchQueryParser.ts | 11 +++++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/common/SearchQueryParser.ts b/src/common/SearchQueryParser.ts index fe36788f..3760456b 100644 --- a/src/common/SearchQueryParser.ts +++ b/src/common/SearchQueryParser.ts @@ -85,7 +85,7 @@ export class SearchQueryParser { return Date.parse(text); } - public parse(str: string, implicitOR = true): SearchQueryDTO { + public parse(str: string, implicitAND = true): SearchQueryDTO { str = str.replace(/\s\s+/g, ' ') // remove double spaces .replace(/:\s+/g, ':').replace(/\)(?=\S)/g, ') ').trim(); @@ -123,25 +123,25 @@ export class SearchQueryParser { if (tokenEnd !== str.length - 1) { if (str.startsWith(' ' + this.keywords.and, tokenEnd)) { - const rest = this.parse(str.slice(tokenEnd + (' ' + this.keywords.and).length), implicitOR); + const rest = this.parse(str.slice(tokenEnd + (' ' + this.keywords.and).length), implicitAND); return { type: SearchQueryTypes.AND, - list: [this.parse(str.slice(0, tokenEnd), implicitOR), // trim brackets + list: [this.parse(str.slice(0, tokenEnd), implicitAND), // trim brackets ...(rest.type === SearchQueryTypes.AND ? (rest as SearchListQuery).list : [rest])] } as ANDSearchQuery; } else if (str.startsWith(' ' + this.keywords.or, tokenEnd)) { - const rest = this.parse(str.slice(tokenEnd + (' ' + this.keywords.or).length), implicitOR); + const rest = this.parse(str.slice(tokenEnd + (' ' + this.keywords.or).length), implicitAND); return { type: SearchQueryTypes.OR, - list: [this.parse(str.slice(0, tokenEnd), implicitOR), // trim brackets + list: [this.parse(str.slice(0, tokenEnd), implicitAND), // trim brackets ...(rest.type === SearchQueryTypes.OR ? (rest as SearchListQuery).list : [rest])] } as ORSearchQuery; } else { // Relation cannot be detected - const t = implicitOR === true ? SearchQueryTypes.OR : SearchQueryTypes.UNKNOWN_RELATION; - const rest = this.parse(str.slice(tokenEnd), implicitOR); + const t = implicitAND === true ? SearchQueryTypes.AND : SearchQueryTypes.UNKNOWN_RELATION; + const rest = this.parse(str.slice(tokenEnd), implicitAND); return { type: t, - list: [this.parse(str.slice(0, tokenEnd), implicitOR), // trim brackets + list: [this.parse(str.slice(0, tokenEnd), implicitAND), // trim brackets ...(rest.type === t ? (rest as SearchListQuery).list : [rest])] } as SearchListQuery; } diff --git a/test/common/unit/SearchQueryParser.ts b/test/common/unit/SearchQueryParser.ts index d3fba65c..59a689eb 100644 --- a/test/common/unit/SearchQueryParser.ts +++ b/test/common/unit/SearchQueryParser.ts @@ -116,6 +116,17 @@ describe('SearchQueryParser', () => { check({type: SearchQueryTypes.orientation, landscape: true} as OrientationSearch); check({type: SearchQueryTypes.orientation, landscape: false} as OrientationSearch); }); + it('Default logical operator should be AND', () => { + + const parser = new SearchQueryParser(queryKeywords); + expect(parser.parse('a b')).to.deep.equals({ + type: SearchQueryTypes.AND, + list: [ + {type: SearchQueryTypes.any_text, text: 'a'} as TextSearch, + {type: SearchQueryTypes.any_text, text: 'b'} as TextSearch + ] + } as ANDSearchQuery); + }); it('And search', () => { check({ type: SearchQueryTypes.AND,