2026-05-05 22:51:19 +00:00
|
|
|
import { describe, expect, test } from 'bun:test'
|
|
|
|
|
|
2026-09-15 07:55:27 +00:00
|
|
|
// eslint-disable-next-line open-pencil/no-mixed-case-acronym-identifiers -- Upstream export spelling.
|
|
|
|
|
import { toJsonSchema as toJSONSchema } from '@valibot/to-json-schema'
|
|
|
|
|
|
2026-09-15 14:12:31 +00:00
|
|
|
import { isAtomicTool, isToolExposed } from '@open-pencil/core/tools'
|
2026-09-15 07:55:27 +00:00
|
|
|
|
2026-05-05 23:05:02 +00:00
|
|
|
import { ALL_TOOLS } from '#tests/helpers/tools'
|
2026-05-05 22:51:19 +00:00
|
|
|
|
|
|
|
|
describe('tool definitions', () => {
|
2026-09-15 14:12:31 +00:00
|
|
|
test('exposure defaults to inclusion and exclusions affect only the named interface', () => {
|
|
|
|
|
for (const target of ['mcp', 'ai', 'webmcp'] as const) {
|
|
|
|
|
expect(isToolExposed({ exposure: {} }, target)).toBe(true)
|
|
|
|
|
expect(isToolExposed({ exposure: { [target]: true } }, target)).toBe(true)
|
|
|
|
|
expect(isToolExposed({ exposure: { [target]: false } }, target)).toBe(false)
|
|
|
|
|
}
|
|
|
|
|
expect(isToolExposed({ exposure: { webmcp: false, ai: false } }, 'mcp')).toBe(true)
|
|
|
|
|
})
|
|
|
|
|
|
2026-09-15 07:55:27 +00:00
|
|
|
test('all tools have unique names and native input schemas', () => {
|
|
|
|
|
const names = ALL_TOOLS.map((tool) => tool.name)
|
2026-05-05 22:51:19 +00:00
|
|
|
expect(new Set(names).size).toBe(names.length)
|
2026-09-15 07:55:27 +00:00
|
|
|
for (const tool of ALL_TOOLS) {
|
|
|
|
|
expect(tool.name).toBeTruthy()
|
|
|
|
|
expect(tool.description).toBeTruthy()
|
|
|
|
|
expect(typeof tool.execute).toBe('function')
|
|
|
|
|
expect(toJSONSchema(tool.input, { typeMode: 'input' }).type).toBe('object')
|
2026-05-05 22:51:19 +00:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
2026-09-15 14:12:31 +00:00
|
|
|
test('browser-eligible tools declare document capabilities', () => {
|
2026-09-15 07:55:27 +00:00
|
|
|
for (const tool of ALL_TOOLS) {
|
|
|
|
|
expect(tool.mutates).toBe(tool.execution.mutation !== 'none')
|
2026-09-15 14:12:31 +00:00
|
|
|
if (!isToolExposed(tool, 'webmcp')) continue
|
|
|
|
|
if (tool.execution.mutation !== 'none' && !isAtomicTool(tool)) continue
|
2026-09-15 07:55:27 +00:00
|
|
|
expect(
|
|
|
|
|
tool.capabilities.every(
|
|
|
|
|
(capability) => capability === 'document:read' || capability === 'document:write'
|
|
|
|
|
)
|
|
|
|
|
).toBe(true)
|
2026-05-05 22:51:19 +00:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|