00a83ce4ac
Remove redundant code-view cancellation and align button labels. Restore module scrollbar thickness while preserving workspace colors, and support config, SDF and world text files locally and remotely.
67 lines
2.8 KiB
JavaScript
67 lines
2.8 KiB
JavaScript
const { test } = require('node:test')
|
|
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 root = path.resolve(__dirname, '../src/renderer/src/features/workspace')
|
|
|
|
function setup(saved, blocked = false) {
|
|
const storage = new Map([['autonomy-studio.lms.studio-theme', saved]])
|
|
const events = new Map()
|
|
const exports = {}
|
|
const code = ts.transpileModule(fs.readFileSync(path.join(root, 'studioTheme.ts'), 'utf8'), {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 }
|
|
}).outputText
|
|
vm.runInNewContext(code, { exports,
|
|
require: () => ({ useSyncExternalStore: (_subscribe, snapshot) => snapshot() }),
|
|
localStorage: {
|
|
getItem(key) { if (blocked) throw Error('blocked'); return storage.get(key) },
|
|
setItem(key, value) { if (blocked) throw Error('blocked'); storage.set(key, value) }
|
|
},
|
|
window: { addEventListener: (type, listener) => events.set(type, listener) }
|
|
})
|
|
return { api: exports, storage, events }
|
|
}
|
|
|
|
test('theme defaults dark, persists light, and restores the preference', () => {
|
|
const { api, storage } = setup('invalid')
|
|
assert.equal(api.useStudioTheme(), 'dark')
|
|
api.setStudioTheme('light')
|
|
assert.equal(api.useStudioTheme(), 'light')
|
|
assert.equal(storage.get(api.STUDIO_THEME_KEY), 'light')
|
|
assert.equal(setup('light').api.useStudioTheme(), 'light')
|
|
})
|
|
test('theme remains usable when storage is blocked', () => {
|
|
const { api } = setup(null, true)
|
|
api.setStudioTheme('light')
|
|
assert.equal(api.useStudioTheme(), 'light')
|
|
})
|
|
test('theme synchronizes across windows without writing runtime settings', () => {
|
|
const { api, storage, events } = setup('dark')
|
|
storage.set(api.STUDIO_THEME_KEY, 'light')
|
|
events.get('storage')({ key: api.STUDIO_THEME_KEY })
|
|
assert.equal(api.useStudioTheme(), 'light')
|
|
storage.clear()
|
|
events.get('storage')({ key: null })
|
|
assert.equal(api.useStudioTheme(), 'dark')
|
|
})
|
|
|
|
test('module content scrollbar uses workspace colors without thinner scrollbar dimensions', () => {
|
|
const source = ts.createSourceFile('ModuleListView.tsx', fs.readFileSync(path.join(root, 'ModuleListView.tsx'), 'utf8'), ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX)
|
|
const scrollClasses = []
|
|
function visit(node) {
|
|
if (ts.isJsxAttribute(node) && node.name.getText(source) === 'className' && node.initializer && ts.isStringLiteral(node.initializer)) {
|
|
const classes = node.initializer.text.split(/\s+/)
|
|
if (classes.includes('overflow-x-auto')) scrollClasses.push(classes)
|
|
}
|
|
ts.forEachChild(node, visit)
|
|
}
|
|
visit(source)
|
|
assert.ok(scrollClasses.length > 0)
|
|
for (const classes of scrollClasses) {
|
|
assert.ok(classes.includes('module-content-scrollbar'))
|
|
assert.ok(!classes.includes('thin-x-scrollbar'))
|
|
}
|
|
})
|