evidence-dsl: extract Evidence DSL v2 compiler from @arbiter/core
The Evidence DSL (ADR-000) is a thin declarative layer that compiles to engine rule types. It has zero runtime coupling to the core engine (DSLCompiler takes an arbiter as a duck-typed argument; the only shared code was the ip-utils helpers, now local). Extracting it into its own package keeps the core artifact free of the DSL surface. - @arbiter/evidence-dsl depends on @arbiter/core (config formats are the compilation target) - deep-path exports for the compiler, parser, generator, validation, and built-in functions (the surface the core's DSL tests consume) - tests moved alongside; generate-parser script + peggy devDep local - CI: test on push, publish on v* tags
This commit is contained in:
+249
@@ -0,0 +1,249 @@
|
||||
# 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
|
||||
```javascript
|
||||
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
|
||||
```javascript
|
||||
import { runSpecificTests } from '../../../../../lib/src/ast/tests/tests/TestRunner.js';
|
||||
|
||||
const results = runSpecificTests(arbiter, [
|
||||
'Expression Tests',
|
||||
'Definition Tests'
|
||||
]);
|
||||
```
|
||||
|
||||
### Run Tests by Level
|
||||
```javascript
|
||||
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
|
||||
```bash
|
||||
# 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
|
||||
Reference in New Issue
Block a user