Test-Driven Development writes tests before code. Red-Green-Refactor is the cycle: write a failing test, make it pass with the simplest code, then refactor. Today you will TDD a feature from scratch and read coverage reports.
// TDD: Write the test FIRST — it will fail (Red)
// src/cart.test.js
import { Cart } from './cart';
describe('Cart', () => {
let cart;
beforeEach(() => { cart = new Cart(); });
test('starts empty', () => {
expect(cart.items).toHaveLength(0);
expect(cart.total).toBe(0);
});
test('adds items', () => {
cart.add({ id: 1, name: 'Widget', price: 9.99 });
expect(cart.items).toHaveLength(1);
expect(cart.total).toBeCloseTo(9.99);
});
test('removes items', () => {
cart.add({ id: 1, name: 'Widget', price: 9.99 });
cart.remove(1);
expect(cart.items).toHaveLength(0);
});
test('applies discount', () => {
cart.add({ id: 1, name: 'Widget', price: 100 });
cart.applyDiscount(10); // 10%
expect(cart.total).toBeCloseTo(90);
});
});// Now write the minimum code to make tests pass (Green)
// src/cart.js
export class Cart {
constructor() { this._items = []; this._discount = 0; }
get items() { return [...this._items]; }
get total() {
const subtotal = this._items.reduce((s, i) => s + i.price, 0);
return subtotal * (1 - this._discount / 100);
}
add(item) { this._items.push(item); }
remove(id) { this._items = this._items.filter(i => i.id !== id); }
applyDiscount(pct) { this._discount = pct; }
}