Files
evidence-dsl/tests
John Dvorak 88f10f9db4
CI / publish (push) Successful in 11s
CI / test (push) Successful in 15s
feat: evidence composition — compile-time reference resolution for evidence sub-rules
An evidence may now reference another derived evidence as a sub-rule
(WHEN can_read(user, doc) where can_read is itself an evidence). Resolution
is a compile-time linker pass: after every evidence config is generated, each
direct reference to an evidence is inlined with that evidence's own (resolved)
config, so the engine evaluates a fully-resolved, acyclic config tree.

- resolveEvidenceReferences(): post-generation pass over evidence configs,
  recursing into logical/defeasible containers (when/unless/never/always/
  requires/union/intersection), always.direct nests, and comparator operands.
- Forward references resolve (all configs exist before the pass runs).
- Cycles and self-references are compile-time errors.
- _subjectAsObject scoping is preserved through inlining.
- dependsOn is recomputed after resolution, so partial-graph requirements
  reach transitively through composed evidence.
- buildDirectRule/buildPredicateRule now apply subject-scoping to top-level
  PredicateCall evidence bodies (latent gap, previously missed).
- validation: reject relation names shared across facts/sources/evidence/
  measures (a collision silently overwrote configs and read as a false cycle).

Tests: EvidenceComposition (9), DSLRuntime transitive requiredFacts, oracle
campaign composition construct, illegal-mutations cycle + cross-kind cases.
2026-08-03 11:17:30 -07:00
..

Evidence DSL Test Suite

Overview

This comprehensive test suite follows a structural linguistic approach to validate the Evidence DSL (Domain Specific Language) for authorization policies. The tests are organized incrementally from basic language primitives to complex integration scenarios.

Test Structure

1. Structural Linguistic Tests (StructuralLinguisticTests.js)

Level: Comprehensive

  • Lexical Primitives: Identifiers, literals, keywords, whitespace
  • Basic Expressions: Arithmetic, logical, comparison, temporal
  • Type System: Definitions, fields, behaviors, caching
  • Fact System: Declarations, properties, caching, limits
  • Evidence System: Rules, defeasible logic, pattern matching
  • Measure System: Aggregation, fusion, return types
  • Complex Integration: Multi-feature combinations

2. Expression Tests (ExpressionTests.js)

Level: Focused

  • Arithmetic operator precedence
  • Logical operator precedence
  • Comparison operators
  • Temporal expressions
  • Unary operators
  • Attribute access
  • Function calls
  • Complex expressions
  • Error handling

3. Definition Tests (DefinitionTests.js)

Level: Focused

  • Basic type definitions
  • Field types (string, number, boolean, timestamp, custom)
  • Array types
  • Behaviors (decay, blur, TTL)
  • Caching (eager, lazy)
  • Complex definitions
  • Error handling

4. Fact Tests (FactTests.js)

Level: Focused

  • Basic fact declarations
  • Fact properties (transitive, symmetrical)
  • Fact caching
  • Fact limits
  • Parameter types
  • Complex facts
  • Error handling

5. Evidence Tests (EvidenceTests.js)

Level: Focused

  • Basic evidence rules
  • Defeasible logic (ALWAYS, WHEN/UNLESS, REQUIRES)
  • Pattern matching with wildcards
  • Fusion strategies (min, max, majority, average)
  • Complex evidence composition
  • Error handling

6. Measure Tests (MeasureTests.js)

Level: Focused

  • Basic measure definitions
  • Return types
  • Aggregation with different strategies
  • Fusion with different strategies
  • Complex measures
  • Error handling

7. Integration Tests (IntegrationTests.js)

Level: Integration

  • Complete authorization systems
  • Multi-domain systems
  • Hierarchical access patterns
  • Similarity-based access
  • Temporal access patterns
  • Complex behaviors
  • Performance scenarios

Test Runner (TestRunner.js)

The test runner orchestrates all test suites and provides:

  • Comprehensive Testing: Run all test suites
  • Selective Testing: Run specific test suites
  • Level-based Testing: Run tests by complexity level
  • Detailed Reporting: Summary and detailed results
  • Coverage Analysis: Language feature coverage

Usage

Run All Tests

import { runAllTests } from '../../../../../lib/src/ast/tests/tests/TestRunner.js';

const results = runAllTests(arbiter);
console.log(`Tests: ${results.passed}/${results.total} passed`);

Run Specific Test Suites

import { runSpecificTests } from '../../../../../lib/src/ast/tests/tests/TestRunner.js';

const results = runSpecificTests(arbiter, [
  'Expression Tests',
  'Definition Tests'
]);

Run Tests by Level

import { runTestsByLevel } from '../../../../../lib/src/ast/tests/tests/TestRunner.js';

// Run only focused tests
const results = runTestsByLevel(arbiter, 'focused');

// Run only integration tests
const results = runTestsByLevel(arbiter, 'integration');

Language Feature Coverage

Lexical Primitives

  • Identifiers (simple, with underscores, with numbers)
  • Literals (string, number, boolean, duration)
  • Keywords (reserved words)
  • Whitespace and comments

Expression System

  • Arithmetic operators (+, -, *, /) with precedence
  • Logical operators (&&, ||, NOT) with precedence
  • Comparison operators (==, !=, >, <, >=, <=)
  • Temporal expressions (within)
  • Unary operators (NOT, !)
  • Attribute access (object.attribute)
  • Function calls (predicate(args))

Type System

  • Type definitions with fields
  • Field types (string, number, boolean, timestamp, custom)
  • Array types (Type[])
  • Behaviors (decay, blur, TTL)
  • Caching directives (eager, lazy)

Fact System

  • Fact declarations with parameters
  • Fact properties (transitive, symmetrical)
  • Caching directives
  • Limits for performance
  • Parameter types

Evidence System

  • Basic evidence rules
  • Defeasible logic (ALWAYS, WHEN/UNLESS, REQUIRES)
  • Pattern matching with wildcards (*)
  • Binding clauses (|variable|)
  • With clauses (with condition)
  • Limits for pattern matching
  • Fusion strategies (min, max, majority, average)

Measure System

  • Measure definitions
  • Return type specifications (PROVIDES)
  • Aggregation with strategies (USING)
  • Fusion with strategies
  • Complex value computation

Integration Features

  • Multi-domain systems
  • Hierarchical access patterns
  • Similarity-based access
  • Temporal access patterns
  • Complex behavior combinations
  • Performance optimization scenarios

Test Philosophy

Structural Linguistic Approach

The tests follow a structural linguistic methodology:

  1. Phonological Level: Basic lexical elements (identifiers, literals)
  2. Morphological Level: Word formation (operators, keywords)
  3. Syntactic Level: Grammar rules (expressions, statements)
  4. Semantic Level: Meaning (types, behaviors, logic)
  5. Pragmatic Level: Usage (integration, real-world scenarios)

Incremental Complexity

Tests progress from simple to complex:

  • Level 1: Lexical primitives
  • Level 2: Basic expressions
  • Level 3: Type system
  • Level 4: Fact system
  • Level 5: Evidence system
  • Level 6: Measure system
  • Level 7: Complex integration

Comprehensive Coverage

Each language feature is tested for:

  • Valid cases: Correct syntax and semantics
  • Invalid cases: Error handling and recovery
  • Edge cases: Boundary conditions
  • Integration: Multi-feature combinations

Running Tests

Prerequisites

  • Node.js environment
  • Arbiter instance for testing
  • All dependencies installed

Basic Usage

# Run all tests
npm test

# Run specific test file
node src/ast/tests/StructuralLinguisticTests.js

# Run with specific arbiter
node -e "
import { runAllTests } from '../../../../../lib/src/ast/tests/src/ast/tests/TestRunner.js';
const results = runAllTests(arbiter);
console.log(results);
"

Test Output

The test runner provides:

  • Progress indicators: Real-time test execution
  • Detailed results: Pass/fail status for each test
  • Error reporting: Specific error messages for failures
  • Performance metrics: Execution time for each suite
  • Coverage analysis: Language feature coverage

Contributing

When adding new tests:

  1. Follow the structural linguistic approach
  2. Test both valid and invalid cases
  3. Include error handling tests
  4. Document test purpose and expected behavior
  5. Maintain incremental complexity
  6. Update coverage documentation

Test Maintenance

  • Regular Updates: Keep tests current with language changes
  • Performance Monitoring: Track test execution time
  • Coverage Analysis: Ensure comprehensive feature coverage
  • Error Handling: Validate error messages and recovery
  • Integration Testing: Test real-world scenarios