Files
evidence-dsl/tests/MeasureTests.js
T

307 lines
9.0 KiB
JavaScript
Raw Normal View History

import { describe, test } from 'node:test';
import assert from 'node:assert/strict';
import { DSLCompiler } from '../src/DSLCompiler.js';
function createMockArbiter() {
const relationConfigs = new Map();
return {
relationConfigs,
setRelationConfig(relation, config) {
relationConfigs.set(relation, config);
}
};
}
describe('Measure Definitions', () => {
const arbiter = createMockArbiter();
const compiler = new DSLCompiler(arbiter);
test('Basic measures', () => {
const testCases = [
{
input: `measure userRole(user: User) {
user.role
} PROVIDES string`,
description: 'Simple measure with attribute access'
},
{
input: `measure userBalance(user: User) {
user.balance
} PROVIDES number`,
description: 'Measure accessing numeric attribute'
},
{
input: `measure isUserActive(user: User) {
user.isActive
} PROVIDES boolean`,
description: 'Measure accessing boolean attribute'
},
{
input: `measure userPermissions(user: User) {
user.permissions
} PROVIDES Permission[]`,
description: 'Measure accessing array attribute'
},
{
input: `measure userScore(user: User) {
user.score
} PROVIDES number`,
description: 'Measure with behavior-inherited attribute'
}
];
testCases.forEach(({ input, description }) => {
const result = compiler.compile(input, `test-basic-measure-${Date.now()}`);
assert.ok(result.success, `${description} should parse successfully`);
assert.ok(result.program.measures.length > 0, 'Should have measures');
});
});
test('Measure return types', () => {
const testCases = [
{ type: 'string', description: 'String return type' },
{ type: 'number', description: 'Number return type' },
{ type: 'boolean', description: 'Boolean return type' },
{ type: 'timestamp', description: 'Timestamp return type' },
{ type: 'Permission[]', description: 'Array return type' },
{ type: 'User', description: 'Custom type return' },
{ type: 'Group[]', description: 'Custom array return type' }
];
testCases.forEach(({ type, description }) => {
const dsl = `measure test() { true } PROVIDES ${type}`;
const result = compiler.compile(dsl, `test-measure-return-${Date.now()}`);
assert.ok(result.success, `${description} should parse successfully`);
});
});
test('Measure aggregation', () => {
const testCases = [
{
input: `measure userPermissions(user: User) {
aggregate {
user.role.permissions
user.group.permissions
} USING majority
} PROVIDES Permission[]`,
description: 'Aggregation with majority strategy'
},
{
input: `measure userClearance(user: User) {
aggregate {
user.clearance
user.role.clearance
user.group.clearance
} USING max
} PROVIDES string`,
description: 'Aggregation with max strategy'
},
{
input: `measure userScore(user: User) {
aggregate {
user.reputation
user.activityScore
user.verificationLevel
} USING average
} PROVIDES number`,
description: 'Aggregation with average strategy'
},
{
input: `measure userTrust(user: User) {
aggregate {
user.reputation
user.activityScore
user.verificationLevel
user.socialProof
} USING min
} PROVIDES number`,
description: 'Aggregation with min strategy'
}
];
testCases.forEach(({ input, description }) => {
const result = compiler.compile(input, `test-measure-aggregation-${Date.now()}`);
assert.ok(result.success, `${description} should parse successfully`);
});
});
test('Measure fusion', () => {
const testCases = [
{
input: `measure effectiveClearance(user: User) {
fusion max {
user.clearance
user.role.clearance
user.group.clearance
}
} PROVIDES string`,
description: 'Fusion with max strategy'
},
{
input: `measure userPermissions(user: User) {
fusion min {
user.role.permissions
user.group.permissions
}
} PROVIDES Permission[]`,
description: 'Fusion with min strategy'
},
{
input: `measure userScore(user: User) {
fusion majority {
user.reputation
user.activityScore
user.verificationLevel
}
} PROVIDES number`,
description: 'Fusion with majority strategy'
},
{
input: `measure userTrust(user: User) {
fusion average {
user.reputation
user.activityScore
user.verificationLevel
user.socialProof
}
} PROVIDES number`,
description: 'Fusion with average strategy'
}
];
testCases.forEach(({ input, description }) => {
const result = compiler.compile(input, `test-measure-fusion-${Date.now()}`);
assert.ok(result.success, `${description} should parse successfully`);
});
});
test('Complex measures', () => {
const testCases = [
{
input: `measure userEffectivePermissions(user: User) {
aggregate {
user.role.permissions
user.group.permissions
user.directPermissions
} USING majority
} PROVIDES Permission[]`,
description: 'Complex aggregation with multiple sources'
},
{
input: `measure userTrustScore(user: User) {
fusion average {
user.reputation
user.activityScore
user.verificationLevel
user.socialProof
user.peerRatings
}
} PROVIDES number`,
description: 'Complex fusion with multiple metrics'
},
{
input: `measure userAccessLevel(user: User) {
fusion max {
user.clearance
user.role.clearance
user.group.clearance
user.temporaryClearance
}
} PROVIDES string`,
description: 'Complex clearance calculation'
},
{
input: `measure userSimilarity(user1: User, user2: User) {
similar(user1, user2) |similarity| {
similarity
} with similarity > 0.5
} PROVIDES number`,
description: 'Similarity measure with pattern matching'
},
{
input: `measure userEffectiveRole(user: User) {
fusion majority {
user.role
user.temporaryRole
user.actingRole
}
} PROVIDES string`,
description: 'Role determination with multiple sources'
}
];
testCases.forEach(({ input, description }) => {
const result = compiler.compile(input, `test-complex-measure-${Date.now()}`);
assert.ok(result.success, `${description} should parse successfully`);
});
});
test('Measure error handling', () => {
const testCases = [
{
input: `measure userRole(user: User) {
user.role
}`,
description: 'Missing PROVIDES clause should fail',
expectSuccess: false
},
{
input: `measure userRole(user: User) {
user.role
} PROVIDES`,
description: 'Incomplete PROVIDES clause should fail',
expectSuccess: false
},
{
input: `measure userRole(user: User) {
user.role
} PROVIDES string`,
description: 'Valid measure should succeed',
expectSuccess: true
},
{
input: `measure userPermissions(user: User) {
aggregate {
user.role.permissions
user.group.permissions
} USING
} PROVIDES Permission[]`,
description: 'Incomplete USING clause should fail',
expectSuccess: false
},
{
input: `measure userScore(user: User) {
fusion {
user.reputation
user.activityScore
}
} PROVIDES number`,
description: 'Missing fusion strategy should fail',
expectSuccess: false
},
{
input: `measure userRole(user: User) {
invalid syntax here
} PROVIDES string`,
description: 'Invalid syntax should fail',
expectSuccess: false
}
];
testCases.forEach(({ input, description, expectSuccess }) => {
try {
const result = compiler.compile(input, `test-measure-error-${Date.now()}`);
if (expectSuccess) {
assert.ok(result.success, `${description} should parse successfully`);
} else {
assert.ok(!result.success, `${description} should fail to parse`);
}
} catch {
if (!expectSuccess) {
// Expected to fail
}
}
});
});
});