Initial commit: Complete TDD workshop materials

- Workshop documentation (WORKSHOP_PLAN, FACILITATOR_GUIDE, etc.)
- FizzBuzz kata with demo script (git history to be recreated)
- Password Validator kata with demo script and solution
- Shopping Cart kata with demo script and solution
- Setup guide and TDD reference card for participants
This commit is contained in:
fiatcode 2026-03-10 15:32:21 +07:00
commit c3355063f2
26 changed files with 4725 additions and 0 deletions

161
FACILITATOR_GUIDE.md Normal file
View file

@ -0,0 +1,161 @@
# Workshop Facilitator Guide — Quick Reference
**Duration:** 2 hours
**Format:** Live demo + hands-on practice with Password Validator or Shopping Cart katas
> **Note:** For the complete detailed plan with minute-by-minute timing, scripts, and checklists, see **WORKSHOP_PLAN.md**. This guide focuses on facilitation tips and kata-specific insights.
---
## Essential Documents
Before the workshop, familiarize yourself with:
- **WORKSHOP_PLAN.md** — Complete schedule, scripts, and preparation checklist
- **fizzbuzz/DEMO_SCRIPT.md** — Step-by-step live demo walkthrough
- **TDD_REFERENCE_CARD.md** — Participant handout
- **SETUP_GUIDE.md** — For helping participants with technical issues
---
## Quick Preparation Checklist
### 1 Week Before
- [ ] Send SETUP_GUIDE.md to participants
- [ ] Confirm everyone completes setup and verifies `dart test` works
- [ ] Practice FizzBuzz live demo using DEMO_SCRIPT.md
### Day Of
- [ ] Arrive 15 minutes early
- [ ] Test projector/screen sharing
- [ ] Open fizzbuzz kata with git log ready
- [ ] Have solution files ready (but don't share early!)
- [ ] Write schedule on whiteboard
---
## Updated Session Structure
| Time | Activity | See |
|------|----------|-----|
| 0:00-0:10 | Welcome & Setup Check | WORKSHOP_PLAN.md |
| 0:10-0:25 | **Live Demo: FizzBuzz TDD** | fizzbuzz/DEMO_SCRIPT.md |
| 0:25-0:30 | Exercise Introduction | Section below |
| 0:30-1:15 | Hands-on Practice (Part 1) | Circulate & nudge |
| 1:15-1:30 | Mid-Point Check-in | WORKSHOP_PLAN.md |
| 1:30-2:00 | Hands-on Practice (Part 2) | Circulate & nudge |
| 2:00-2:10 | Show & Tell | 2-3 volunteers |
| 2:10-2:20 | Retrospective | WORKSHOP_PLAN.md |
---
## Live Demo: FizzBuzz (NEW SECTION)
**Purpose:** Show RED-GREEN-REFACTOR cycle in real-time
### Setup
1. Open `fizzbuzz/` directory
2. Have `fizzbuzz/DEMO_SCRIPT.md` open on second screen
3. Terminal ready with `dart test`
4. Reset git to initial commit: `git reset --hard <first-commit-hash>`
### Key Points to Emphasize
- **Run tests frequently** (every 30 seconds)
- **Minimal implementations** (hardcode "1" for first test)
- **Test-driven design** (algorithm emerges from tests)
- **Order matters** (check 15 before 3 and 5)
### Timing
- 0-2 min: Introduce FizzBuzz rules
- 2-4 min: Cycle 1 (input 1 → "1")
- 4-6 min: Cycle 2 (input 2 → "2")
- 6-9 min: Cycle 3 (input 3 → "Fizz")
- 9-11 min: Cycle 4 (input 5 → "Buzz")
- 11-14 min: Cycle 5 (input 15 → "FizzBuzz")
- 14-15 min: Wrap up, show git log
**See fizzbuzz/DEMO_SCRIPT.md for complete talking points and what to code at each step.**
---
## What to watch for while circulating
**Good signs:**
- Running `dart test` after every small change
- Seeing RED before touching `lib/`
- Short, focused commits (or at least talking through each step)
**Gentle interventions:**
- *"Have you run the test yet? What did it say?"* — nudge anyone writing too much code before testing
- *"Can you make it pass with even less code?"* — push toward minimal Green
- *"Now that it's Green, what could you clean up?"* — prompt the Refactor step
---
## Feature A: Password Validator — facilitator notes
**Likely first implementation** (all rules as if-blocks):
```dart
ValidationResult validate(String password) {
final errors = <String>[];
if (password.length < 8) errors.add('Must be at least 8 characters long');
if (!password.contains(RegExp(r'[A-Z]'))) errors.add('Must contain at least one uppercase letter');
// ... etc
return ValidationResult(isValid: errors.isEmpty, errors: errors);
}
```
**The refactor insight to guide toward (Step 6):**
Each rule is just a function `String? Function(String)`. They can live in a list.
Adding a new rule = adding one function. No touching existing code.
This is the Open-Closed Principle — same insight as Gilded Rose's Strategy pattern.
**Talking point:** *"If you had 20 rules, how readable would 20 if-blocks be? What would you do?"*
---
## Feature B: Shopping Cart — facilitator notes
**Likely first implementation** (List-based):
```dart
final List<CartItem> _items = [];
double subtotal() => _items.fold(0, (s, i) => s + i.price * i.quantity);
```
**The Map insight (Step 3 — remove by name):**
When participants try to implement `removeItem(name)` with a List, they'll write a `.removeWhere()`.
This works, but nudge them: *"What data structure makes 'find by name' really natural?"*
Let the remove-by-name test drive them toward `Map<String, CartItem>`.
**CartItem validation (Step 5):**
Many will put validation in `addItem()`. Ask: *"What if someone creates a CartItem and passes it somewhere else? Who validates it then?"*
This conversation leads naturally to Value Objects.
**Bonus design question:**
The duplicate name test has no right answer. Both "replace" and "accumulate" are valid.
The point is: TDD forces you to decide, and the test documents the decision permanently.
---
## Closing discussion questions
1. *"What was the first test you wrote? Why that one?"*
2. *"Did your design change as you added more tests? How?"*
3. *"Did you ever feel tempted to skip the Red step and just write the code?"*
4. *"What would have been different if you'd designed the class first, then written tests?"*
---
## Common questions and answers
**"Can I write all the tests first, then implement?"**
Not quite — TDD is one test at a time. Write one, watch it fail, make it pass, then the next.
Writing all tests upfront is a different practice (it's fine, but it's not TDD).
**"What if I don't know what test to write next?"**
Ask: *"What's the simplest behavior this thing should have that it doesn't have yet?"*
Start with the empty/zero case. Then one item. Then two. Then edge cases.
**"Is this realistic? Do people actually do this for real code?"**
Yes — especially for domain logic (pricing, validation, calculations).
It's less common for framework glue code, and that's okay. Apply it where behavior matters most.