const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const vm = require('node:vm'); const ts = require('typescript'); const moduleRow = { name: 'Test', folderName: 'test' }; const clean = 'modules/Test/clean.py'; const dirty = 'modules/Test/dirty.py'; let reads = 0; const context = { exports: {}, console, require: name => name === 'react' ? { useRef: value => ({ current: value }) } : {}, window: { remoteWorkspace: { moduleFiles: { read: async () => { reads++; return { files: {}, filePaths: [clean, dirty], folders: [], absoluteRoot: '/module' }; } } } } }; const source = fs.readFileSync(path.join(__dirname, '../src/renderer/src/features/workspace/useWorkspaceFileActions.ts'), 'utf8'); vm.runInNewContext(ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS } }).outputText, context); let files = { [clean]: 'cached', [dirty]: 'unsaved' }; const options = { selectedModule: moduleRow, remoteWorkspace: true, getRemoteWorkspaceTarget: () => ({ host: 'test' }), clonePathPreview: '/workspace', dirtyEditorFiles: { [dirty]: true }, setEditorFiles: fn => { files = fn(files); }, setNewFileDraft: () => {} }; for (const name of ['setModuleFileLoadingByName', 'setSavedEditorFiles', 'setLoadedModuleFilePaths', 'setLoadedModuleFolders', 'setLoadedModuleRoots']) { options[name] = fn => fn({}); } (async () => { const actions = context.exports.useWorkspaceFileActions(options); const cached = files; await actions.loadModuleFiles(moduleRow); await actions.loadModuleFiles(moduleRow); assert.equal(reads, 2); assert.equal(files, cached, 'Automatic listing refresh must retain the content cache'); await actions.loadModuleFiles(moduleRow, true); assert.equal(files[clean], undefined, 'Explicit refresh invalidates clean content'); assert.equal(files[dirty], 'unsaved', 'Explicit refresh preserves unsaved edits'); files = { [clean]: 'reloaded', [dirty]: 'unsaved' }; actions.refreshModuleFiles(); await new Promise(resolve => setImmediate(resolve)); assert.equal(files[clean], undefined, 'Refresh button must explicitly invalidate content'); assert.equal(files[dirty], 'unsaved'); options.remoteWorkspace = false; context.window.localWorkspace = { moduleFiles: { read: async () => ({ files: { [clean]: 'local disk' }, folders: [], absoluteRoot: '/module' }) } }; await context.exports.useWorkspaceFileActions(options).loadModuleFiles(moduleRow); assert.equal(files[clean], 'local disk', 'Local workspace retains its existing eager loading'); console.log('Automatic cache retention, explicit refresh, dirty protection and local loading tests passed.'); })().catch(error => { console.error(error); process.exitCode = 1; });