- Add double-click handler to make file names editable in UI - Remove duplicate IPC handler for rename-file in renderer.js - Fix checkEpisodeCountMatch to properly validate sequential episodes - Fix begin-mapping to handle both season folder and show folder cases - Improve open-file-in-player handler to properly log results
319 lines
8.7 KiB
JavaScript
319 lines
8.7 KiB
JavaScript
// Test folder navigation performance
|
|
const { test } = require('node:test');
|
|
const assert = require('assert');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
test('Navigation performance with many files', async () => {
|
|
const testDir = path.join(__dirname, 'test_performance_dir');
|
|
|
|
if (!fs.existsSync(testDir)) {
|
|
fs.mkdirSync(testDir);
|
|
}
|
|
|
|
try {
|
|
// Create 100 mock files
|
|
const numFiles = 100;
|
|
for (let i = 0; i < numFiles; i++) {
|
|
fs.writeFileSync(path.join(testDir, `file${i}.mp4`), '');
|
|
}
|
|
|
|
// Create some subdirectories
|
|
for (let i = 0; i < 5; i++) {
|
|
const subdirPath = path.join(testDir, `folder${i}`);
|
|
if (!fs.existsSync(subdirPath)) {
|
|
fs.mkdirSync(subdirPath);
|
|
}
|
|
}
|
|
|
|
// Create mock UIManager
|
|
const mockUIManager = {
|
|
currentDirectory: null,
|
|
selectedDirEl: { textContent: '' },
|
|
|
|
appState: {
|
|
navigationStack: [],
|
|
currentDepth: 0,
|
|
|
|
addToNavigationStack: function(dir) {
|
|
this.navigationStack.push(dir);
|
|
this.currentDepth = this.navigationStack.length - 1;
|
|
},
|
|
|
|
getNavigationStack: function() {
|
|
return this.navigationStack;
|
|
},
|
|
|
|
goBack: function() {
|
|
if (this.currentDepth > 0) {
|
|
this.navigationStack.pop();
|
|
this.currentDepth--;
|
|
return this.navigationStack[this.currentDepth];
|
|
}
|
|
return null;
|
|
},
|
|
|
|
canGoBack: function() {
|
|
return this.currentDepth > 0;
|
|
}
|
|
},
|
|
|
|
scanDirectory: async (dir) => {
|
|
// Simulate scanning with many files
|
|
const files = [];
|
|
for (let i = 0; i < numFiles; i++) {
|
|
files.push({ name: `file${i}.mp4` });
|
|
}
|
|
return { success: true, files };
|
|
},
|
|
|
|
_logAuditEvent: async () => {},
|
|
|
|
openDirectory: async function(directory) {
|
|
mockUIManager.appState.addToNavigationStack(directory);
|
|
mockUIManager.currentDirectory = directory;
|
|
await mockUIManager.scanDirectory(directory);
|
|
},
|
|
|
|
handleFolderClick: async function(folderPath, folderName) {
|
|
if (!fs.existsSync(folderPath) || !fs.statSync(folderPath).isDirectory()) {
|
|
return;
|
|
}
|
|
await mockUIManager.openDirectory(folderPath);
|
|
},
|
|
|
|
updateBreadcrumbNavigation: function() {
|
|
// Mock breadcrumb update
|
|
}
|
|
};
|
|
|
|
// Measure navigation time
|
|
const startTime = performance.now();
|
|
await mockUIManager.openDirectory(testDir);
|
|
const endTime = performance.now();
|
|
|
|
const navigationTime = endTime - startTime;
|
|
console.log(`Navigation time with ${numFiles} files: ${navigationTime.toFixed(2)}ms`);
|
|
|
|
// Verify navigation completed
|
|
assert.strictEqual(mockUIManager.currentDirectory, testDir);
|
|
|
|
// Performance threshold: should complete within 5 seconds
|
|
// (actual time will be much less)
|
|
assert.ok(navigationTime < 5000, `Navigation should complete within 5 seconds (took ${navigationTime}ms)`);
|
|
|
|
console.log('Performance test passed');
|
|
} finally {
|
|
if (fs.existsSync(testDir)) {
|
|
fs.rmSync(testDir, { recursive: true });
|
|
}
|
|
}
|
|
});
|
|
|
|
test('Breadcrumb updates are efficient', () => {
|
|
const mockUIManager = {
|
|
selectedDirEl: { textContent: '' },
|
|
|
|
appState: {
|
|
getNavigationStack: () => [
|
|
'/Users/test/Movies',
|
|
'/Users/test/Movies/Show Name',
|
|
'/Users/test/Movies/Show Name/Season 1',
|
|
'/Users/test/Movies/Show Name/Season 1/extras',
|
|
'/Users/test/Movies/Show Name/Season 1/behind the scenes'
|
|
],
|
|
canGoBack: () => true
|
|
}
|
|
};
|
|
|
|
// Mock DOM operations
|
|
let elementCount = 0;
|
|
const mockAppendChild = (element) => {
|
|
elementCount++;
|
|
};
|
|
|
|
mockUIManager.updateBreadcrumbNavigation = function() {
|
|
const breadcrumbs = this.appState.getNavigationStack();
|
|
const container = { appendChild: mockAppendChild };
|
|
|
|
breadcrumbs.forEach((dir, index) => {
|
|
// Simulate creating breadcrumb elements
|
|
elementCount++;
|
|
});
|
|
|
|
return container;
|
|
};
|
|
|
|
// Measure breadcrumb update time
|
|
const startTime = performance.now();
|
|
mockUIManager.updateBreadcrumbNavigation();
|
|
const endTime = performance.now();
|
|
|
|
const updateTime = endTime - startTime;
|
|
console.log(`Breadcrumb update time: ${updateTime.toFixed(2)}ms`);
|
|
|
|
// Verify efficient update
|
|
assert.ok(updateTime < 100, `Breadcrumb update should be fast (< 100ms)`);
|
|
|
|
console.log('Breadcrumb efficiency test passed');
|
|
});
|
|
|
|
test('Large navigation stack performance', () => {
|
|
const mockUIManager = {
|
|
selectedDirEl: { textContent: '' },
|
|
|
|
appState: {
|
|
navigationStack: [],
|
|
currentDepth: 0,
|
|
|
|
addToNavigationStack: function(dir) {
|
|
this.navigationStack.push(dir);
|
|
this.currentDepth = this.navigationStack.length - 1;
|
|
},
|
|
|
|
getNavigationStack: function() {
|
|
return this.navigationStack;
|
|
},
|
|
|
|
goBack: function() {
|
|
if (this.currentDepth > 0) {
|
|
this.navigationStack.pop();
|
|
this.currentDepth--;
|
|
return this.navigationStack[this.currentDepth];
|
|
}
|
|
return null;
|
|
},
|
|
|
|
canGoBack: function() {
|
|
return this.currentDepth > 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
// Build a large navigation stack
|
|
for (let i = 0; i < 100; i++) {
|
|
mockUIManager.appState.addToNavigationStack(`/path/to/folder${i}`);
|
|
}
|
|
|
|
assert.strictEqual(mockUIManager.appState.getNavigationStack().length, 100);
|
|
|
|
// Measure performance
|
|
const startTime = performance.now();
|
|
|
|
// Test goBack performance
|
|
for (let i = 0; i < 50; i++) {
|
|
mockUIManager.appState.goBack();
|
|
}
|
|
|
|
const endTime = performance.now();
|
|
const timePerOperation = (endTime - startTime) / 50;
|
|
|
|
console.log(`Average goBack time: ${timePerOperation.toFixed(4)}ms`);
|
|
|
|
// Verify reasonable performance
|
|
assert.ok(timePerOperation < 1, `goBack should be fast (< 1ms)`);
|
|
|
|
console.log('Large stack performance test passed');
|
|
});
|
|
|
|
test('Memory usage during navigation', () => {
|
|
const mockUIManager = {
|
|
selectedDirEl: { textContent: '' },
|
|
|
|
appState: {
|
|
navigationStack: [],
|
|
currentDepth: 0,
|
|
|
|
addToNavigationStack: function(dir) {
|
|
this.navigationStack.push(dir);
|
|
this.currentDepth = this.navigationStack.length - 1;
|
|
},
|
|
|
|
goBack: function() {
|
|
if (this.currentDepth > 0) {
|
|
this.navigationStack.pop();
|
|
this.currentDepth--;
|
|
return this.navigationStack[this.currentDepth];
|
|
}
|
|
return null;
|
|
},
|
|
|
|
getNavigationStack: function() {
|
|
return this.navigationStack;
|
|
}
|
|
}
|
|
};
|
|
|
|
// Perform many navigation operations
|
|
const numOperations = 1000;
|
|
const paths = [];
|
|
|
|
for (let i = 0; i < numOperations; i++) {
|
|
const path = `/path/to/folder${i}`;
|
|
paths.push(path);
|
|
mockUIManager.appState.addToNavigationStack(path);
|
|
}
|
|
|
|
// Verify stack size
|
|
assert.strictEqual(mockUIManager.appState.getNavigationStack().length, numOperations);
|
|
|
|
// Go back half way
|
|
for (let i = 0; i < numOperations / 2; i++) {
|
|
mockUIManager.appState.goBack();
|
|
}
|
|
|
|
// Verify stack size after going back
|
|
assert.strictEqual(mockUIManager.appState.getNavigationStack().length, numOperations / 2);
|
|
|
|
console.log('Memory usage test passed');
|
|
});
|
|
|
|
test('Multiple breadcrumb renders', () => {
|
|
const mockUIManager = {
|
|
selectedDirEl: { textContent: '' },
|
|
|
|
appState: {
|
|
getNavigationStack: () => [
|
|
'/Users/test/Movies',
|
|
'/Users/test/Movies/Show Name',
|
|
'/Users/test/Movies/Show Name/Season 1',
|
|
'/Users/test/Movies/Show Name/Season 1/extras'
|
|
],
|
|
canGoBack: () => true
|
|
}
|
|
};
|
|
|
|
const numRenders = 100;
|
|
|
|
mockUIManager.updateBreadcrumbNavigation = function() {
|
|
const breadcrumbs = this.appState.getNavigationStack();
|
|
const container = { appendChild: () => {} };
|
|
|
|
breadcrumbs.forEach((dir, index) => {
|
|
// Simulate creating breadcrumb elements
|
|
});
|
|
|
|
return container;
|
|
};
|
|
|
|
// Measure multiple renders
|
|
const startTime = performance.now();
|
|
|
|
for (let i = 0; i < numRenders; i++) {
|
|
mockUIManager.updateBreadcrumbNavigation();
|
|
}
|
|
|
|
const endTime = performance.now();
|
|
const totalTime = endTime - startTime;
|
|
const timePerRender = totalTime / numRenders;
|
|
|
|
console.log(`Average breadcrumb render time: ${timePerRender.toFixed(4)}ms`);
|
|
console.log(`Total time for ${numRenders} renders: ${totalTime.toFixed(2)}ms`);
|
|
|
|
// Verify reasonable performance
|
|
assert.ok(timePerRender < 1, `Breadcrumb render should be fast (< 1ms)`);
|
|
|
|
console.log('Multiple breadcrumb renders test passed');
|
|
});
|
|
|
|
console.log('All performance tests passed!'); |