Mailspring/packages/client-app/spec/services/search/search-query-parser-spec.es6
Mark Hahnenberg 2d2621d2f3 [client-app] Refactor search query codegen into proper backend
Summary:
Previously we were using the raw visitors that were confined to the flux
attributes directory. We're going to add more search query backends, so this
is mostly just moving things to a new, more general place.

Test Plan:
Run locally, verify parser specs still work, verify in-app search
still works.

Reviewers: spang, evan, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D4053
2017-03-01 11:53:03 -08:00

138 lines
5 KiB
JavaScript

import {
SearchQueryAST,
SearchQueryParser,
} from 'nylas-exports';
const {
SearchQueryToken,
OrQueryExpression,
AndQueryExpression,
FromQueryExpression,
ToQueryExpression,
SubjectQueryExpression,
GenericQueryExpression,
TextQueryExpression,
UnreadStatusQueryExpression,
StarredStatusQueryExpression,
InQueryExpression,
} = SearchQueryAST;
const token = (text) => { return new SearchQueryToken(text); }
const and = (e1, e2) => { return new AndQueryExpression(e1, e2); }
const or = (e1, e2) => { return new OrQueryExpression(e1, e2); }
const from = (text) => { return new FromQueryExpression(text); }
const to = (text) => { return new ToQueryExpression(text); }
const subject = (text) => { return new SubjectQueryExpression(text); }
const generic = (text) => { return new GenericQueryExpression(text); }
const in_ = (text) => { return new InQueryExpression(text); }
const text = (tok) => { return new TextQueryExpression(tok); }
const unread = (status) => { return new UnreadStatusQueryExpression(status); }
const starred = (status) => { return new StarredStatusQueryExpression(status); }
describe('SearchQueryParser.parse', () => {
it('correctly parses simple queries', () => {
expect(SearchQueryParser.parse('blah').equals(
generic(text(token('blah')))
)).toBe(true)
expect(SearchQueryParser.parse('"foo bar"').equals(
generic(text(token('foo bar')))
)).toBe(true)
expect(SearchQueryParser.parse('to:blah').equals(
to(text(token('blah')))
)).toBe(true)
expect(SearchQueryParser.parse('from:blah').equals(
from(text(token('blah')))
)).toBe(true)
expect(SearchQueryParser.parse('subject:blah').equals(
subject(text(token('blah')))
)).toBe(true)
expect(SearchQueryParser.parse('to:mhahnenb@gmail.com').equals(
to(text(token('mhahnenb@gmail.com')))
)).toBe(true)
expect(SearchQueryParser.parse('to:"mhahnenb@gmail.com"').equals(
to(text(token('mhahnenb@gmail.com')))
)).toBe(true)
expect(SearchQueryParser.parse('to:"Mark mhahnenb@gmail.com"').equals(
to(text(token('Mark mhahnenb@gmail.com')))
)).toBe(true)
expect(SearchQueryParser.parse('is:unread').equals(
unread(true)
)).toBe(true)
expect(SearchQueryParser.parse('is:read').equals(
unread(false)
)).toBe(true)
expect(SearchQueryParser.parse('is:starred').equals(
starred(true)
)).toBe(true)
expect(SearchQueryParser.parse('is:unstarred').equals(
starred(false)
)).toBe(true)
expect(SearchQueryParser.parse('in:foo').equals(
in_(text(token('foo')))
)).toBe(true)
});
it('correctly parses reserved words as normal text in certain places', () => {
expect(SearchQueryParser.parse('to:blah').equals(
to(text(token('blah')))
)).toBe(true)
expect(SearchQueryParser.parse('to:to').equals(
to(text(token('to')))
)).toBe(true)
expect(SearchQueryParser.parse('to:subject').equals(
to(text(token('subject')))
)).toBe(true)
expect(SearchQueryParser.parse('to:from').equals(
to(text(token('from')))
)).toBe(true)
expect(SearchQueryParser.parse('to:unread').equals(
to(text(token('unread')))
)).toBe(true)
expect(SearchQueryParser.parse('to:starred').equals(
to(text(token('starred')))
)).toBe(true)
});
it('correctly parses compound queries', () => {
expect(SearchQueryParser.parse('foo bar').equals(
and(generic(text(token('foo'))), generic(text(token('bar'))))
)).toBe(true)
expect(SearchQueryParser.parse('foo AND bar').equals(
and(generic(text(token('foo'))), generic(text(token('bar'))))
)).toBe(true)
expect(SearchQueryParser.parse('foo OR bar').equals(
or(generic(text(token('foo'))), generic(text(token('bar'))))
)).toBe(true)
expect(SearchQueryParser.parse('to:foo OR bar').equals(
or(to(text(token('foo'))), generic(text(token('bar'))))
)).toBe(true)
expect(SearchQueryParser.parse('foo OR to:bar').equals(
or(generic(text(token('foo'))), to(text(token('bar'))))
)).toBe(true)
expect(SearchQueryParser.parse('foo bar baz').equals(
and(generic(text(token('foo'))),
and(generic(text(token('bar'))), generic(text(token('baz')))))
)).toBe(true)
expect(SearchQueryParser.parse('foo AND bar AND baz').equals(
and(generic(text(token('foo'))),
and(generic(text(token('bar'))), generic(text(token('baz')))))
)).toBe(true)
expect(SearchQueryParser.parse('foo OR bar AND baz').equals(
and(
or(generic(text(token('foo'))), generic(text(token('bar')))),
generic(text(token('baz'))))
)).toBe(true)
expect(SearchQueryParser.parse('foo OR bar OR baz').equals(
or(generic(text(token('foo'))),
or(generic(text(token('bar'))), generic(text(token('baz')))))
)).toBe(true)
expect(SearchQueryParser.parse('foo is:unread').equals(
and(generic(text(token('foo'))), unread(true)),
)).toBe(true)
expect(SearchQueryParser.parse('is:unread foo').equals(
and(unread(true), generic(text(token('foo'))))
)).toBe(true)
});
});