- init
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { tokenize } from '../lexer';
|
||||
|
||||
const types = (s: string) => tokenize(s).map((t) => t.type);
|
||||
const values = (s: string) => tokenize(s).map((t) => t.value);
|
||||
|
||||
describe('lexer', () => {
|
||||
it('tokenizes numbers incl. decimals and exponents', () => {
|
||||
expect(values('1 2.5 .5 1e3 1.2E-3')).toEqual([
|
||||
'1',
|
||||
'2.5',
|
||||
'.5',
|
||||
'1e3',
|
||||
'1.2E-3',
|
||||
'',
|
||||
]);
|
||||
expect(types('42')).toEqual(['NUMBER', 'EOF']);
|
||||
});
|
||||
|
||||
it('tokenizes operators and punctuation', () => {
|
||||
expect(types('+-*/^():;!')).toEqual([
|
||||
'PLUS',
|
||||
'MINUS',
|
||||
'STAR',
|
||||
'SLASH',
|
||||
'CARET',
|
||||
'LPAREN',
|
||||
'RPAREN',
|
||||
'COLON',
|
||||
'SEMICOLON',
|
||||
'BANG',
|
||||
'EOF',
|
||||
]);
|
||||
});
|
||||
|
||||
it('reads bare words as IDENT (cell refs, functions, sheet names alike)', () => {
|
||||
expect(types('SUM(A1:B2)')).toEqual([
|
||||
'IDENT',
|
||||
'LPAREN',
|
||||
'IDENT',
|
||||
'COLON',
|
||||
'IDENT',
|
||||
'RPAREN',
|
||||
'EOF',
|
||||
]);
|
||||
});
|
||||
|
||||
it('reads single-quoted sheet names with spaces', () => {
|
||||
const t = tokenize("'Kosten Q3'!B2");
|
||||
expect(t[0]).toMatchObject({ type: 'QUOTED', value: 'Kosten Q3' });
|
||||
expect(t[1].type).toBe('BANG');
|
||||
expect(t[2]).toMatchObject({ type: 'IDENT', value: 'B2' });
|
||||
});
|
||||
|
||||
it('handles escaped double-quoted strings', () => {
|
||||
expect(tokenize('"a\\"b"')[0]).toMatchObject({ type: 'STRING', value: 'a"b' });
|
||||
});
|
||||
|
||||
it('skips whitespace', () => {
|
||||
expect(types(' A1\t+\n B2 ')).toEqual(['IDENT', 'PLUS', 'IDENT', 'EOF']);
|
||||
});
|
||||
|
||||
it('throws on an unexpected character', () => {
|
||||
expect(() => tokenize('A1 & B2')).toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user