import { getSituation } from '../completion/situation'; describe('getSituation', () => { describe('EMPTY', () => { it('returns EMPTY for empty text', () => { expect(getSituation('', 0)).toEqual({ type: 'EMPTY' }); }); }); describe('IN_WITH_BODY', () => { it('returns IN_WITH_BODY when cursor is after with block', () => { const text = 'with (cpu = sum(rate(foo[5m])))\ncpu'; // find the second occurrence of 'cpu' (after the with block) const firstCpu = text.indexOf('cpu'); const pos = text.indexOf('cpu', firstCpu + 1); const result = getSituation(text, pos); expect(result).toEqual({ type: 'IN_WITH_BODY' }); }); it('returns IN_WITH_BODY for simple with expression', () => { const text = 'with (a = foo) a'; const pos = text.length; // cursor at end const result = getSituation(text, pos); expect(result).toEqual({ type: 'IN_WITH_BODY' }); }); it('returns IN_WITH_BODY for multi-CTE with expressions', () => { const text = 'with (x = rate(foo[5m]), y = sum(bar))\nx + y'; const pos = text.length; const result = getSituation(text, pos); expect(result).toEqual({ type: 'IN_WITH_BODY' }); }); it('does NOT return IN_WITH_BODY when cursor is before closing paren', () => { const text = 'with (a = foo|) a'; const pipePos = text.indexOf('|'); const cleanText = text.slice(0, pipePos) + text.slice(pipePos + 1); const result = getSituation(cleanText, pipePos); expect(result?.type).not.toBe('IN_WITH_BODY'); }); it('does NOT return IN_WITH_BODY for regular query starting with identifier containing "with"', () => { const text = 'without_cpu'; const pos = text.length; const result = getSituation(text, pos); expect(result?.type).not.toBe('IN_WITH_BODY'); }); }); describe('AT_ROOT', () => { it('returns AT_ROOT for simple metric name', () => { const text = 'node_cpu_seconds_total'; const pos = text.length; const result = getSituation(text, pos); expect(result).toEqual({ type: 'AT_ROOT' }); }); it('returns AT_ROOT for function call', () => { const text = 'rate(node_cpu_seconds_total[5m])'; const pos = text.length; const result = getSituation(text, pos); expect(result).toEqual({ type: 'AT_ROOT' }); }); }); describe('IN_FUNCTION', () => { it('returns IN_FUNCTION inside function body', () => { const text = 'sum()'; const pos = text.indexOf(')'); const result = getSituation(text, pos); expect(result?.type).toBe('IN_FUNCTION'); }); }); describe('IN_DURATION', () => { it('returns a situation for incomplete duration', () => { // Cursor just after `[` but before `]` should trigger some situation const text = 'foo[5'; const pos = text.length; const result = getSituation(text, pos); // Result depends on exact parse tree; not null for valid/incomplete input expect(result).toBeDefined(); }); }); });