llparse Test Fixture
raw JSON →llparse-test-fixture is a utility package designed to provide a consistent and controlled environment for testing parsers generated by `llparse` and other `llparse`-based modules. `llparse` itself is an API for compiling incremental parsers into highly optimized C output, often used in performance-critical applications like `llhttp` (the HTTP parser in Node.js). This fixture, currently at version 5.1.0, facilitates the creation of test cases, feeding input data, and asserting on the behavior and output of such low-level parsers. It primarily serves as a development dependency for projects that utilize `llparse` to ensure the correctness and robustness of their generated parsers, offering abstractions to simplify complex parsing scenarios in tests. Its release cadence is likely tied to updates in the core `llparse` project. It differentiates itself by providing specialized tools for a generated C-based parser, contrasting with general-purpose testing libraries.
Common errors
error Error: Cannot find module 'llparse-test-fixture' ↓
npm install llparse-test-fixture or yarn add llparse-test-fixture. For CJS projects, ensure proper transpilation or switch to ESM if possible, as the library is primarily designed for ESM. error TypeError: Cannot read properties of undefined (reading 'on_data') ↓
createFixture call to ensure all expected llparse callbacks are provided. Consult the documentation for your llparse-generated parser to confirm the exact callback API. error TS2742: The inferred type of '...' cannot be named without a reference to '.../node_modules/llparse-test-fixture/index.d.ts'. This is likely not portable. A type annotation is necessary. ↓
import type { IParsedEvent } from 'llparse-test-fixture'; for type-only imports, or add explicit type annotations to variables where the complex type is inferred. Warnings
breaking Major versions of `llparse-test-fixture` are typically tied to `llparse` itself. Upgrading `llparse` may require upgrading the fixture, as internal APIs or expected parser behavior might change, leading to test failures or incorrect mock interactions. ↓
gotcha When testing `llparse`-generated C code (e.g., via `napi-rs` or direct C++ bindings), ensure your testing environment has the necessary C/C++ toolchain configured. Mismatched compiler versions or missing build tools can lead to compilation errors during test setup. ↓
gotcha Asynchronous event handling in `llparse` parsers (e.g., `on_data` callbacks) can lead to race conditions or incomplete test assertions if not properly awaited. Tests might pass spuriously if assertions run before all parser events have fired. ↓
Install
npm install llparse-test-fixture yarn add llparse-test-fixture pnpm add llparse-test-fixture Imports
- createFixture wrong
const createFixture = require('llparse-test-fixture').createFixture;correctimport { createFixture } from 'llparse-test-fixture'; - ParserTestStream wrong
import ParserTestStream from 'llparse-test-fixture/stream';correctimport { ParserTestStream } from 'llparse-test-fixture'; - IParsedEvent wrong
import { IParsedEvent } from 'llparse-test-fixture';correctimport type { IParsedEvent } from 'llparse-test-fixture';
Quickstart
import { createFixture, ParserTestStream, IParsedEvent } from 'llparse-test-fixture';
// Assume 'my-llparse-parser' is a module that exports a class
// generated by llparse, with a parse() method and event callbacks.
// For demonstration, we'll mock a simple parser structure.
interface MyParserCallbackEvents {
on_data?: (value: number) => void;
on_complete?: () => void;
}
class MockLLParseParser {
private callbacks: MyParserCallbackEvents = {};
constructor(callbacks: MyParserCallbackEvents) {
this.callbacks = callbacks;
}
// Simulate parsing, calling callbacks based on input
parse(data: Buffer): number {
for (const byte of data) {
if (byte === 0x01 && this.callbacks.on_data) {
this.callbacks.on_data(byte);
} else if (byte === 0x02 && this.callbacks.on_complete) {
this.callbacks.on_complete();
}
}
return data.length;
}
// Simulate reinitialization
reset(): void {
console.log('Parser reset.');
}
}
describe('My LLParse Parser', () => {
it('should parse simple data and trigger complete event', async () => {
const events: IParsedEvent[] = [];
const fixture = createFixture(MockLLParseParser, {
on_data: (value) => events.push({ type: 'data', value }),
on_complete: () => events.push({ type: 'complete' })
});
const parser = fixture.parser; // Access the mocked parser instance
const stream = new ParserTestStream(parser);
stream.feed(Buffer.from([0x01, 0x01]));
stream.feed(Buffer.from([0x02]));
stream.end();
// Wait for all async parsing to settle if applicable (mocked here as sync)
await new Promise(resolve => setImmediate(resolve));
expect(events).toEqual([
{ type: 'data', value: 1 },
{ type: 'data', value: 1 },
{ type: 'complete' }
]);
expect(fixture.getCalls('on_complete').length).toBe(1);
});
it('should handle parser reset correctly', async () => {
const events: IParsedEvent[] = [];
const fixture = createFixture(MockLLParseParser, {
on_data: (value) => events.push({ type: 'data', value })
});
const parser = fixture.parser;
parser.parse(Buffer.from([0x01]));
fixture.reset(); // Calls the parser's reset method
parser.parse(Buffer.from([0x01]));
expect(events.length).toBe(2); // Events before and after reset
});
});