Shopping Cart

Level: Intermediate 30–60 min

Concepts: StateBusiness Rules

Solutions: C# | TypeScript | Python


Implement a shopping cart system that handles products, quantities, pricing, and various types of discounts. The system should be able to calculate totals, apply discounts, and handle special cases like bulk pricing and promotional offers.

Requirements

  1. Add and remove items from the cart
  2. Update quantities of items
  3. Calculate subtotal for each item
  4. Calculate total for the entire cart
  5. Apply different types of discounts:
    • Percentage-based discounts
    • Fixed amount discounts
    • Buy X get Y free offers
    • Bulk pricing (e.g., buy 3 or more for a special price)
  6. Handle special cases:
    • Items with limited stock
    • Items that can’t be combined with certain discounts
    • Maximum quantity limits per item

Hint

Start by implementing the basic cart operations (add, remove, update) and then gradually add the discount logic. Consider using the Strategy pattern for different types of discounts. Think about how to handle the order of discount application and how to validate that discounts are being applied correctly.

Bonus

  • Implement a loyalty points system
  • Add support for different currencies and exchange rates
  • Implement a tax calculation system
  • Add support for shipping costs and different shipping methods
  • Implement a coupon code system
  • Add support for saving carts and returning to them later

(Bonus features — loyalty, currency, tax, shipping, coupons, saved carts — are deliberately out of scope for the reference implementations below. They would each warrant their own collaborator or aggregate; the reference focuses on the core Cart + LineItem + DiscountPolicy vocabulary.)

Reference Walkthrough

This kata ships as a Mode F (Agent Full-Bake) reference: one commit per language, with a design-rationale walkthrough explaining why the domain came out the shape it did (Money and Quantity as value types, DiscountPolicy as a strategy hierarchy, ProductBuilder and CartBuilder for scenario setup).

All three implementations satisfy the same eighteen scenarios in SCENARIOS.md.


  • TDD Already Does BDD, Without the Gherkin
    BDD wasn't a discovery. It was a rebrand of what disciplined TDD was already doing. Test data builders, factory hierarchies, and mock-driven collaboration tests are the scenarios, and they evolve alongside the code instead of rotting beside it.
  • The Test Pyramid Was an Economic Argument
    The test pyramid was not a quality law. It was a cost structure: unit tests were cheap, integration tests were expensive, so you wrote many of the first and few of the second. Agents collapsed the cost of writing tests at every level, and the cheapest test that still tells the truth is the one that pins a seam the agent cannot fake.
  • 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.