Click any file in the tree, or any file::symbol reference in the cross-cutting box below, to navigate between source code and its shadow.
def calculate_total(items, coupon_code=None):
subtotal = sum(item["price"] * item["qty"] for item in items)
if coupon_code:
coupon = get_coupon(coupon_code) # no .upper()
if coupon and subtotal >= coupon["min_total"]:
subtotal -= subtotal * coupon["discount"]
...
from cart import get_coupon
def validate_coupon(code):
"""Check if a coupon code is valid."""
coupon = get_coupon(code.upper()) # normalizes!
return coupon is not None
def test_coupon():
items = [{"name": "Widget", "price": 25.00, "qty": 3}]
total = calculate_total(items, coupon_code="SAVE20")
assert total == 64.80
# only tests uppercase "SAVE20" — never catches the bug
## `calculate_total`
- Does NOT normalize `coupon_code` to uppercase before
lookup. Lowercase codes silently produce no discount.
This contradicts `validate_coupon` which DOES normalize.
_(verified, source: exploration, labels: [bug])_
Also involves: `inventory.py::validate_coupon`
## `validate_coupon`
- Normalizes `code` to uppercase via `.upper()` before
lookup, but `calculate_total` does NOT — a code that
validates successfully may still produce no discount.
_(verified, source: exploration, labels: [bug])_
Also involves: `cart.py::calculate_total`
## `test_coupon`
- Verifies SAVE20 on 75.00 subtotal: 75.00 − 20% = 60.00
+ 4.80 tax = 64.80. _(verified)_
- Only tests with uppercase coupon code `"SAVE20"`. Does not
test lowercase, so does NOT catch the case-normalization bug.
_(verified, source: exploration)_
Also involves: `cart.py::calculate_total`
# Coupon case normalization mismatch
**Category**: edge-case
**Refs**:
- `inventory.py::validate_coupon`↗ click to jump
- `cart.py::calculate_total`↗ click to jump
- `cart.py::load_coupon`↗ click to jump
**Discovery**: `validate_coupon` normalizes codes to uppercase via `.upper()`,
but `calculate_total` passes `coupon_code` through without normalization. A user
who validates `"save20"` (returns True) and then calls `calculate_total("save20")`
gets no discount — the coupon silently fails because `load_coupon`'s keys are uppercase. _(verified, source: exploration, labels: [bug])_
Real files from examples/coupon-demo/. Every source file pairs with a sibling
shadow markdown; _cross/ discoveries anchor to many symbols across files
via file::symbol.