UNPKG

the-rule-engine

Version:

⚙️ A small fluent DSL for conditional logic (validation, gating, etc)

189 lines (158 loc) 4.53 kB
// test/ruleEngine.test.js import { createRuleEngine } from '../src/index.js'; console.log('✅ Running RuleEngine Tests...'); // Helper function runTest(description, fn) { try { const result = fn(); console.log(`✅ ${description}: ${result}`); } catch (err) { console.error(`❌ ${description}:`, err.message); } } // // 1. Basic `when` logic // runTest('Simple .when() pass', () => { const engine = createRuleEngine() .when(u => u.age >= 18) .then(() => 'Allowed') .otherwise(() => 'Blocked'); return engine.evaluate({ age: 20 }) === 'Allowed'; }); runTest('Simple .when() fail', () => { const engine = createRuleEngine() .when(u => u.age >= 18) .then(() => 'Allowed') .otherwise(() => 'Blocked'); return engine.evaluate({ age: 15 }) === 'Blocked'; }); // // 2. Using .and() and .or() // runTest('.when() + .and()', () => { const engine = createRuleEngine() .when(u => u.age >= 18) .and(u => u.country === 'US') .then(() => 'Welcome') .otherwise(() => 'Denied'); return engine.evaluate({ age: 19, country: 'US' }) === 'Welcome'; }); runTest('.when() + .and() fail', () => { const engine = createRuleEngine() .when(u => u.age >= 18) .and(u => u.country === 'US') .then(() => 'Welcome') .otherwise(() => 'Denied'); return engine.evaluate({ age: 19, country: 'CA' }) === 'Denied'; }); runTest('.or() logic', () => { const engine = createRuleEngine() .when(u => u.age >= 18) .or(u => u.isAdmin) .then(() => 'Access') .otherwise(() => 'No Access'); return engine.evaluate({ age: 16, isAdmin: true }) === 'Access'; }); // // 3. Group logic // runTest('.group() for compound AND', () => { const engine = createRuleEngine() .group(g => g .when(u => u.role === 'editor') .and(u => u.active === true) ) .then(() => 'OK') .otherwise(() => 'Blocked'); return engine.evaluate({ role: 'editor', active: true }) === 'OK'; }); runTest('.orGroup()', () => { const engine = createRuleEngine() .when(u => u.age >= 21) .orGroup(g => g .when(u => u.role === 'vip') .and(u => u.premium === true) ) .then(() => 'Granted') .otherwise(() => 'Denied'); return engine.evaluate({ role: 'vip', premium: true }) === 'Granted'; }); runTest('.andGroup()', () => { const engine = createRuleEngine() .when(u => u.age >= 18) .andGroup(g => g .when(u => u.verified) .and(u => u.subscribed) ) .then(() => 'Welcome') .otherwise(() => 'Denied'); return engine.evaluate({ age: 20, verified: true, subscribed: true }) === 'Welcome'; }); // // 4. Negated group // runTest('.notGroup() blocks banned users', () => { const engine = createRuleEngine() .when(u => u.role === 'user') .notGroup(g => g.when(u => u.banned).or(u => u.inactive) ) .then(() => 'Accepted') .otherwise(() => 'Rejected'); return engine.evaluate({ role: 'user', banned: false, inactive: false }) === 'Accepted' && engine.evaluate({ role: 'user', banned: true }) === 'Rejected'; }); // // 5. Nested ruleEngines // runTest('.or() with sub-engine', () => { const sub = createRuleEngine() .when(u => u.status === 'gold') .and(u => u.spending > 1000); const engine = createRuleEngine() .when(u => u.age > 25) .or(sub) .then(() => 'VIP') .otherwise(() => 'Standard'); return engine.evaluate({ age: 30 }) === 'VIP' && engine.evaluate({ status: 'gold', spending: 1500 }) === 'VIP'; }); // // 6. .not() with function // runTest('.not() with simple rule', () => { const engine = createRuleEngine() .when(u => u.active) .and(u => u.verified) .not(u => u.suspended) .then(() => 'Good') .otherwise(() => 'Bad'); return engine.evaluate({ active: true, verified: true, suspended: false }) === 'Good'; }); // // 7. .evaluateLogicOnly() // runTest('evaluateLogicOnly returns boolean', () => { const engine = createRuleEngine() .when(u => u.enabled) .and(u => u.subscribed); return engine.evaluateLogicOnly({ enabled: true, subscribed: true }) === true; }); // // 8. Edge cases // runTest('No then/otherwise returns null', () => { const engine = createRuleEngine().when(() => true); return engine.evaluate({}) === null; }); runTest('Throws on invalid condition', () => { let threw = false; try { createRuleEngine().when('not a function'); } catch { threw = true; } return threw; }); console.log('\n✅ All RuleEngine tests completed.\n');