mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-01-24 03:06:16 +00:00
- Replace original sync-md plugin with new Solid.js implementation - Add comprehensive bidirectional sync algorithm with conflict detection - Include built Solid.js assets (CSS and JS) for plugin UI - Create detailed sync examples demonstrating various scenarios - Support three sync modes: bidirectional, file-to-project, project-to-file - Implement checksum-based change tracking for reliable sync state
249 lines
5.8 KiB
JavaScript
249 lines
5.8 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Test script for bidirectional sync logic
|
|
* Run with: npx tsx test-sync-logic.ts
|
|
*/
|
|
|
|
import { BidirectionalSync, SyncState } from './src/syncLogic';
|
|
import { Task, MarkdownTask, SyncDirection } from './src/types';
|
|
|
|
// Test data
|
|
const markdownContent1 = `
|
|
- [ ] Design new feature
|
|
- [x] Research requirements
|
|
- [ ] Create mockups
|
|
- [x] Fix bug in login
|
|
- [ ] Write documentation
|
|
`;
|
|
|
|
const markdownContent2 = `
|
|
- [ ] Design new feature
|
|
- [x] Research requirements
|
|
- [x] Create mockups
|
|
- [ ] Get feedback
|
|
- [x] Fix bug in login
|
|
- [ ] Write documentation
|
|
- [ ] Deploy to staging
|
|
`;
|
|
|
|
const projectTasks1: Task[] = [
|
|
{
|
|
id: '1',
|
|
title: 'Design new feature',
|
|
isDone: false,
|
|
projectId: 'proj1',
|
|
subTaskIds: ['1-1', '1-2'],
|
|
},
|
|
{
|
|
id: '1-1',
|
|
title: 'Research requirements',
|
|
isDone: true,
|
|
projectId: 'proj1',
|
|
parentId: '1',
|
|
},
|
|
{
|
|
id: '1-2',
|
|
title: 'Create mockups',
|
|
isDone: false,
|
|
projectId: 'proj1',
|
|
parentId: '1',
|
|
},
|
|
{
|
|
id: '2',
|
|
title: 'Fix bug in login',
|
|
isDone: true,
|
|
projectId: 'proj1',
|
|
},
|
|
{
|
|
id: '3',
|
|
title: 'Write documentation',
|
|
isDone: false,
|
|
projectId: 'proj1',
|
|
},
|
|
];
|
|
|
|
const projectTasks2: Task[] = [
|
|
...projectTasks1.map((t) => (t.id === '1-2' ? { ...t, isDone: true } : t)),
|
|
{
|
|
id: '4',
|
|
title: 'Review code',
|
|
isDone: false,
|
|
projectId: 'proj1',
|
|
},
|
|
];
|
|
|
|
// Test functions
|
|
async function testFileToProjectSync() {
|
|
console.log('\n=== Testing File to Project Sync ===');
|
|
const sync = new BidirectionalSync();
|
|
|
|
const result = await sync.sync(markdownContent2, projectTasks1, 'fileToProject');
|
|
|
|
console.log('Sync Result:', result);
|
|
console.log(
|
|
'Expected: 1 task added (Deploy to staging), 1 updated (Create mockups), 0 deleted',
|
|
);
|
|
}
|
|
|
|
async function testProjectToFileSync() {
|
|
console.log('\n=== Testing Project to File Sync ===');
|
|
const sync = new BidirectionalSync();
|
|
|
|
const result = await sync.sync(markdownContent1, projectTasks2, 'projectToFile');
|
|
|
|
console.log('Sync Result:', result);
|
|
console.log(
|
|
'Expected: 1 task added (Review code), 1 updated (Create mockups), 0 deleted',
|
|
);
|
|
}
|
|
|
|
async function testBidirectionalSync() {
|
|
console.log('\n=== Testing Bidirectional Sync ===');
|
|
const sync = new BidirectionalSync();
|
|
|
|
// First sync to establish baseline
|
|
console.log('Initial sync...');
|
|
const result1 = await sync.sync(markdownContent1, projectTasks1, 'bidirectional');
|
|
console.log('Initial sync result:', result1);
|
|
|
|
// Save sync state
|
|
const syncState = sync.updateSyncState(markdownContent1, projectTasks1);
|
|
|
|
// Now test with changes on both sides
|
|
console.log('\nSecond sync with changes on both sides...');
|
|
const sync2 = new BidirectionalSync();
|
|
const result2 = await sync2.sync(
|
|
markdownContent2,
|
|
projectTasks2,
|
|
'bidirectional',
|
|
syncState,
|
|
);
|
|
|
|
console.log('Sync Result:', result2);
|
|
console.log('Expected: Changes detected on both sides, potential conflicts');
|
|
}
|
|
|
|
async function testConflictDetection() {
|
|
console.log('\n=== Testing Conflict Detection ===');
|
|
|
|
// Create conflicting changes
|
|
const markdownWithConflict = `
|
|
- [ ] Design new feature
|
|
- [x] Research requirements
|
|
- [ ] Create wireframes
|
|
- [x] Fix bug in authentication
|
|
- [ ] Write documentation
|
|
`;
|
|
|
|
const projectWithConflict: Task[] = [
|
|
{
|
|
id: '1',
|
|
title: 'Design new feature',
|
|
isDone: false,
|
|
projectId: 'proj1',
|
|
subTaskIds: ['1-1', '1-2'],
|
|
},
|
|
{
|
|
id: '1-1',
|
|
title: 'Research requirements',
|
|
isDone: true,
|
|
projectId: 'proj1',
|
|
parentId: '1',
|
|
},
|
|
{
|
|
id: '1-2',
|
|
title: 'Create prototypes',
|
|
isDone: false,
|
|
projectId: 'proj1',
|
|
parentId: '1',
|
|
},
|
|
{
|
|
id: '2',
|
|
title: 'Fix bug in authorization',
|
|
isDone: true,
|
|
projectId: 'proj1',
|
|
},
|
|
{
|
|
id: '3',
|
|
title: 'Write documentation',
|
|
isDone: false,
|
|
projectId: 'proj1',
|
|
},
|
|
];
|
|
|
|
const sync = new BidirectionalSync();
|
|
|
|
// First sync
|
|
await sync.sync(markdownContent1, projectTasks1, 'bidirectional');
|
|
const syncState = sync.updateSyncState(markdownContent1, projectTasks1);
|
|
|
|
// Second sync with conflicts
|
|
const sync2 = new BidirectionalSync();
|
|
const result = await sync2.sync(
|
|
markdownWithConflict,
|
|
projectWithConflict,
|
|
'bidirectional',
|
|
syncState,
|
|
);
|
|
|
|
console.log('Sync Result:', result);
|
|
console.log('Conflicts detected:', result.conflicts.length);
|
|
result.conflicts.forEach((conflict) => {
|
|
console.log(`- Conflict in task "${conflict.taskTitle}"`);
|
|
console.log(` File value:`, conflict.fileValue);
|
|
console.log(` Project value:`, conflict.projectValue);
|
|
});
|
|
}
|
|
|
|
async function testMarkdownParsing() {
|
|
console.log('\n=== Testing Markdown Parsing ===');
|
|
|
|
const complexMarkdown = `
|
|
# Project Tasks
|
|
|
|
- [ ] Main task 1
|
|
- [x] Subtask 1.1
|
|
- [ ] Subtask 1.2
|
|
- [x] Sub-subtask 1.2.1
|
|
- [ ] Sub-subtask 1.2.2
|
|
- [ ] Subtask 1.3
|
|
|
|
Some notes here
|
|
|
|
- [x] Main task 2
|
|
- [x] Subtask 2.1
|
|
- [x] Subtask 2.2
|
|
|
|
* [ ] Main task 3 (asterisk format)
|
|
* [x] Subtask 3.1
|
|
* [ ] Subtask 3.2
|
|
`;
|
|
|
|
const sync = new BidirectionalSync();
|
|
// Access private method through type assertion for testing
|
|
const parsed = (sync as any).parseMarkdown(complexMarkdown);
|
|
|
|
console.log('Parsed tasks:', JSON.stringify(parsed, null, 2));
|
|
console.log(`Total main tasks: ${parsed.length}`);
|
|
console.log(`Main task 1 subtasks: ${parsed[0]?.subTasks.length}`);
|
|
}
|
|
|
|
// Run all tests
|
|
async function runAllTests() {
|
|
console.log('Starting Sync Logic Tests...');
|
|
|
|
try {
|
|
await testMarkdownParsing();
|
|
await testFileToProjectSync();
|
|
await testProjectToFileSync();
|
|
await testBidirectionalSync();
|
|
await testConflictDetection();
|
|
|
|
console.log('\n✅ All tests completed!');
|
|
} catch (error) {
|
|
console.error('\n❌ Test failed:', error);
|
|
}
|
|
}
|
|
|
|
// Run tests
|
|
runAllTests();
|