A production-grade implementation of the famous String Calculator Kata, demonstrating strict Test-Driven Development (TDD) practices and clean architecture principles.
This calculator handles complex string parsing scenarios including:
- Basic Arithmetic: Sums comma-separated integers.
- Robust Parsing: Handles newlines (
\n) and custom delimiters seamlessly. - Advanced Delimiters:
- Custom single-character delimiters (e.g.,
//;\n1;2) - Multi-character delimiters (e.g.,
//[***]\n1***2***3) - Multiple different delimiters (e.g.,
//[*][%]\n1*2%3) - Multiple multi-character delimiters (e.g.,
//[foo][bar]\n1foo2bar3)
- Custom single-character delimiters (e.g.,
- Safety:
- Ignores empty entries caused by consecutive delimiters (
1,,2→ 3). - Ignores numbers > 1000.
- Throws informative exceptions for negative numbers, listing all offenders.
- Ignores empty entries caused by consecutive delimiters (
| # | Feature | Example | Output | Status |
|---|---|---|---|---|
| 1 | Empty String | add("") |
0 |
✅ |
| 2 | Single Number | add("1") |
1 |
✅ |
| 3 | Multiple Numbers | add("1,2,3") |
6 |
✅ |
| 4 | Newline Delimiter | add("1\n2,3") |
6 |
✅ |
| 5 | Custom Delimiter | add("//;\n1;2") |
3 |
✅ |
| 6 | Negative Exception | add("-1,2") |
Exception | ✅ |
| 7 | All Negatives Listed | add("-1,-2") |
Exception: -1, -2 | ✅ |
| 8 | Ignore > 1000 | add("2,1001") |
2 |
✅ |
| 9 | Multi-char Delimiter | add("//[***]\n1***2") |
3 |
✅ |
| 10 | Multiple Delimiters | add("//[*][%]\n1*2%3") |
6 |
✅ |
| 11 | Multi-char Multiple | add("//[foo][bar]\n1foo2bar3") |
6 |
✅ |
| 12 | Consecutive Delimiters | add("1,,2") |
3 |
✅ |
| 13 | Trailing Delimiters | add("1,2,") |
3 |
✅ |
| 14 | Boundary (1000) | add("1000,1001,5") |
1005 |
✅ |
| 15 | Invalid Input | add("1,a,3") |
Exception | ✅ |
This project was built using the Red-Green-Refactor cycle.
- Unified Regex Parsing: Instead of messy
if-elsechains for different delimiter types, the solution compiles all delimiters into a singleRegExp. This makes theaddmethod purely functional and declarative. - Immutability: The code prioritizes
finalvariables and pure functions to reduce side effects. - Defensive Coding:
RegExp.escape()is used to prevent special characters (like*or+) from crashing the parser.- Boundary checks (e.g., inclusive vs exclusive limits) are explicitly tested.
This project uses the standard test package.
Run all tests:
dart testRun with expanded output (to see individual test cases):
dart test -r expandedstring_calculator_kata/
├── lib/
│ ├── string_calculator_kata.dart # Main logic (Parse -> Filter -> Reduce)
└── test/
│ └── string_calculator_kata_test.dart # Comprehensive test suite
└── README.md
The git log of this repository serves as proof of the TDD process, featuring atomic commits tagged with test: [RED], feat: [GREEN], and refactor steps.
Implemented as part of the Incubyte TDD Assessment.
