Free code template
Unit-test starter
A function with a test file: the happy path, the edges and the errors, grouped and named clearly.
It opens with this template loaded and runs in your browser. You don't need an account to use it; a free account saves your work and exports it.
The job it does
When you add tests to code that has none, or want a pattern for a team's first tests. It comes with its own checks, so after you change it you can see at a glance that it still does the job.
What's inside
This is the template exactly as the Code Lab opens it, read-only. Open it to run it, change it and export it.
- 2 files
- Runs from price.js
- JavaScript
A pattern for a first test file: one test per behaviour, named so a failure explains itself, in the order happy path → edges → errors. The function under test, formatPrice, shows prices in the app.
Replace price.js with your own function and write one test per thing it must do. Run (Ctrl+Enter) after each one.
- All my tests pass
- formatPrice(100000, "BDT") returns "৳1,000.00"
- No uncaught errors
// The function under test: how the app shows a price.
// Cents in, text out; negative amounts are refunds; unknown currencies are a bug in the caller.
const SYMBOLS = { USD: '$', EUR: '€', BDT: '৳', NGN: '₦' };
export function formatPrice(cents, currency = 'USD') {
if (!Number.isInteger(cents)) throw new Error('cents must be a whole number');
const symbol = SYMBOLS[currency];
if (!symbol) throw new Error(`unknown currency ${currency}`);
const sign = cents < 0 ? '-' : '';
const abs = Math.abs(cents);
const whole = String(Math.floor(abs / 100)).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return `${sign}${symbol}${whole}.${String(abs % 100).padStart(2, '0')}`;
}
import { formatPrice } from './price';
// One test per behaviour, named so a failure explains itself.
// Happy path first, then the edges, then the errors.
test('formatPrice › shows dollars and cents', () => {
expect(formatPrice(1250)).toBe('$12.50');
});
test('formatPrice › uses the currency symbol', () => {
expect(formatPrice(99, 'EUR')).toBe('€0.99');
});
test('formatPrice (edge) › zero is $0.00', () => {
expect(formatPrice(0)).toBe('$0.00');
});
test('formatPrice (edge) › thousands get a separator', () => {
expect(formatPrice(123456789)).toBe('$1,234,567.89');
});
test('formatPrice (edge) › a refund keeps its minus sign before the symbol', () => {
expect(formatPrice(-305)).toBe('-$3.05');
});
test('formatPrice (error) › an unknown currency is refused', () => {
expect(() => formatPrice(100, 'XYZ')).toThrow('unknown currency');
});
test('formatPrice (error) › fractions of a cent are refused', () => {
expect(() => formatPrice(10.5)).toThrow('whole number');
});
The lesson behind it
Learn why it works, with a podcast and a quiz for each lesson.
More code templates
Utility script
A small script with its options at the top, input checks, a summary line and tests.
API client with retries
A fetch wrapper with a timeout, retries with growing waits, and errors that say what failed.
CSV cleaner
Read a CSV, trim and fix values, drop broken rows with a reason, and write clean CSV back.