118 lines
3.8 KiB
TypeScript
118 lines
3.8 KiB
TypeScript
|
|
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||
|
|
import { SmartlogDestinationBuffer } from '../ts_destination_buffer/index.js';
|
||
|
|
import type { ILogPackage, TLogLevel } from '../ts_interfaces/index.js';
|
||
|
|
|
||
|
|
const createMockLogPackage = (level: TLogLevel, message: string): ILogPackage => {
|
||
|
|
return {
|
||
|
|
timestamp: Date.now(),
|
||
|
|
type: 'log',
|
||
|
|
level,
|
||
|
|
message,
|
||
|
|
context: {
|
||
|
|
environment: 'test',
|
||
|
|
runtime: 'node',
|
||
|
|
zone: 'test-zone',
|
||
|
|
},
|
||
|
|
correlation: {
|
||
|
|
id: '123',
|
||
|
|
type: 'none',
|
||
|
|
},
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
let buffer: SmartlogDestinationBuffer;
|
||
|
|
|
||
|
|
tap.test('should create a buffer destination instance', async () => {
|
||
|
|
buffer = new SmartlogDestinationBuffer({ maxEntries: 100 });
|
||
|
|
expect(buffer).toBeTruthy();
|
||
|
|
expect(buffer.getEntryCount()).toEqual(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should store log entries via handleLog', async () => {
|
||
|
|
await buffer.handleLog(createMockLogPackage('info', 'Hello world'));
|
||
|
|
await buffer.handleLog(createMockLogPackage('error', 'Something failed'));
|
||
|
|
await buffer.handleLog(createMockLogPackage('warn', 'Watch out'));
|
||
|
|
|
||
|
|
expect(buffer.getEntryCount()).toEqual(3);
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should retrieve entries newest-first', async () => {
|
||
|
|
const entries = buffer.getEntries();
|
||
|
|
expect(entries.length).toEqual(3);
|
||
|
|
expect(entries[0].message).toEqual('Watch out');
|
||
|
|
expect(entries[2].message).toEqual('Hello world');
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should filter entries by level', async () => {
|
||
|
|
const errorEntries = buffer.getEntries({ level: 'error' });
|
||
|
|
expect(errorEntries.length).toEqual(1);
|
||
|
|
expect(errorEntries[0].message).toEqual('Something failed');
|
||
|
|
|
||
|
|
const multiLevel = buffer.getEntries({ level: ['info', 'warn'] });
|
||
|
|
expect(multiLevel.length).toEqual(2);
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should filter entries by search string', async () => {
|
||
|
|
const results = buffer.getEntries({ search: 'hello' });
|
||
|
|
expect(results.length).toEqual(1);
|
||
|
|
expect(results[0].message).toEqual('Hello world');
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should support limit and offset pagination', async () => {
|
||
|
|
const page1 = buffer.getEntries({ limit: 2, offset: 0 });
|
||
|
|
expect(page1.length).toEqual(2);
|
||
|
|
expect(page1[0].message).toEqual('Watch out');
|
||
|
|
|
||
|
|
const page2 = buffer.getEntries({ limit: 2, offset: 2 });
|
||
|
|
expect(page2.length).toEqual(1);
|
||
|
|
expect(page2[0].message).toEqual('Hello world');
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should filter by since timestamp', async () => {
|
||
|
|
const now = Date.now();
|
||
|
|
const freshBuffer = new SmartlogDestinationBuffer();
|
||
|
|
|
||
|
|
const oldPkg = createMockLogPackage('info', 'Old message');
|
||
|
|
oldPkg.timestamp = now - 60000;
|
||
|
|
await freshBuffer.handleLog(oldPkg);
|
||
|
|
|
||
|
|
const newPkg = createMockLogPackage('info', 'New message');
|
||
|
|
newPkg.timestamp = now;
|
||
|
|
await freshBuffer.handleLog(newPkg);
|
||
|
|
|
||
|
|
const results = freshBuffer.getEntries({ since: now - 1000 });
|
||
|
|
expect(results.length).toEqual(1);
|
||
|
|
expect(results[0].message).toEqual('New message');
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should enforce circular buffer max entries', async () => {
|
||
|
|
const smallBuffer = new SmartlogDestinationBuffer({ maxEntries: 5 });
|
||
|
|
|
||
|
|
for (let i = 0; i < 10; i++) {
|
||
|
|
await smallBuffer.handleLog(createMockLogPackage('info', `Message ${i}`));
|
||
|
|
}
|
||
|
|
|
||
|
|
expect(smallBuffer.getEntryCount()).toEqual(5);
|
||
|
|
|
||
|
|
// Should have kept the latest 5 (messages 5-9)
|
||
|
|
const entries = smallBuffer.getEntries({ limit: 10 });
|
||
|
|
expect(entries[0].message).toEqual('Message 9');
|
||
|
|
expect(entries[4].message).toEqual('Message 5');
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should clear all entries', async () => {
|
||
|
|
expect(buffer.getEntryCount()).toBeGreaterThan(0);
|
||
|
|
buffer.clear();
|
||
|
|
expect(buffer.getEntryCount()).toEqual(0);
|
||
|
|
expect(buffer.getEntries().length).toEqual(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should use default maxEntries of 2000', async () => {
|
||
|
|
const defaultBuffer = new SmartlogDestinationBuffer();
|
||
|
|
// Just verify it was created without error
|
||
|
|
expect(defaultBuffer).toBeTruthy();
|
||
|
|
expect(defaultBuffer.getEntryCount()).toEqual(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
export default tap.start();
|