From 8cbc205e1daa2f99cc0a676b6436772fe3eae453 Mon Sep 17 00:00:00 2001 From: Yury Bayda Date: Sat, 15 Aug 2026 00:37:06 -0700 Subject: [PATCH 1/2] fix: correct Legacy Code examples and curriculum links Wrap Class demonstrated inheritance rather than wrapping. Hold the legacy Engine in the wrapper and delegate to it, and correct the comparison table row that described the technique as subclassing. The sprouting kata told readers not to modify the original method, which sprouting cannot satisfy; ask for the minimal call site change instead. The C++ singleton compared a pointer against `null`. The invoice characterization test expected 1850.95 where the shown calculator returns 2132.10. The tax characterization test asserted against values it had just computed from the same calculator, which passes whatever the behaviour is; record the expected outputs instead. Point the Advanced TDD C++ Mars Rover link at the C++ repository. --- README.md | 4 +-- legacy-code/02-kata-identifying.md | 2 +- legacy-code/03-safety-net.md | 31 ++++++++++------------- legacy-code/05-safe-changes.md | 21 ++++++++------- legacy-code/06-kata-sprouting-wrapping.md | 6 ++--- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 079412a..9c4826e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Overview -Here you can find slides for Clean Code conversations or classes. +This repository contains slide decks for Clean Code conversations and classes. ## Development @@ -85,7 +85,7 @@ here are the only place the curriculum is edited. | 1 | Discussion | [Advanced TDD](advanced-tdd/01-advanced-tdd.md#warmup) | | 2 | Coding Dojo | Roman Numerals Kata ([Python][roman-numerals-python], [C++][roman-numerals-cpp]) | | 3 | Discussion | [Clean Tests](advanced-tdd/03-clean-tests.md#warmup) | -| 4 | Coding Dojo | Mars Rover Kata ([Python][mars-rover-python], [C++][mars-rover-python]) | +| 4 | Coding Dojo | Mars Rover Kata ([Python][mars-rover-python], [C++][mars-rover-cpp]) | | 5 | Coding Mob | Mars Rover Kata ([Python][mars-rover-python], [C++][mars-rover-cpp]) | | 6 | Discussion | Test Design / Test Process | | 7 | Coding Dojo | Hyper-optimized Telemetry Kata ([Python][hyper-optimized-telemetry-python], [C++][hyper-optimized-telemetry-cpp]) | diff --git a/legacy-code/02-kata-identifying.md b/legacy-code/02-kata-identifying.md index c34c546..77a79e8 100644 --- a/legacy-code/02-kata-identifying.md +++ b/legacy-code/02-kata-identifying.md @@ -28,7 +28,7 @@ private: public: static OrderProcessor* getInstance() { - if (instance == null) { + if (instance == nullptr) { instance = new OrderProcessor(); } return instance; diff --git a/legacy-code/03-safety-net.md b/legacy-code/03-safety-net.md index 3c8425e..7cbf486 100644 --- a/legacy-code/03-safety-net.md +++ b/legacy-code/03-safety-net.md @@ -67,7 +67,7 @@ TEST_CASE("InvoiceCalculator preserves existing behavior") { double result = calc.calculateTotal(items); // Document the exact current behavior - REQUIRE(result == Approx(1850.95)); + REQUIRE(result == Approx(2132.10)); // Note: This might not be correct behavior, // but it's what the system currently does } @@ -76,6 +76,9 @@ TEST_CASE("InvoiceCalculator preserves existing behavior") { ## Python Example: Characterization Testing Technique ```python +import pytest + + # Original Legacy Code class TaxCalculator: def calculate_tax(self, income, state): @@ -98,26 +101,20 @@ class TaxCalculator: def test_capture_current_tax_behavior(): calc = TaxCalculator() - # Test cases to capture current behavior + # Exact outputs captured from the current implementation test_cases = [ - (30000, "NY"), - (60000, "NY"), - (120000, "NY"), - (50000, "CA"), - (80000, "CA"), - (45000, "TX") + (30000, "NY", 1200), + (60000, "NY", 3600), + (120000, "NY", 10800), + (50000, "CA", 1500), + (80000, "CA", 5600), + (45000, "TX", 450), ] - # Store current behavior - results = { - case: calc.calculate_tax(*case) - for case in test_cases - } - # Verify behavior remains unchanged - for case in test_cases: - assert calc.calculate_tax(*case) == results[case], \ - f"Behavior changed for {case}" + for income, state, expected in test_cases: + result = calc.calculate_tax(income, state) + assert result == pytest.approx(expected), f"Behavior changed for {(income, state)}" ``` # Key Techniques diff --git a/legacy-code/05-safe-changes.md b/legacy-code/05-safe-changes.md index ece802b..f3bfefa 100644 --- a/legacy-code/05-safe-changes.md +++ b/legacy-code/05-safe-changes.md @@ -147,10 +147,13 @@ class Engine: ### Improved Code Example ```python -class LoggingEngine(Engine): +class LoggingEngine: + def __init__(self, engine): + self._engine = engine + def calculate_torque(self, rpm, throttle): print(f"[LOG] Calculating torque: rpm={rpm}, throttle={throttle}") - torque = super().calculate_torque(rpm, throttle) + torque = self._engine.calculate_torque(rpm, throttle) print(f"[LOG] Torque result: {torque}") return torque ``` @@ -158,7 +161,7 @@ class LoggingEngine(Engine): # Usage ```python -engine = LoggingEngine() +engine = LoggingEngine(Engine()) engine.calculate_torque(3000, 70) ``` @@ -200,12 +203,12 @@ car.drive() # Comparison & Benefits -| Technique | Location
of Change | Scope | Purpose | Risk | Code Impact | -| ------------- | ----------------------- | ---------------- | ------------------------------ | ---- | ------------------------- | -| Sprout Method | Same class | One method | Isolate new logic | Low | Add method,
call it | -| Sprout Class | New class | Functionality | Extract cohesive
behavior | Low | New class,
inject it | -| Wrap Method | Same class | One method | Insert logic around
method | Low | Rename + wrap
method | -| Wrap Class | Subclass | Multiple methods | Modify/extend
behavior | Med | New subclass
created | +| Technique | Location
of Change | Scope | Purpose | Risk | Code Impact | +| ------------- | ----------------------- | ---------------- | ------------------------------------ | ---- | ------------------------- | +| Sprout Method | Same class | One method | Isolate new logic | Low | Add method,
call it | +| Sprout Class | New class | Functionality | Extract cohesive
behavior | Low | New class,
inject it | +| Wrap Method | Same class | One method | Insert logic around
method | Low | Rename + wrap
method | +| Wrap Class | Wrapper | Multiple methods | Add behavior around
legacy class | Med | New wrapper
created | # Summary diff --git a/legacy-code/06-kata-sprouting-wrapping.md b/legacy-code/06-kata-sprouting-wrapping.md index c987d2b..a11381e 100644 --- a/legacy-code/06-kata-sprouting-wrapping.md +++ b/legacy-code/06-kata-sprouting-wrapping.md @@ -36,15 +36,15 @@ class UserManager: # Tasks 1. **Sprouting (20 min)** - - Add a new authentication method that uses a user database or config file - - Do not modify the original method + - Add new authentication logic in a separate method that uses a user database or config file + - Make only the minimal change to the original method needed to call the new method 2. **Wrapping (20 min)** - Create a wrapper that logs authentication attempts - Ensure the wrapper can be tested independently 3. **Testing (30 min)** - - Write tests for both the new and legacy authentication methods + - Write tests for both the new method and the original authentication entry point - Validate that wrapping does not change legacy behavior 4. **Review (20 min)** From 7b3d53dca3d63fd7baa1ac90fcf33b4850508bd3 Mon Sep 17 00:00:00 2001 From: Yury Bayda Date: Sat, 15 Aug 2026 23:02:44 -0700 Subject: [PATCH 2/2] build: give pandoc the index page title as metadata The template hardcoded the title element, so pandoc saw no title metadata and warned on every build while defaulting to the source filename. Pass the title as metadata and read it in the template. --- Makefile | 3 ++- index.template.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 34ca764..296467e 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,8 @@ MARKDOWNS := $(shell find . -mindepth 2 -name '*.md' \ -not -path './node_modules/*' -not -path './$(OUTDIR)/*' | sed 's|^\./||' | sort) PDFS := $(patsubst %.md,$(OUTDIR)/%.pdf,$(MARKDOWNS)) MDFLAGS := -f markdown -t beamer -s -H include.tex -V aspectratio:169 -V urlcolor:red -HTMLFLAGS := -f markdown -t html5 -s --template index.template.html --lua-filter index.lua +HTMLFLAGS := -f markdown -t html5 -s --template index.template.html --lua-filter index.lua \ + --metadata title="Clean Code Slides" .PHONY: all check clean format format-check lint diff --git a/index.template.html b/index.template.html index 2d1be2d..f8c0a5b 100644 --- a/index.template.html +++ b/index.template.html @@ -5,7 +5,7 @@ - Clean Code Slides + $pagetitle$