UNPKG

boolean-expression-solve

Version:

Boolean expression solver, simplifier, truth-table generator

300 lines (249 loc) โ€ข 10.4 kB
const { simplify, getTruthTable, getVariables, isValidExpression, evaluate } = require('./index'); /** * Test runner utility */ class TestRunner { constructor() { this.passed = 0; this.failed = 0; this.tests = []; } test(description, testFunction) { try { console.log(`\n๐Ÿงช Testing: ${description}`); const result = testFunction(); if (result === true || result === undefined) { console.log(`โœ… PASSED: ${description}`); this.passed++; } else { console.log(`โŒ FAILED: ${description} - ${result}`); this.failed++; } } catch (error) { console.log(`โŒ ERROR: ${description} - ${error.message}`); this.failed++; } this.tests.push({ description, passed: this.failed === 0 }); } expect(actual, expected, message = '') { if (JSON.stringify(actual) === JSON.stringify(expected)) { return true; } else { return `Expected: ${JSON.stringify(expected)}, Got: ${JSON.stringify(actual)} ${message}`; } } summary() { console.log('\n' + '='.repeat(60)); console.log('๐Ÿ“Š TEST SUMMARY'); console.log('='.repeat(60)); console.log(`โœ… Passed: ${this.passed}`); console.log(`โŒ Failed: ${this.failed}`); console.log(`๐Ÿ“ˆ Total: ${this.passed + this.failed}`); console.log(`๐ŸŽฏ Success Rate: ${((this.passed / (this.passed + this.failed)) * 100).toFixed(1)}%`); if (this.failed === 0) { console.log('\n๐ŸŽ‰ All tests passed!'); } else { console.log('\nโš ๏ธ Some tests failed. Check the output above.'); } } } // Initialize test runner const test = new TestRunner(); console.log('๐Ÿš€ Starting Boolean Expression Simplifier Tests...\n'); // Test 1: Basic simplification test.test('Basic OR simplification: A + A should equal A', () => { const result = simplify('A + A'); return test.expect(result, 'A'); }); test.test('Basic AND simplification: A . A should equal A', () => { const result = simplify('A . A'); return test.expect(result, 'A'); }); // Test 2: Identity laws test.test('Identity law: A + 0 should equal A', () => { const result = simplify('A + 0'); return test.expect(result, 'A'); }); test.test('Identity law: A . 1 should equal A', () => { const result = simplify('A . 1'); return test.expect(result, 'A'); }); // Test 3: Domination laws test.test('Domination law: A + 1 should equal 1', () => { const result = simplify('A + 1'); return test.expect(result, '1'); }); test.test('Domination law: A . 0 should equal 0', () => { const result = simplify('A . 0'); return test.expect(result, '0'); }); // Test 4: Complement laws test.test('Complement law: A + A\' should equal 1', () => { const result = simplify('A + A\''); return test.expect(result, '1'); }); test.test('Complement law: A . A\' should equal 0', () => { const result = simplify('A . A\''); return test.expect(result, '0'); }); // Test 5: Absorption laws test.test('Absorption law: A + A.B should equal A', () => { const result = simplify('A + A.B'); return test.expect(result, 'A'); }); test.test('Absorption law: A.(A + B) should equal A', () => { const result = simplify('A.(A + B)'); return test.expect(result, 'A'); }); // Test 6: Complex expressions test.test('Complex expression: (A+B).(A+B\') should equal A', () => { const result = simplify('(A+B).(A+B\')'); return test.expect(result, 'A'); }); test.test('Your original complex expression', () => { const result = simplify('(A+B\'+C).(A\'+B+C)(A\'+B+C\')(A\'+B\'+C).(A\'+B\'+C\')'); // This should simplify to something shorter return result.length < 50; // Just check if it's simplified (shorter) }); // Test 7: getVariables function test.test('Extract variables from A + B.C', () => { const result = getVariables('A + B.C'); return test.expect(result, ['A', 'B', 'C']); }); test.test('Extract variables from complex expression', () => { const result = getVariables('(X+Y\'+Z).(W\'+X+Y)'); return test.expect(result, ['W', 'X', 'Y', 'Z']); }); test.test('Extract variables from expression with no variables (constants)', () => { const result = getVariables('1 + 0'); return test.expect(result, []); }); // Test 8: isValidExpression function test.test('Valid expression: A + B should be valid', () => { const result = isValidExpression('A + B'); return test.expect(result, true); }); test.test('Valid complex expression should be valid', () => { const result = isValidExpression('(A+B\').(C+D)'); return test.expect(result, true); }); test.test('Invalid expression with double operators should be invalid', () => { const result = isValidExpression('A + + B'); return test.expect(result, false); }); // Test 9: evaluate function test.test('Evaluate A + B with A=0, B=1 should equal 1', () => { const result = evaluate('A + B', { A: 0, B: 1 }); return test.expect(result, 1); }); test.test('Evaluate A . B with A=1, B=0 should equal 0', () => { const result = evaluate('A . B', { A: 1, B: 0 }); return test.expect(result, 0); }); test.test('Evaluate A\' with A=1 should equal 0', () => { const result = evaluate('A\'', { A: 1 }); return test.expect(result, 0); }); test.test('Evaluate complex expression (A+B).C with A=0, B=1, C=1 should equal 1', () => { const result = evaluate('(A+B).C', { A: 0, B: 1, C: 1 }); return test.expect(result, 1); }); // Test 10: getTruthTable function (string format) test.test('Truth table string for A + B should contain correct header', () => { const result = getTruthTable('A + B', 'string'); return result.includes('| A | B | A + B |'); }); test.test('Truth table string should contain 4 data rows for 2 variables', () => { const result = getTruthTable('A + B', 'string'); const lines = result.split('\n'); const dataRows = lines.filter(line => line.match(/^\| [01] \| [01] \|/)); return test.expect(dataRows.length, 4); }); // Test 11: getTruthTable function (array format) test.test('Truth table array for A + B should have 4 rows', () => { const result = getTruthTable('A + B', 'array'); return test.expect(result.length, 4); }); test.test('Truth table array should have correct structure', () => { const result = getTruthTable('A + B', 'array'); const firstRow = result[0]; const hasRequiredProps = firstRow.hasOwnProperty('inputs') && firstRow.hasOwnProperty('output') && firstRow.hasOwnProperty('expression'); return test.expect(hasRequiredProps, true); }); test.test('Truth table array for A + B should have correct first row', () => { const result = getTruthTable('A + B', 'array'); const expectedFirstRow = { inputs: { A: 0, B: 0 }, output: 0, expression: 'A + B' }; return test.expect(result[0], expectedFirstRow); }); // Test 12: Error handling test.test('getTruthTable with invalid type should return Error', () => { const result = getTruthTable('A + B', 'invalid'); return result instanceof Error; }); test.test('evaluate with missing variables should throw error', () => { try { evaluate('A + B', { A: 1 }); // Missing B return 'Should have thrown an error'; } catch (error) { return true; // Expected to throw } }); // Test 13: Case insensitivity test.test('Case insensitive input: a + b should work', () => { const result = getVariables('a + b'); return test.expect(result, ['A', 'B']); // Variables should be normalized to uppercase }); // Test 14: Edge cases test.test('Single variable should remain unchanged', () => { const result = simplify('A'); return test.expect(result, 'A'); }); test.test('Constant 1 should remain 1', () => { const result = simplify('1'); return test.expect(result, '1'); }); test.test('Constant 0 should remain 0', () => { const result = simplify('0'); return test.expect(result, '0'); }); // Test 15: Performance test with large expression test.test('Performance test: Complex expression should complete in reasonable time', () => { const start = Date.now(); const result = simplify('(A+B+C).(A+B+C\').(A+B\'+C).(A+B\'+C\').(A\'+B+C).(A\'+B+C\').(A\'+B\'+C)'); const end = Date.now(); const duration = end - start; console.log(` โฑ๏ธ Execution time: ${duration}ms`); console.log(` ๐Ÿ“ Result: ${result}`); return duration < 5000; // Should complete in less than 5 seconds }); // Display comprehensive test results console.log('\n' + '='.repeat(60)); console.log('๐Ÿ” DETAILED FUNCTION TESTING'); console.log('='.repeat(60)); // Demo of actual outputs console.log('\n๐Ÿ“‹ Sample Function Outputs:'); console.log('โ”€'.repeat(40)); console.log('\n1. simplify() examples:'); console.log(` simplify('A + A.B') = "${simplify('A + A.B')}"`); console.log(` simplify('(A+B).(A+B\\')') = "${simplify('(A+B).(A+B\')')}"`); console.log('\n2. getVariables() examples:'); console.log(` getVariables('A + B.C') = [${getVariables('A + B.C').join(', ')}]`); console.log('\n3. evaluate() examples:'); console.log(` evaluate('A + B', {A: 0, B: 1}) = ${evaluate('A + B', { A: 0, B: 1 })}`); console.log(` evaluate('A . B', {A: 1, B: 0}) = ${evaluate('A . B', { A: 1, B: 0 })}`); console.log('\n4. getTruthTable() array example:'); const sampleTruthArray = getTruthTable('A . B', 'array'); console.log(' getTruthTable(\'A . B\', \'array\'):'); sampleTruthArray.forEach((row, index) => { console.log(` [${index}] ${JSON.stringify(row)}`); }); console.log('\n5. getTruthTable() string example:'); console.log(' getTruthTable(\'A + B\', \'string\'):'); const sampleTruthString = getTruthTable('A + B', 'string'); sampleTruthString.split('\n').forEach(line => { console.log(` ${line}`); }); // Run test summary test.summary();