fix(tsmdb): add comprehensive unit tests for tsmdb components: checksum, query planner, index engine, session, and WAL
This commit is contained in:
232
test/test.tsmdb.checksum.ts
Normal file
232
test/test.tsmdb.checksum.ts
Normal file
@@ -0,0 +1,232 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as smartmongo from '../ts/index.js';
|
||||
|
||||
const {
|
||||
calculateCRC32,
|
||||
calculateCRC32Buffer,
|
||||
calculateDocumentChecksum,
|
||||
addChecksum,
|
||||
verifyChecksum,
|
||||
removeChecksum,
|
||||
} = smartmongo.tsmdb;
|
||||
|
||||
// ============================================================================
|
||||
// CRC32 String Tests
|
||||
// ============================================================================
|
||||
|
||||
tap.test('checksum: calculateCRC32 should return consistent value for same input', async () => {
|
||||
const result1 = calculateCRC32('hello world');
|
||||
const result2 = calculateCRC32('hello world');
|
||||
expect(result1).toEqual(result2);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateCRC32 should return different values for different inputs', async () => {
|
||||
const result1 = calculateCRC32('hello');
|
||||
const result2 = calculateCRC32('world');
|
||||
expect(result1).not.toEqual(result2);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateCRC32 should return a 32-bit unsigned integer', async () => {
|
||||
const result = calculateCRC32('test string');
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
expect(result).toBeLessThanOrEqual(0xFFFFFFFF);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateCRC32 should handle empty string', async () => {
|
||||
const result = calculateCRC32('');
|
||||
expect(typeof result).toEqual('number');
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateCRC32 should handle special characters', async () => {
|
||||
const result = calculateCRC32('hello\nworld\t!"#$%&\'()');
|
||||
expect(typeof result).toEqual('number');
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateCRC32 should handle unicode characters', async () => {
|
||||
const result = calculateCRC32('hello 世界 🌍');
|
||||
expect(typeof result).toEqual('number');
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// CRC32 Buffer Tests
|
||||
// ============================================================================
|
||||
|
||||
tap.test('checksum: calculateCRC32Buffer should return consistent value for same input', async () => {
|
||||
const buffer = Buffer.from('hello world');
|
||||
const result1 = calculateCRC32Buffer(buffer);
|
||||
const result2 = calculateCRC32Buffer(buffer);
|
||||
expect(result1).toEqual(result2);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateCRC32Buffer should return different values for different inputs', async () => {
|
||||
const buffer1 = Buffer.from('hello');
|
||||
const buffer2 = Buffer.from('world');
|
||||
const result1 = calculateCRC32Buffer(buffer1);
|
||||
const result2 = calculateCRC32Buffer(buffer2);
|
||||
expect(result1).not.toEqual(result2);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateCRC32Buffer should handle empty buffer', async () => {
|
||||
const result = calculateCRC32Buffer(Buffer.from(''));
|
||||
expect(typeof result).toEqual('number');
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateCRC32Buffer should handle binary data', async () => {
|
||||
const buffer = Buffer.from([0x00, 0xFF, 0x7F, 0x80, 0x01]);
|
||||
const result = calculateCRC32Buffer(buffer);
|
||||
expect(typeof result).toEqual('number');
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Document Checksum Tests
|
||||
// ============================================================================
|
||||
|
||||
tap.test('checksum: calculateDocumentChecksum should return consistent value', async () => {
|
||||
const doc = { name: 'John', age: 30 };
|
||||
const result1 = calculateDocumentChecksum(doc);
|
||||
const result2 = calculateDocumentChecksum(doc);
|
||||
expect(result1).toEqual(result2);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateDocumentChecksum should exclude _checksum field', async () => {
|
||||
const doc1 = { name: 'John', age: 30 };
|
||||
const doc2 = { name: 'John', age: 30, _checksum: 12345 };
|
||||
const result1 = calculateDocumentChecksum(doc1);
|
||||
const result2 = calculateDocumentChecksum(doc2);
|
||||
expect(result1).toEqual(result2);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateDocumentChecksum should handle empty document', async () => {
|
||||
const result = calculateDocumentChecksum({});
|
||||
expect(typeof result).toEqual('number');
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateDocumentChecksum should handle nested objects', async () => {
|
||||
const doc = {
|
||||
name: 'John',
|
||||
address: {
|
||||
street: '123 Main St',
|
||||
city: 'Springfield',
|
||||
zip: {
|
||||
code: '12345',
|
||||
plus4: '6789',
|
||||
},
|
||||
},
|
||||
};
|
||||
const result = calculateDocumentChecksum(doc);
|
||||
expect(typeof result).toEqual('number');
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
tap.test('checksum: calculateDocumentChecksum should handle arrays', async () => {
|
||||
const doc = {
|
||||
name: 'John',
|
||||
tags: ['developer', 'tester', 'admin'],
|
||||
scores: [95, 87, 92],
|
||||
};
|
||||
const result = calculateDocumentChecksum(doc);
|
||||
expect(typeof result).toEqual('number');
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Add/Verify/Remove Checksum Tests
|
||||
// ============================================================================
|
||||
|
||||
tap.test('checksum: addChecksum should add _checksum field to document', async () => {
|
||||
const doc = { name: 'John', age: 30 };
|
||||
const docWithChecksum = addChecksum(doc);
|
||||
|
||||
expect('_checksum' in docWithChecksum).toBeTrue();
|
||||
expect(typeof docWithChecksum._checksum).toEqual('number');
|
||||
expect(docWithChecksum.name).toEqual('John');
|
||||
expect(docWithChecksum.age).toEqual(30);
|
||||
});
|
||||
|
||||
tap.test('checksum: addChecksum should not modify the original document', async () => {
|
||||
const doc = { name: 'John', age: 30 };
|
||||
addChecksum(doc);
|
||||
expect('_checksum' in doc).toBeFalse();
|
||||
});
|
||||
|
||||
tap.test('checksum: verifyChecksum should return true for valid checksum', async () => {
|
||||
const doc = { name: 'John', age: 30 };
|
||||
const docWithChecksum = addChecksum(doc);
|
||||
const isValid = verifyChecksum(docWithChecksum);
|
||||
expect(isValid).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('checksum: verifyChecksum should return false for tampered document', async () => {
|
||||
const doc = { name: 'John', age: 30 };
|
||||
const docWithChecksum = addChecksum(doc);
|
||||
|
||||
// Tamper with the document
|
||||
docWithChecksum.age = 31;
|
||||
|
||||
const isValid = verifyChecksum(docWithChecksum);
|
||||
expect(isValid).toBeFalse();
|
||||
});
|
||||
|
||||
tap.test('checksum: verifyChecksum should return false for wrong checksum', async () => {
|
||||
const doc = { name: 'John', age: 30, _checksum: 12345 };
|
||||
const isValid = verifyChecksum(doc);
|
||||
expect(isValid).toBeFalse();
|
||||
});
|
||||
|
||||
tap.test('checksum: verifyChecksum should return true for document without checksum', async () => {
|
||||
const doc = { name: 'John', age: 30 };
|
||||
const isValid = verifyChecksum(doc);
|
||||
expect(isValid).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('checksum: removeChecksum should remove _checksum field', async () => {
|
||||
const doc = { name: 'John', age: 30 };
|
||||
const docWithChecksum = addChecksum(doc);
|
||||
const docWithoutChecksum = removeChecksum(docWithChecksum);
|
||||
|
||||
expect('_checksum' in docWithoutChecksum).toBeFalse();
|
||||
expect(docWithoutChecksum.name).toEqual('John');
|
||||
expect(docWithoutChecksum.age).toEqual(30);
|
||||
});
|
||||
|
||||
tap.test('checksum: removeChecksum should handle document without checksum', async () => {
|
||||
const doc = { name: 'John', age: 30 };
|
||||
const result = removeChecksum(doc);
|
||||
|
||||
expect('_checksum' in result).toBeFalse();
|
||||
expect(result.name).toEqual('John');
|
||||
expect(result.age).toEqual(30);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Round-trip Tests
|
||||
// ============================================================================
|
||||
|
||||
tap.test('checksum: full round-trip - add, verify, remove', async () => {
|
||||
const original = { name: 'Test', value: 42, nested: { a: 1, b: 2 } };
|
||||
|
||||
// Add checksum
|
||||
const withChecksum = addChecksum(original);
|
||||
expect('_checksum' in withChecksum).toBeTrue();
|
||||
|
||||
// Verify checksum
|
||||
expect(verifyChecksum(withChecksum)).toBeTrue();
|
||||
|
||||
// Remove checksum
|
||||
const restored = removeChecksum(withChecksum);
|
||||
expect('_checksum' in restored).toBeFalse();
|
||||
|
||||
// Original data should be intact
|
||||
expect(restored.name).toEqual('Test');
|
||||
expect(restored.value).toEqual(42);
|
||||
expect(restored.nested.a).toEqual(1);
|
||||
expect(restored.nested.b).toEqual(2);
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
Reference in New Issue
Block a user