delta-sync
Version:
A lightweight framework for bi-directional database synchronization with automatic version tracking and conflict resolution.
143 lines (142 loc) • 5.21 kB
JavaScript
// tester/SyncViewTester.ts
import { SyncView } from '../core/types';
export class SyncViewTester {
constructor() {
this.testResults = {};
this.view = new SyncView();
}
async runTest(testName, testFn) {
try {
await testFn();
this.testResults[testName] = {
success: true,
message: 'Test passed successfully'
};
}
catch (error) {
this.testResults[testName] = {
success: false,
message: error instanceof Error ? error.message : 'Unknown error'
};
}
}
async runAllTests() {
// 按顺序执行所有测试
await this.runTest('basicCRUD', () => this.testBasicCRUD());
await this.runTest('batchOperations', () => this.testBatchOperations());
await this.runTest('storePagination', () => this.testStorePagination());
await this.runTest('viewDiff', () => this.testViewDiff());
await this.runTest('serialization', () => this.testSerialization());
await this.runTest('storeManagement', () => this.testStoreManagement());
await this.runTest('clearOperation', () => this.testClearOperation());
// 计算整体测试结果
const success = Object.values(this.testResults).every(result => result.success);
return {
success,
results: this.testResults
};
}
async testBasicCRUD() {
const testItem = {
id: 'test1',
store: 'notes',
version: 1
};
// 测试插入
this.view.upsert(testItem);
if (this.view.size() !== 1) {
throw new Error('Insert failed');
}
// 测试查询
const retrieved = this.view.get('notes', 'test1');
if (!retrieved || retrieved.id !== testItem.id) {
throw new Error('Get operation failed');
}
// 测试更新
const updatedItem = { ...testItem, version: 2 };
this.view.upsert(updatedItem);
const updated = this.view.get('notes', 'test1');
if (!updated || updated.version !== 2) {
throw new Error('Update operation failed');
}
// 测试删除
this.view.delete('notes', 'test1');
if (this.view.get('notes', 'test1') !== undefined) {
throw new Error('Delete operation failed');
}
}
async testBatchOperations() {
const items = [
{ id: '1', store: 'notes', version: 1 },
{ id: '2', store: 'notes', version: 1 },
{ id: '3', store: 'tasks', version: 1 }
];
this.view.upsertBatch(items);
if (this.view.size() !== 3) {
throw new Error('Batch insert failed');
}
if (this.view.storeSize('notes') !== 2) {
throw new Error('Store size calculation failed');
}
}
async testStorePagination() {
this.view.clear();
const items = Array.from({ length: 10 }, (_, i) => ({
id: `${i}`,
store: 'notes',
version: 1
}));
this.view.upsertBatch(items);
const page1 = this.view.getByStore('notes', 0, 5);
const page2 = this.view.getByStore('notes', 5, 5);
if (page1.length !== 5 || page2.length !== 5) {
throw new Error('Pagination failed');
}
}
async testViewDiff() {
const localView = new SyncView();
const remoteView = new SyncView();
localView.upsert({ id: 'local1', store: 'notes', version: 1 });
remoteView.upsert({ id: 'remote1', store: 'notes', version: 1 });
const diff = SyncView.diffViews(localView, remoteView);
if (diff.toUpload.length !== 1 || diff.toDownload.length !== 1) {
throw new Error('View difference comparison failed');
}
}
async testSerialization() {
this.view.clear();
const items = [
{ id: '1', store: 'notes', version: 1 },
{ id: '2', store: 'notes', version: 2 }
];
this.view.upsertBatch(items);
const serialized = this.view.serialize();
const newView = SyncView.deserialize(serialized);
if (newView.size() !== 2) {
throw new Error('Serialization/Deserialization failed');
}
}
async testStoreManagement() {
this.view.clear();
this.view.upsert({ id: '1', store: 'notes', version: 1 });
this.view.upsert({ id: '2', store: 'tasks', version: 1 });
const stores = this.view.getStores();
if (!stores.includes('notes') || !stores.includes('tasks')) {
throw new Error('Store management failed');
}
}
async testClearOperation() {
this.view.upsertBatch([
{ id: '1', store: 'notes', version: 1 },
{ id: '2', store: 'tasks', version: 1 }
]);
this.view.clear();
if (this.view.size() !== 0) {
throw new Error('Clear operation failed');
}
}
}
export async function testSyncViewFunctionality() {
const tester = new SyncViewTester();
return await tester.runAllTests();
}