philomena/assets/js/query/__tests__/term.spec.ts

132 lines
4.1 KiB
TypeScript
Raw Normal View History

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);
});
});