diff --git a/tests/lib/philomena/search/QueryLexer.spec.ts b/tests/lib/philomena/search/QueryLexer.spec.ts index 1c7e9d3..634c0de 100644 --- a/tests/lib/philomena/search/QueryLexer.spec.ts +++ b/tests/lib/philomena/search/QueryLexer.spec.ts @@ -1,10 +1,55 @@ -import { QueryLexer, QuotedTermToken, Token } from "$lib/philomena/search/QueryLexer"; +import { + AndToken, GroupEndToken, GroupStartToken, + NotToken, + OrToken, + QueryLexer, + QuotedTermToken, + TermToken, + Token +} from "$lib/philomena/search/QueryLexer"; describe('QueryLexer', () => { function parseQuery(query: string): Token[] { return new QueryLexer(query).parse(); } + function parseQueryTypes(query: string): (typeof Token)[] { + return parseQuery(query) + .map(term => (term.constructor as any) as typeof Token); + } + + it('should properly parse different kinds of queries', () => { + expect(parseQueryTypes('safe')).toEqual([TermToken]); + expect(parseQueryTypes('safe, avali')).toEqual([TermToken, AndToken, TermToken]); + expect(parseQueryTypes('!avali')).toEqual([NotToken, TermToken]); + expect(parseQueryTypes('avali || 4 ears')).toEqual([TermToken, OrToken, TermToken]); + expect(parseQueryTypes('avali && !4 ears')).toEqual([TermToken, AndToken, NotToken, TermToken]); + + expect(parseQueryTypes('avali AND (!4 ears OR -3 fingers)')).toEqual([ + TermToken, AndToken, GroupStartToken, NotToken, TermToken, OrToken, NotToken, TermToken, GroupEndToken, + ]); + }); + + it('should not treat parentheses as groups inside the term', () => { + expect(parseQueryTypes('!(experiment (casualties unknown) || milky (casualties unknown))')).toEqual([ + NotToken, GroupStartToken, TermToken, OrToken, TermToken, GroupEndToken, + ]); + }); + + it('should accept any amount of whitespaces between different tokens', () => { + expect(parseQueryTypes('! ( avali , experiment (casualties unknown) ) && safe')).toEqual([ + NotToken, GroupStartToken, TermToken, AndToken, TermToken, GroupEndToken, AndToken, TermToken, + ]); + }); + + it('should trim whitespaces inside the terms, even in quoted ones', () => { + const [termWithSpaces] = parseQuery(' avali '); + expect(termWithSpaces.value).toBe('avali'); + + const [quotedTermWithSpaces] = parseQuery(' " avali " '); + expect(quotedTermWithSpaces instanceof QuotedTermToken && quotedTermWithSpaces.decodedValue || new Error('Wrong token')).toBe('avali'); + }); + describe('QuotedTermToken', () => { it('should decode and encode quotes and backslash', () => { const encodedQuote = `"term with \\\" inside of it"`;