Setting up Unit Tests
Relevant source files
The following files were used as context for generating this wiki page:
The Calculator project implements a browser-based calculation engine with a logic layer decoupled from the DOM. Setting up unit tests for this system involves isolating core arithmetic functions, state management, and history logging to ensure mathematical accuracy and UI consistency.
The testing infrastructure focuses on validating the compute, round, and formatNum utilities, as well as state transitions governed by user inputs (digits, decimals, and operators). By leveraging a testing framework, developers can simulate keyboard and click events to verify that the internal state—represented by the current, previous, and operator variables—updates correctly.
Core Logic Architecture
The calculator's logic is encapsulated within a set of JavaScript functions that manage internal state and perform arithmetic operations. For unit testing, these functions represent the primary targets for validation.
Arithmetic and Calculation Engine
The compute function serves as the central processing unit for all mathematical operations. It handles addition, subtraction, multiplication, and division, including edge case handling for division by zero.
The logic relies on a round helper to maintain precision using toPrecision(12).
Sources: calculator.html:438-450, calculator.html:452-454
State Management Components
Unit tests must monitor the lifecycle of the calculator's state. The following variables define the system's status at any given time:
| Variable | Type | Description |
|---|---|---|
current | String | The value currently being entered or displayed. |
previous | String | The value stored before an operator was selected. |
operator | String/Null | The current active mathematical operator (+, −, ×, ÷). |
shouldReset | Boolean | Flag indicating if the next digit input should overwrite current. |
history | Array | Collection of previous calculation objects { expr, result }. |
Sources: calculator.html:388-393
Testable Interaction Flows
Testing the system requires simulating the data flow from user input through state modification to display updates.
Input Validation Flow
When a digit is input, the system checks the shouldReset flag and the length of the current string (capped at 14 characters) before updating the display.
Sources: calculator.html:408-413
Calculation and History Logging
The handleEquals function triggers the final computation, updates the history state, and resets the operator. This is a critical path for unit tests to ensure that the expression displayed matches the result stored in history.
| Step | Action | Logic Reference |
|---|---|---|
| 1 | Parse previous and current to Float | parseFloat() |
| 2 | Execute calculation | compute(a, b, operator) |
| 3 | Log to History | addHistory(expr, result) |
| 4 | Reset State | operator = null, shouldReset = true |
Sources: calculator.html:456-468
Formatting and Utility Testing
The project includes specific formatting logic that must be tested for UI consistency, particularly regarding localization and scientific notation.
Number Formatting Logic
The formatNum function handles:
- Converting strings to floats.
- Converting large numbers (>= 1e12) or very small numbers (< 1e-6) to exponential notation.
- Applying locale-specific separators (e.g., thousands separators) using
toLocaleString(). - Preserving decimal segments during string splitting.
Sources: calculator.html:398-413
Summary
Setting up unit tests for the Calculator involves targeting the core arithmetic logic in compute(), the precision-handling in round(), and the complex state transitions managed by inputDigit() and handleOp(). By focusing on these isolated functions, the test suite ensures that mathematical operations remain accurate while the state correctly reflects user interactions and history management. Sources: calculator.html:388-468