- Password Validator kata with starter code and tests - Shopping Cart kata with starter code and tests - FizzBuzz reference code (from live demo) - Setup guide and TDD reference card - No solutions included (participants implement themselves)
62 lines
1.9 KiB
Markdown
62 lines
1.9 KiB
Markdown
# Feature B — Shopping Cart
|
||
|
||
## Your goal
|
||
|
||
Implement `ShoppingCart` using strict TDD. **Do not write any production code before you have a failing test.**
|
||
|
||
## Domain rules to implement (in order)
|
||
|
||
| Step | Feature | Notes |
|
||
|------|---------|-------|
|
||
| 1 | Empty cart has subtotal 0 and count 0 | The baseline |
|
||
| 2 | Add items — subtotal = price × quantity | Multiple items accumulate |
|
||
| 3 | Remove item by name | Removing unknown name does nothing |
|
||
| 4 | Apply % discount to subtotal | 10% off $50 → $45 |
|
||
| 5 | CartItem rejects zero/negative price & quantity | Value Object validation |
|
||
| 6 | Bonus: duplicate name / float precision | Design decision — your call |
|
||
|
||
## The rhythm — repeat for every rule
|
||
|
||
```
|
||
1. Uncomment the next test → run → watch it FAIL (Red)
|
||
2. Write the minimum code to make it pass → run → GREEN
|
||
3. Refactor if needed → run → still GREEN
|
||
4. Move to the next test
|
||
```
|
||
|
||
## Running the tests
|
||
|
||
```bash
|
||
dart pub get
|
||
dart test
|
||
```
|
||
|
||
## Files
|
||
|
||
- `lib/shopping_cart.dart` — your implementation goes here
|
||
- `test/shopping_cart_test.dart` — uncomment tests one at a time
|
||
|
||
## Design hints (don't peek until you're stuck!)
|
||
|
||
<details>
|
||
<summary>Hint for Step 3 — Remove by name</summary>
|
||
|
||
When you need to remove by name, a `List<CartItem>` forces you to search by name.
|
||
A `Map<String, CartItem>` makes lookup O(1) and removal trivial.
|
||
Let the test drive you toward the right data structure.
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Hint for Step 5 — Value Object</summary>
|
||
|
||
Validation belongs in `CartItem`'s constructor, not in `ShoppingCart.addItem()`.
|
||
If the item can't be created, the cart never sees it.
|
||
This is the Value Object pattern: invalid state is unrepresentable.
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Hint for the float precision bonus test</summary>
|
||
|
||
Use `closeTo(expected, delta)` instead of `equals()` for floating point comparisons.
|
||
Example: `expect(result, closeTo(0.30, 0.001))`
|
||
</details>
|