init geek calc
Some checks failed
Deploy to GitHub Pages / build-and-deploy (push) Has been cancelled

This commit is contained in:
2025-10-04 10:53:41 +08:00
commit 54f427ea21
45 changed files with 4878 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
// Contract test for Core Calculator API
// This test should fail initially since the calculator module doesn't exist yet
// Define expected interface for calculator module
const expectedCalculatorInterface = [
'evaluate',
'add',
'subtract',
'multiply',
'divide',
'percentage',
'toggleSign',
'clear',
'getCurrentDisplay'
];
// Test if calculator module exists and has expected interface
function testCalculatorInterface() {
try {
// This will fail since calculator.js doesn't exist yet
const calc = new Calculator();
// Check if all expected methods exist
for (const method of expectedCalculatorInterface) {
if (typeof calc[method] !== 'function') {
throw new Error(`Method ${method} does not exist on Calculator`);
}
}
// Test basic functionality
// Add should return sum of two numbers
if (calc.add(2, 3) !== 5) {
throw new Error('Calculator add method does not return correct result');
}
// Subtract should return difference
if (calc.subtract(5, 3) !== 2) {
throw new Error('Calculator subtract method does not return correct result');
}
// Multiply should return product
if (calc.multiply(4, 5) !== 20) {
throw new Error('Calculator multiply method does not return correct result');
}
// Divide should return quotient
if (calc.divide(10, 2) !== 5) {
throw new Error('Calculator divide method does not return correct result');
}
// Division by zero should return Infinity
if (!isFinite(calc.divide(10, 0))) {
// This is expected, division by zero returns Infinity
} else {
throw new Error('Calculator divide by zero does not return Infinity');
}
// Percentage should convert percentage to decimal
if (calc.percentage(50) !== 0.5) {
throw new Error('Calculator percentage method does not return correct result');
}
// ToggleSign should change sign
if (calc.toggleSign(5) !== -5) {
throw new Error('Calculator toggleSign method does not return correct result');
}
if (calc.toggleSign(-5) !== 5) {
throw new Error('Calculator toggleSign method does not return correct result for negative number');
}
// Clear should reset to initial state
calc.clear();
if (calc.getCurrentDisplay() !== '0') {
throw new Error('Calculator clear method does not reset to initial state');
}
// Evaluate should handle simple expressions
if (calc.evaluate('2 + 3') !== 5) {
throw new Error('Calculator evaluate method does not return correct result');
}
return true; // All tests passed
} catch (error) {
return { error: error.message };
}
}
// Add test to global test collection
if (typeof addTest !== 'undefined') {
addTest('Calculator Interface Contract', testCalculatorInterface);
} else {
console.log('Test harness not loaded. Run with test runner.');
}

98
tests/unit/math.test.js Normal file
View File

@@ -0,0 +1,98 @@
// Unit tests for core math operations
// These tests should fail initially since the calculator module doesn't exist yet
function testMathOperations() {
try {
// This will fail since calculator.js doesn't exist yet
const calc = new Calculator();
// Test addition
if (calc.add(2, 3) !== 5) {
throw new Error('Addition failed: 2 + 3 should equal 5');
}
if (calc.add(-1, 1) !== 0) {
throw new Error('Addition failed: -1 + 1 should equal 0');
}
if (calc.add(0, 0) !== 0) {
throw new Error('Addition failed: 0 + 0 should equal 0');
}
// Test subtraction
if (calc.subtract(5, 3) !== 2) {
throw new Error('Subtraction failed: 5 - 3 should equal 2');
}
if (calc.subtract(0, 5) !== -5) {
throw new Error('Subtraction failed: 0 - 5 should equal -5');
}
// Test multiplication
if (calc.multiply(4, 5) !== 20) {
throw new Error('Multiplication failed: 4 * 5 should equal 20');
}
if (calc.multiply(-2, 3) !== -6) {
throw new Error('Multiplication failed: -2 * 3 should equal -6');
}
if (calc.multiply(0, 100) !== 0) {
throw new Error('Multiplication failed: 0 * 100 should equal 0');
}
// Test division
if (calc.divide(10, 2) !== 5) {
throw new Error('Division failed: 10 / 2 should equal 5');
}
if (calc.divide(7, 2) !== 3.5) {
throw new Error('Division failed: 7 / 2 should equal 3.5');
}
// Test division by zero (should return Infinity)
const divByZero = calc.divide(5, 0);
if (!isFinite(divByZero)) {
// This is expected, division by zero returns Infinity
} else {
throw new Error('Division by zero should return Infinity');
}
// Test percentage
if (calc.percentage(50) !== 0.5) {
throw new Error('Percentage failed: 50% should equal 0.5');
}
if (calc.percentage(100) !== 1) {
throw new Error('Percentage failed: 100% should equal 1');
}
if (calc.percentage(0) !== 0) {
throw new Error('Percentage failed: 0% should equal 0');
}
// Test toggle sign
if (calc.toggleSign(5) !== -5) {
throw new Error('Toggle sign failed: 5 should become -5');
}
if (calc.toggleSign(-5) !== 5) {
throw new Error('Toggle sign failed: -5 should become 5');
}
if (calc.toggleSign(0) !== 0) {
throw new Error('Toggle sign failed: 0 should remain 0');
}
return true; // All tests passed
} catch (error) {
return { error: error.message };
}
}
// Add test to global test collection
if (typeof addTest !== 'undefined') {
addTest('Math Operations Unit Tests', testMathOperations);
} else {
console.log('Test harness not loaded. Run with test runner.');
}

View File

@@ -0,0 +1,79 @@
// Contract test for RPN Calculator API
// This test should fail initially since the rpn-calculator module doesn't exist yet
// Define expected interface for RPN calculator module
const expectedRPNCalculatorInterface = [
'push',
'pop',
'operate',
'clear',
'getStack',
'evaluate'
];
// Test if RPN calculator module exists and has expected interface
function testRPNCalculatorInterface() {
try {
// This will fail since rpn-calculator.js doesn't exist yet
const rpnCalc = new RPNCalculator();
// Check if all expected methods exist
for (const method of expectedRPNCalculatorInterface) {
if (typeof rpnCalc[method] !== 'function') {
throw new Error(`Method ${method} does not exist on RPNCalculator`);
}
}
// Test basic RPN functionality
// Push should add value to stack
rpnCalc.push(3);
const stackAfterPush = rpnCalc.getStack();
if (stackAfterPush.length !== 1 || stackAfterPush[0] !== 3) {
throw new Error('RPN calculator push method does not work correctly');
}
// Pop should remove and return top value from stack
const poppedValue = rpnCalc.pop();
if (poppedValue !== 3) {
throw new Error('RPN calculator pop method does not return correct value');
}
// Stack should be empty after pop
if (rpnCalc.getStack().length !== 0) {
throw new Error('RPN calculator stack not empty after pop');
}
// Clear should empty the stack
rpnCalc.push(1);
rpnCalc.push(2);
rpnCalc.clear();
if (rpnCalc.getStack().length !== 0) {
throw new Error('RPN calculator clear method does not empty the stack');
}
// Operate should perform operation on stack values
rpnCalc.push(2);
rpnCalc.push(3);
const result = rpnCalc.operate('+');
if (result !== 5) {
throw new Error('RPN calculator operate method does not return correct result for addition');
}
// Evaluate should handle RPN expressions
const evalResult = rpnCalc.evaluate('2 3 +');
if (evalResult !== 5) {
throw new Error('RPN calculator evaluate method does not return correct result');
}
return true; // All tests passed
} catch (error) {
return { error: error.message };
}
}
// Add test to global test collection
if (typeof addTest !== 'undefined') {
addTest('RPN Calculator Interface Contract', testRPNCalculatorInterface);
} else {
console.log('Test harness not loaded. Run with test runner.');
}

93
tests/unit/rpn.test.js Normal file
View File

@@ -0,0 +1,93 @@
// Unit tests for RPN stack operations
// These tests should fail initially since the rpn-calculator module doesn't exist yet
function testRPNStackOperations() {
try {
// This will fail since rpn-calculator.js doesn't exist yet
const rpnCalc = new RPNCalculator();
// Test push operation
rpnCalc.push(1);
rpnCalc.push(2);
rpnCalc.push(3);
const stack = rpnCalc.getStack();
if (stack.length !== 3 || stack[0] !== 1 || stack[1] !== 2 || stack[2] !== 3) {
throw new Error('RPN push operation failed: stack does not contain expected values');
}
// Test pop operation
const popped = rpnCalc.pop();
if (popped !== 3) {
throw new Error('RPN pop operation failed: did not return top value');
}
// Stack should now have 2 elements
if (rpnCalc.getStack().length !== 2) {
throw new Error('RPN pop operation failed: stack length incorrect after pop');
}
// Test multiple operations
rpnCalc.clear();
rpnCalc.push(4);
rpnCalc.push(2);
// Perform addition: 4 + 2 = 6
const addResult = rpnCalc.operate('+');
if (addResult !== 6) {
throw new Error('RPN addition operation failed: 4 2 + should equal 6');
}
// Perform subtraction: 6 - 2 = 4 (the 2 was consumed, now 6-2)
rpnCalc.push(2);
const subResult = rpnCalc.operate('-');
if (subResult !== 4) {
throw new Error('RPN subtraction operation failed: 6 2 - should equal 4');
}
// Test multiplication
rpnCalc.push(3);
rpnCalc.push(4);
const multResult = rpnCalc.operate('*');
if (multResult !== 12) {
throw new Error('RPN multiplication operation failed: 3 4 * should equal 12');
}
// Test division
rpnCalc.push(12);
rpnCalc.push(4);
const divResult = rpnCalc.operate('/');
if (divResult !== 3) {
throw new Error('RPN division operation failed: 12 4 / should equal 3');
}
// Test division by zero
rpnCalc.push(5);
rpnCalc.push(0);
const divByZeroResult = rpnCalc.operate('/');
if (!isFinite(divByZeroResult)) {
// This is expected behavior for division by zero in RPN
} else {
throw new Error('RPN division by zero should return Infinity');
}
// Test clear operation
rpnCalc.push(10);
rpnCalc.push(20);
rpnCalc.clear();
if (rpnCalc.getStack().length !== 0) {
throw new Error('RPN clear operation failed: stack not empty after clear');
}
return true; // All tests passed
} catch (error) {
return { error: error.message };
}
}
// Add test to global test collection
if (typeof addTest !== 'undefined') {
addTest('RPN Stack Operations Unit Tests', testRPNStackOperations);
} else {
console.log('Test harness not loaded. Run with test runner.');
}