96 SUCCESS tests complet
This commit is contained in:
@@ -1,35 +1,6 @@
|
||||
import { detectQueryType, parseSearchQuery, queryToPredicate } from './search-parser';
|
||||
import { SearchContext } from './search-parser.types';
|
||||
|
||||
type TestFn = () => void;
|
||||
|
||||
interface TestResult {
|
||||
name: string;
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
const testResults: TestResult[] = [];
|
||||
|
||||
const runTest = (name: string, fn: TestFn): void => {
|
||||
try {
|
||||
fn();
|
||||
testResults.push({ name });
|
||||
} catch (error) {
|
||||
testResults.push({ name, error: error instanceof Error ? error : new Error(String(error)) });
|
||||
console.error(`[search-parser spec] ${name} failed`, error);
|
||||
}
|
||||
};
|
||||
|
||||
const assert = (condition: boolean, message: string): void => {
|
||||
if (!condition) {
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
|
||||
const assertEqual = <T>(actual: T, expected: T, message: string): void => {
|
||||
assert(actual === expected, `${message} (expected ${expected}, received ${actual})`);
|
||||
};
|
||||
|
||||
const createContext = (overrides: Partial<SearchContext> = {}): SearchContext => ({
|
||||
filePath: 'notes/example.md',
|
||||
fileName: 'example',
|
||||
@@ -47,55 +18,55 @@ const createContext = (overrides: Partial<SearchContext> = {}): SearchContext =>
|
||||
...overrides
|
||||
});
|
||||
|
||||
runTest('parseSearchQuery marks empty query as empty', () => {
|
||||
const parsed = parseSearchQuery('');
|
||||
assert(parsed.isEmpty, 'Empty query should be flagged as empty');
|
||||
assertEqual(parsed.ast.type, 'group', 'Empty query AST should be an empty group');
|
||||
});
|
||||
describe('Search Parser', () => {
|
||||
it('parseSearchQuery marks empty query as empty', () => {
|
||||
const parsed = parseSearchQuery('');
|
||||
expect(parsed.isEmpty).toBeTrue();
|
||||
expect(parsed.ast.type).toBe('group');
|
||||
});
|
||||
|
||||
runTest('parseSearchQuery handles basic text queries', () => {
|
||||
const parsed = parseSearchQuery('hello world');
|
||||
assert(!parsed.isEmpty, 'Non-empty query should not be marked empty');
|
||||
assertEqual(parsed.ast.type, 'group', 'Text query AST should be a group');
|
||||
});
|
||||
it('parseSearchQuery handles basic text queries', () => {
|
||||
const parsed = parseSearchQuery('hello world');
|
||||
expect(parsed.isEmpty).toBeFalse();
|
||||
expect(parsed.ast.type).toBe('group');
|
||||
});
|
||||
|
||||
runTest('parseSearchQuery handles operators', () => {
|
||||
const parsed = parseSearchQuery('path:notes/ tag:#tag file:example');
|
||||
assert(!parsed.isEmpty, 'Operator query should parse successfully');
|
||||
});
|
||||
it('parseSearchQuery handles operators', () => {
|
||||
const parsed = parseSearchQuery('path:notes/ tag:#tag file:example');
|
||||
expect(parsed.isEmpty).toBeFalse();
|
||||
});
|
||||
|
||||
runTest('queryToPredicate matches simple text', () => {
|
||||
const predicate = queryToPredicate(parseSearchQuery('hello'));
|
||||
assert(predicate(createContext()), 'Predicate should match when text is present');
|
||||
});
|
||||
it('queryToPredicate matches simple text', () => {
|
||||
const predicate = queryToPredicate(parseSearchQuery('hello'));
|
||||
expect(predicate(createContext())).toBeTrue();
|
||||
});
|
||||
|
||||
runTest('queryToPredicate respects negation', () => {
|
||||
const predicate = queryToPredicate(parseSearchQuery('-deprecated'));
|
||||
assert(predicate(createContext()), 'Predicate should pass when term is absent');
|
||||
assert(!predicate(createContext({ content: 'deprecated feature' })), 'Predicate should fail when negated term exists');
|
||||
});
|
||||
it('queryToPredicate respects negation', () => {
|
||||
const predicate = queryToPredicate(parseSearchQuery('-deprecated'));
|
||||
expect(predicate(createContext())).toBeTrue();
|
||||
expect(predicate(createContext({ content: 'deprecated feature' }))).toBeFalse();
|
||||
});
|
||||
|
||||
runTest('queryToPredicate matches task scopes', () => {
|
||||
const todoPredicate = queryToPredicate(parseSearchQuery('task-todo:Call'));
|
||||
const donePredicate = queryToPredicate(parseSearchQuery('task-done:Review'));
|
||||
assert(todoPredicate(createContext()), 'task-todo should match incomplete tasks');
|
||||
assert(donePredicate(createContext()), 'task-done should match completed tasks');
|
||||
});
|
||||
it('queryToPredicate matches task scopes', () => {
|
||||
const todoPredicate = queryToPredicate(parseSearchQuery('task-todo:Call'));
|
||||
const donePredicate = queryToPredicate(parseSearchQuery('task-done:Review'));
|
||||
expect(todoPredicate(createContext())).toBeTrue();
|
||||
expect(donePredicate(createContext())).toBeTrue();
|
||||
});
|
||||
|
||||
runTest('detectQueryType recognises path prefix', () => {
|
||||
const info = detectQueryType('path:notes');
|
||||
assertEqual(info.type, 'path', 'Should recognise path prefix');
|
||||
assertEqual(info.value, 'notes', 'Should capture path value');
|
||||
});
|
||||
it('detectQueryType recognises path prefix', () => {
|
||||
const info = detectQueryType('path:notes');
|
||||
expect(info.type).toBe('path');
|
||||
expect(info.value).toBe('notes');
|
||||
});
|
||||
|
||||
runTest('detectQueryType recognises property bracket', () => {
|
||||
const info = detectQueryType('[status:');
|
||||
assertEqual(info.type, 'property', 'Should recognise property prefix');
|
||||
});
|
||||
it('detectQueryType recognises property bracket', () => {
|
||||
const info = detectQueryType('[status:');
|
||||
expect(info.type).toBe('property');
|
||||
});
|
||||
|
||||
runTest('detectQueryType falls back to general type', () => {
|
||||
const info = detectQueryType('plain text');
|
||||
assertEqual(info.type, 'general', 'General text should return general type');
|
||||
it('detectQueryType falls back to general type', () => {
|
||||
const info = detectQueryType('plain text');
|
||||
expect(info.type).toBe('general');
|
||||
});
|
||||
});
|
||||
|
||||
export { testResults };
|
||||
|
||||
Reference in New Issue
Block a user