diff --git a/kitty/search_query_parser.py b/kitty/search_query_parser.py index 0f64d7a9f..bd89cdb86 100644 --- a/kitty/search_query_parser.py +++ b/kitty/search_query_parser.py @@ -223,13 +223,15 @@ class Parser: return self.base_token() def base_token(self) -> SearchTreeNode: - tt = self.token(advance=True) - assert tt is not None if self.token_type() is TokenType.QUOTED_WORD: + tt = self.token(advance=True) + assert tt is not None if self.allow_no_location: return TokenNode('all', tt) raise ParseException(f'No location specified before {tt}') + tt = self.token(advance=True) + assert tt is not None words = tt.split(':') # The complexity here comes from having colon-separated search # values. That forces us to check that the first "word" in a colon- diff --git a/kitty_tests/search_query_parser.py b/kitty_tests/search_query_parser.py index 19c55e621..9e93a012d 100644 --- a/kitty_tests/search_query_parser.py +++ b/kitty_tests/search_query_parser.py @@ -8,20 +8,23 @@ from . import BaseTest class TestSQP(BaseTest): def test_search_query_parser(self): - from kitty.search_query_parser import search + from kitty.search_query_parser import search, ParseException locations = 'id' universal_set = {1, 2, 3, 4, 5} def get_matches(location, query, candidates): return {x for x in candidates if query == str(x)} - def t(q, expected): + def t(q, expected=set()): actual = search(q, locations, universal_set, get_matches) self.ae(actual, expected) t('id:1', {1}) + t('id:"1"', {1}) t('id:1 and id:1', {1}) t('id:1 or id:2', {1, 2}) - t('id:1 and id:2', set()) + t('id:1 and id:2') t('not id:1', universal_set - {1}) t('(id:1 or id:2) and id:1', {1}) + self.assertRaises(ParseException, t, '1') + self.assertRaises(ParseException, t, '"id:1"')