import { getAstMatcherForTerm } from '../term'; import { MatcherFactory, defaultMatcher } from '../matcher'; import { termSpaceToImageField } from '../fields'; function noMatch() { return false; } class TestMatcherFactory implements MatcherFactory { public dateVals: string[]; public literalVals: string[]; public numberVals: number[]; public userVals: string[]; constructor() { this.dateVals = []; this.literalVals = []; this.numberVals = []; this.userVals = []; } makeDateMatcher(term: string) { this.dateVals.push(term); return noMatch; } makeLiteralMatcher(term: string) { this.literalVals.push(term); return noMatch; } makeNumberMatcher(term: number) { this.numberVals.push(term); return noMatch; } makeUserMatcher(term: string) { this.userVals.push(term); return noMatch; } } describe('Search terms', () => { let factory: TestMatcherFactory; beforeEach(() => { factory = new TestMatcherFactory(); }); it('should parse the default field', () => { getAstMatcherForTerm('default', 0, factory); expect(factory.literalVals).toEqual(['default']); }); it('should parse the default field with wildcarding', () => { getAstMatcherForTerm('def?ul*', 0, factory); expect(factory.literalVals).toEqual(['def?ul*']); }); it('should parse the default field with fuzzing', () => { getAstMatcherForTerm('default', 1, factory); expect(factory.literalVals).toEqual(['default']); }); it('should parse the default field within quotes', () => { getAstMatcherForTerm('"default"', 0, factory); expect(factory.literalVals).toEqual(['default']); }); it('should parse exact date field values', () => { getAstMatcherForTerm('created_at:2024', 0, factory); expect(factory.dateVals).toEqual(['2024']); }); it('should parse ranged date field values', () => { getAstMatcherForTerm('created_at.lte:2024', 0, factory); getAstMatcherForTerm('created_at.lt:2024', 0, factory); getAstMatcherForTerm('created_at.gte:2024', 0, factory); getAstMatcherForTerm('created_at.gt:2024', 0, factory); expect(factory.dateVals).toEqual(['2024', '2024', '2024', '2024']); }); it('should parse exact number field values', () => { getAstMatcherForTerm('width:1920', 0, factory); expect(factory.numberVals).toEqual([1920]); }); it('should parse ranged number field values', () => { getAstMatcherForTerm('width.lte:1920', 0, factory); getAstMatcherForTerm('width.lt:1920', 0, factory); getAstMatcherForTerm('width.gte:1920', 0, factory); getAstMatcherForTerm('width.gt:1920', 0, factory); expect(factory.numberVals).toEqual([1920, 1920, 1920, 1920]); }); it('should parse literal field values', () => { getAstMatcherForTerm('source_url:*twitter*', 0, factory); expect(factory.literalVals).toEqual(['*twitter*']); }); it('should parse user field values', () => { getAstMatcherForTerm('my:upvotes', 0, factory); getAstMatcherForTerm('my:downvotes', 0, factory); getAstMatcherForTerm('my:faves', 0, factory); expect(factory.userVals).toEqual(['upvotes', 'downvotes', 'faves']); }); it('should match document with proper field values', () => { const idMatcher = getAstMatcherForTerm('id.lt:1', 0, defaultMatcher); const sourceMatcher = getAstMatcherForTerm('source_url:twitter.com', 0, defaultMatcher); const idAttribute = termSpaceToImageField.id; const sourceUrlAttribute = termSpaceToImageField.source_url; const properElement = document.createElement('div'); properElement.setAttribute(idAttribute, '0'); properElement.setAttribute(sourceUrlAttribute, 'twitter.com'); expect(idMatcher(properElement)).toBe(true); expect(sourceMatcher(properElement)).toBe(true); }); it('should not match document without field values', () => { const idMatcher = getAstMatcherForTerm('id.lt:1', 0, defaultMatcher); const sourceMatcher = getAstMatcherForTerm('source_url:twitter.com', 0, defaultMatcher); const improperElement = document.createElement('div'); expect(idMatcher(improperElement)).toBe(false); expect(sourceMatcher(improperElement)).toBe(false); }); });