Calculator Refactor
Level: Advanced 60–90 minConcepts: Refactoring
Solutions: C# | TypeScript | Python
You are given a calculator application. However, the solution is not perfect. All logic sits in “action scripts” behind button clicks, there are no test and it does not always handle operations correctly. E.g 1++2 equals 3 instead of “Error”
The code for this kata can be found at https://github.com/TDDBuddy/Wpf-Calculator-Kata
Your job is to write tests for the code, refactoring the code to create testable units pulling code left behind button clicks into something structured.
- Keep your check-ins small by limiting each one to a single refactoring.
- Should you find any bugs, fix them as you go by creating a failing test and then making it pass; then return to refactoring.
Bonus
Try and avoid the use of if or switch statements in your final solution.
Reference Walkthrough
Reference implementations in C#, TypeScript, and Python live at tddbuddy-reference-katas/calc-refactor. This is an F2 refactoring kata: the legacy WPF calculator’s behavior is captured in a shared characterization set (SCENARIOS.md), and each language ships a clean Calculator domain object that satisfies that contract byte-for-byte — including the fixed behavior for the 1++2 = 3 bug the brief calls out (the reference displays "Error", not 3) and division by zero (also "Error").
Scope note — calculator core only. The reference is scoped to the pure calculator domain: press(key) in, display string out. The WPF UI, event handlers, decimal entry, floating-point arithmetic, and memory buttons are all out of scope — a deliberate tightening that keeps the characterization set decidable and the F2 surface small. A small test-folder CalculatorBuilder lets every scenario open with one line naming the key sequence it exercises: aCalculator().pressKeys("1+2=").build().
- C# (.NET 8, xUnit, FluentAssertions 6.12.0) — walkthrough
- TypeScript (Node 20, Vitest 1.6, TS 5 strict) — walkthrough
- Python (3.11, pytest) — walkthrough
This kata ships in Agent Full-Bake mode at middle gear, the F2 (light builder) tier. See the repo’s Gears section for why middle gear is the deliberate choice once the characterization set is settled — the refactor lands in one commit per language because the bugs-vs-intent decisions were made up front, in SCENARIOS.md.
Related reading
- Product Literacy Is the New Core Engineering Skill
Engineering treated product literacy as a 'nice to have', useful but not core. With agents handling translation from intent to syntax, the engineer's value lives almost entirely in the translation from business reality to correctly-named domain model. Product literacy is the part that didn't get automated. - Agents Amplify Whatever Vocabulary They Find
Agents do not bring vocabulary to your codebase. They mirror what's already there. Strong vocabulary gets agent contributions that read like the team. Weak vocabulary gets faster mediocrity. The work you did for craft reasons just became leverage. - The Hidden Output of TDD Was Never Code
The visible artifact of TDD is a passing test suite. The actual artifact, the one that compounded value over the life of the codebase, was the vocabulary the team built while writing it. The dictionary, not the regression net.