UNPKG

bramble-parser

Version:

Bramble is a lightweight recursive descent parser that processes .havenfs files, returning a structured Json tree that can be used to construct an in-memory FS representation. The parser is based on line-based grammar, chunk headers, and metadata declarat

83 lines (65 loc) 2.9 kB
import * as fs from 'fs'; import { describe, test, expect, vi, beforeEach } from 'bun:test'; import { ELexerTokens } from '../../src/common'; import { BrambleLexer } from '../../src/lexer/brambleLexer'; describe('Tokenisation of HIST Headers', () => { beforeEach(() => { vi.restoreAllMocks(); }); test('Correctly tokenises a complete HIST line', () => { const fakeContent = 'HIST f1a7e 20250625T1230 user=ellie action=created hash=abc123\n'; vi.spyOn(fs, 'readFileSync').mockReturnValue(fakeContent); const lexer = new BrambleLexer('./test/test.example.havenfs'); lexer.tokenize(); const filteredTokens = lexer.tokens.filter(t => t.type !== ELexerTokens.WHITESPACE); const [ tokenHist, tokenId, tokenTimestamp, tokenUser, tokenOpUser, tokenUserVal, tokenAction, tokenOpAction, tokenActionVal, tokenHashAttr, tokenOpHash, tokenHashVal, tokenNewline ] = filteredTokens; console.log(ELexerTokens[tokenActionVal.type]); expect(tokenHist.type).toBe(ELexerTokens.KW_HIST); expect(tokenId.type).toBe(ELexerTokens.ID); expect(tokenTimestamp.type).toBe(ELexerTokens.TIMESTAMP); expect(tokenUser.type).toBe(ELexerTokens.ATT_USER); expect(tokenOpUser.type).toBe(ELexerTokens.OPERATOR); expect(tokenUserVal.type).toBe(ELexerTokens.STRING); expect(tokenAction.type).toBe(ELexerTokens.ATT_ACTION); expect(tokenOpAction.type).toBe(ELexerTokens.OPERATOR); expect(tokenActionVal.type).toBe(ELexerTokens.ATT_CREATED); expect(tokenHashAttr.type).toBe(ELexerTokens.ATT_HASH); expect(tokenOpHash.type).toBe(ELexerTokens.OPERATOR); expect(tokenHashVal.type).toBe(ELexerTokens.ID); expect(tokenNewline.type).toBe(ELexerTokens.NEWLINE); }); test('Correctly tokenises a minimal HIST line', () => { const fakeContent = 'HIST f1a7e 20250625T1230\n'; vi.spyOn(fs, 'readFileSync').mockReturnValue(fakeContent); const lexer = new BrambleLexer('./test/test.example.havenfs'); lexer.tokenize(); const filteredTokens = lexer.tokens.filter(t => t.type !== ELexerTokens.WHITESPACE); expect(filteredTokens[0].type).toBe(ELexerTokens.KW_HIST); expect(filteredTokens[1].type).toBe(ELexerTokens.ID); expect(filteredTokens[2].type).toBe(ELexerTokens.TIMESTAMP); expect(filteredTokens[3].type).toBe(ELexerTokens.NEWLINE); }); test('Detects absence of ID after HIST', () => { const fakeContent = 'HIST\n'; vi.spyOn(fs, 'readFileSync').mockReturnValue(fakeContent); const lexer = new BrambleLexer('./test/test.example.havenfs'); lexer.tokenize(); const filteredTokens = lexer.tokens.filter(t => t.type !== ELexerTokens.WHITESPACE); expect(filteredTokens[0].type).toBe(ELexerTokens.KW_HIST); expect(filteredTokens[1].type).toBe(ELexerTokens.NEWLINE); // No ID present }); });