test(namespace): unit pins for the pure law — the ruled maps verbatim (incl. the relation mirror, unpinnable via public API), plumbing refusals both kinds, did-you-mean text
This commit is contained in:
parent
56deb2e888
commit
5502abcdd8
1 changed files with 141 additions and 0 deletions
141
tests/unit/db/fieldAddressing.test.ts
Normal file
141
tests/unit/db/fieldAddressing.test.ts
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* @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')
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue