initial commit: @arbiter/core authorization engine with js-rigor hardening
Zanzibar-style authorization graph engine (direct/chain/TTU/defeasible/ binary modes, condensed snapshots, value relations) with 39 rigor test campaigns. Includes fixes for snapshot binary writer/reader format mismatch (snapshot-of-snapshot corruption), possibility write-boundary validation, empty-graph snapshot serialization, relation lookup cache direction collision, config-redefinition cache invalidation, binary threshold semantics, defeasible compiled routing, and comparator reason whitelisting.
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { describe, test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { PeggyDSLParser } from '../../src/ast/parser/PeggyDSLParser.js';
|
||||
|
||||
describe('Peggy DSL Parser', () => {
|
||||
const parser = new PeggyDSLParser();
|
||||
|
||||
test('Basic parsing', () => {
|
||||
const dsl = `
|
||||
definition User {
|
||||
role: string
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
fact hasRole(user: User, role: string)
|
||||
|
||||
evidence canRead(user: User, doc: Document) {
|
||||
hasRole(user, 'admin')
|
||||
}
|
||||
`;
|
||||
|
||||
const program = parser.parse(dsl);
|
||||
assert.ok(program !== null, 'Program should be created');
|
||||
assert.ok(program.definitions.length === 1, 'Should have 1 definition');
|
||||
assert.ok(program.facts.length === 1, 'Should have 1 fact');
|
||||
assert.ok(program.evidence.length === 1, 'Should have 1 evidence');
|
||||
});
|
||||
|
||||
test('Complex DSL parsing', () => {
|
||||
const dsl = `
|
||||
definition User {
|
||||
role: string
|
||||
isActive: boolean
|
||||
clearance: string BEHAVES {
|
||||
blurring adaptive confidence_95
|
||||
} CACHE eager
|
||||
}
|
||||
|
||||
fact hasRole(user: User, role: string) CACHE eager
|
||||
fact isMember(user: User, group: Group) transitive CACHE lazy
|
||||
|
||||
evidence canRead(user: User, doc: Document) {
|
||||
hasRole(user, 'admin')
|
||||
|
||||
isMember(user, *group) {
|
||||
canRead(group, doc)
|
||||
} limit 5
|
||||
|
||||
WHEN hasRole(user, 'admin') UNLESS isSuspended(user)
|
||||
}
|
||||
`;
|
||||
|
||||
const program = parser.parse(dsl);
|
||||
assert.ok(program !== null, 'Program should be created');
|
||||
assert.ok(program.definitions.length === 1, 'Should have 1 definition');
|
||||
assert.ok(program.facts.length === 2, 'Should have 2 facts');
|
||||
assert.ok(program.evidence.length === 1, 'Should have 1 evidence');
|
||||
});
|
||||
|
||||
test('Error handling', () => {
|
||||
const invalidDSL = `
|
||||
definition User {
|
||||
role: string
|
||||
// Missing closing brace
|
||||
|
||||
fact hasRole(user: User, role: string)
|
||||
// Missing semicolon
|
||||
`;
|
||||
|
||||
assert.throws(
|
||||
() => parser.parse(invalidDSL),
|
||||
/Parsing failed/,
|
||||
'Should have parsing error message'
|
||||
);
|
||||
});
|
||||
|
||||
test('Validation', () => {
|
||||
const validDSL = `
|
||||
definition User {
|
||||
role: string
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
fact hasRole(user: User, role: string)
|
||||
`;
|
||||
|
||||
const invalidDSL = `
|
||||
definition User {
|
||||
role: string
|
||||
// Missing closing brace
|
||||
`;
|
||||
|
||||
const validResult = parser.validate(validDSL);
|
||||
assert.ok(validResult.success, 'Valid DSL should pass validation');
|
||||
assert.ok(validResult.program !== null, 'Valid DSL should return program');
|
||||
|
||||
const invalidResult = parser.validate(invalidDSL);
|
||||
assert.ok(!invalidResult.success, 'Invalid DSL should fail validation');
|
||||
assert.ok(invalidResult.errors.length > 0, 'Should have validation errors');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user