64 lines
3.8 KiB
JavaScript
64 lines
3.8 KiB
JavaScript
const { test } = require('node:test')
|
|
const assert = require('node:assert/strict')
|
|
const fs = require('node:fs')
|
|
const vm = require('node:vm')
|
|
const ts = require('typescript')
|
|
const React = require('react')
|
|
|
|
function compile(path, overrides = {}) {
|
|
const exports = {}
|
|
const source = fs.readFileSync(require.resolve(path), 'utf8')
|
|
vm.runInNewContext(ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022, jsx: ts.JsxEmit.ReactJSX } }).outputText,
|
|
{ exports, require: name => overrides[name] ?? require(name) })
|
|
return exports
|
|
}
|
|
const models = compile('../src/renderer/src/features/workspace/agentModels.ts')
|
|
const options = [{ provider: 'OPENAI', model: 'gpt-6.1-sol', imagesEnabled: false }, { provider: 'QWEN', model: 'qwen3.8-flash', imagesEnabled: true }]
|
|
const plain = value => JSON.parse(JSON.stringify(value))
|
|
|
|
test('normalizes enabled models, validates IDs and preserves old single-model servers', () => {
|
|
const status = models.normalizeAgentStatus({ enabled: true, models: [options[1], options[0], options[0], { provider: 'FORGED', model: 'bad' }, { provider: 'GEMINI', model: '' }] })
|
|
assert.deepEqual(plain(status.models), options)
|
|
assert.equal(status.selectionSupported, true)
|
|
assert.deepEqual(plain(models.normalizeAgentStatus({ enabled: true, ...options[1] }).models), [options[1]])
|
|
assert.equal(models.normalizeAgentStatus({ enabled: true, ...options[1] }).selectionSupported, false)
|
|
assert.equal(models.normalizeAgentStatus({ enabled: false, models: options }).models.length, 0)
|
|
assert.equal(models.normalizeAgentStatus({ enabled: true, models: [] }).enabled, false)
|
|
})
|
|
|
|
test('selects the saved provider only while it is available, and never invents one', () => {
|
|
assert.equal(models.selectedAgentModel(options, 'QWEN'), options[1])
|
|
assert.equal(models.selectedAgentModel(options, 'ANTHROPIC'), options[0])
|
|
assert.equal(models.selectedAgentModel([options[0]], 'QWEN'), options[0])
|
|
assert.equal(models.selectedAgentModel([], 'QWEN'), null)
|
|
})
|
|
|
|
function elements(root, predicate) {
|
|
if (!React.isValidElement(root)) return []
|
|
return [...(predicate(root) ? [root] : []), ...React.Children.toArray(root.props.children).flatMap(child => elements(child, predicate))]
|
|
}
|
|
const { AgentModelSelector } = compile('../src/renderer/src/components/AgentModelSelector.tsx', {
|
|
'../i18n': { t: value => value }, '../features/workspace/agentModels': models,
|
|
})
|
|
|
|
for (const dark of [true, false]) test(`model control lists only allowed providers and follows the theme (${dark})`, () => {
|
|
let selected
|
|
const tree = AgentModelSelector({ models: options, provider: 'QWEN', dark, disabled: false, onChange: value => { selected = value } })
|
|
const select = elements(tree, node => node.type === 'select')[0]
|
|
assert.equal(select.props.value, 'QWEN')
|
|
assert.equal(select.props.style.colorScheme, dark ? 'dark' : 'light')
|
|
assert.deepEqual(elements(select, node => node.type === 'option').map(node => node.props.value), ['OPENAI', 'QWEN'])
|
|
select.props.onChange({ target: { value: 'OPENAI' } })
|
|
assert.equal(selected, 'OPENAI')
|
|
assert.match(select.props.className, /truncate/)
|
|
assert.ok(elements(AgentModelSelector({ models: options, provider: 'QWEN', dark, disabled: true, onChange() {} }), node => node.type === 'select')[0].props.disabled)
|
|
const empty = elements(AgentModelSelector({ models: [], provider: null, dark, disabled: false, onChange() {} }), node => node.type === 'select')[0]
|
|
assert.ok(empty.props.disabled)
|
|
assert.equal(elements(empty, node => node.type === 'option')[0].props.children, '사용 가능한 모델 없음')
|
|
})
|
|
|
|
test('A-Copilot has a single managed label', () => {
|
|
assert.equal(models.agentModelLabel({ provider: 'A_COPILOT', model: 'A-Copilot', imagesEnabled: false }), 'A-Copilot')
|
|
assert.equal(models.agentModelLabel(options[0]), 'OpenAI · gpt-6.1-sol')
|
|
})
|