141 lines
4.7 KiB
TypeScript
141 lines
4.7 KiB
TypeScript
/**
|
|
* @module tests/unit/db/fieldAddressing
|
|
* @description Unit pins for the one field-addressing law (ruled 2026-08-03).
|
|
* These pin the PURE half of the law — parsing, the ruled maps, plumbing
|
|
* invisibility, refusal text — including the RELATION map, which cannot be
|
|
* pinned through the public query API today (related() carries no
|
|
* field-addressing options): the verb mirror is contract-tested here at the
|
|
* module level so the two engines cannot drift on it.
|
|
*/
|
|
import { describe, it, expect } from 'vitest'
|
|
import {
|
|
SYSTEM_ENTITY_SCALARS,
|
|
SYSTEM_RELATION_SCALARS,
|
|
PLUMBING_FIELDS,
|
|
parseFieldAddress,
|
|
buildUnresolvableMessage,
|
|
InvalidFieldAddressError
|
|
} from '../../../src/db/fieldAddressing.js'
|
|
|
|
describe('field-addressing law — pure module pins', () => {
|
|
it('the entity system map is EXACTLY the ruled ten scalars', () => {
|
|
expect([...SYSTEM_ENTITY_SCALARS].sort()).toEqual(
|
|
[
|
|
'confidence',
|
|
'createdAt',
|
|
'createdBy',
|
|
'id',
|
|
'service',
|
|
'subtype',
|
|
'type',
|
|
'updatedAt',
|
|
'visibility',
|
|
'weight'
|
|
].sort()
|
|
)
|
|
})
|
|
|
|
it('the relation system map is the ruled verb mirror', () => {
|
|
expect([...SYSTEM_RELATION_SCALARS].sort()).toEqual(
|
|
[
|
|
'verb',
|
|
'sourceId',
|
|
'targetId',
|
|
'confidence',
|
|
'createdAt',
|
|
'createdBy',
|
|
'service',
|
|
'subtype',
|
|
'updatedAt',
|
|
'visibility',
|
|
'weight'
|
|
].sort()
|
|
)
|
|
})
|
|
|
|
it('plumbing is exactly the ruled five, and none of it leaks into a system map', () => {
|
|
expect([...PLUMBING_FIELDS].sort()).toEqual(
|
|
['_rev', 'connections', 'data', 'level', 'vector'].sort()
|
|
)
|
|
for (const field of PLUMBING_FIELDS) {
|
|
expect(SYSTEM_ENTITY_SCALARS.has(field)).toBe(false)
|
|
expect(SYSTEM_RELATION_SCALARS.has(field)).toBe(false)
|
|
}
|
|
})
|
|
|
|
it('bare names address user metadata — even when the name matches a system scalar', () => {
|
|
expect(parseFieldAddress('level', 'entity')).toEqual({
|
|
scope: 'metadata',
|
|
field: 'level',
|
|
raw: 'level'
|
|
})
|
|
expect(parseFieldAddress('confidence', 'entity').scope).toBe('metadata')
|
|
expect(parseFieldAddress('createdAt', 'entity').scope).toBe('metadata')
|
|
expect(parseFieldAddress('verb', 'relation').scope).toBe('metadata')
|
|
})
|
|
|
|
it('metadata.-prefix is the explicit spelling of the bare form', () => {
|
|
expect(parseFieldAddress('metadata.level', 'entity')).toEqual({
|
|
scope: 'metadata',
|
|
field: 'level',
|
|
raw: 'metadata.level'
|
|
})
|
|
})
|
|
|
|
it('system.-prefix reaches exactly the map — entity and relation', () => {
|
|
for (const field of SYSTEM_ENTITY_SCALARS) {
|
|
expect(parseFieldAddress(`system.${field}`, 'entity')).toEqual({
|
|
scope: 'system',
|
|
field,
|
|
raw: `system.${field}`
|
|
})
|
|
}
|
|
for (const field of SYSTEM_RELATION_SCALARS) {
|
|
expect(parseFieldAddress(`system.${field}`, 'relation').scope).toBe('system')
|
|
}
|
|
// The structural relation members are NOT entity scalars.
|
|
expect(() => parseFieldAddress('system.verb', 'entity')).toThrow(InvalidFieldAddressError)
|
|
expect(() => parseFieldAddress('system.sourceId', 'entity')).toThrow(InvalidFieldAddressError)
|
|
})
|
|
|
|
it('plumbing refuses in the system spelling, on both record kinds', () => {
|
|
for (const field of PLUMBING_FIELDS) {
|
|
expect(() => parseFieldAddress(`system.${field}`, 'entity')).toThrow(
|
|
InvalidFieldAddressError
|
|
)
|
|
expect(() => parseFieldAddress(`system.${field}`, 'relation')).toThrow(
|
|
InvalidFieldAddressError
|
|
)
|
|
}
|
|
})
|
|
|
|
it('refusal text carries the whole valid map — the fix lives in the message', () => {
|
|
try {
|
|
parseFieldAddress('system.level', 'entity')
|
|
expect.unreachable('should have thrown')
|
|
} catch (e) {
|
|
const msg = (e as Error).message
|
|
for (const field of SYSTEM_ENTITY_SCALARS) {
|
|
expect(msg).toContain(`system.${field}`)
|
|
}
|
|
expect(msg).toContain('plumbing')
|
|
}
|
|
})
|
|
|
|
it('malformed addresses refuse: empty name, bare metadata. prefix', () => {
|
|
expect(() => parseFieldAddress('', 'entity')).toThrow(InvalidFieldAddressError)
|
|
expect(() => parseFieldAddress('metadata.', 'entity')).toThrow(InvalidFieldAddressError)
|
|
})
|
|
|
|
it('the did-you-mean names BOTH candidates for a system-colliding bare name', () => {
|
|
const msg = buildUnresolvableMessage('createdAt', 'entity')
|
|
expect(msg).toContain('system.createdAt')
|
|
expect(msg).toContain('metadata.createdAt')
|
|
})
|
|
|
|
it('a non-colliding unknown bare name gets the single-candidate refusal', () => {
|
|
const msg = buildUnresolvableMessage('scoore', 'entity')
|
|
expect(msg).not.toContain('system.scoore')
|
|
expect(msg).toContain('metadata.scoore')
|
|
})
|
|
})
|