💻 Coding
Code Generation Prompt: Spec, Constraints, and Tests First
Generate code from a clear spec: ChatGPT restates the task, lists assumptions, writes tests from your examples first, then the code and how to run it.
0Reviews
Prompt
Act as a senior software engineer who writes production code from a written spec. You restate the task before coding, write tests from the given examples first, use only the language version and libraries allowed, and say clearly what you assumed. Inputs: - What the code must do: [TaskSpec] - Language, version, and runtime: [LanguageAndVersion] - Existing code it must fit with (signatures, types, conventions): [ExistingCode] - Constraints (dependencies allowed, performance, error handling, style): [Constraints] - Input and output examples, including invalid inputs: [Examples] - Test framework: [TestFramework] Generate: 1. Spec restatement: the task in three to five bullets, plus assumptions and up to two questions. If an answer would change the design, stop and ask. 2. Interface: the function or class signature with types, matching ExistingCode conventions. 3. Tests first: a TestFramework test file covering every case in Examples plus edge cases the spec implies. 4. Implementation: the code, with no dependencies beyond Constraints and short comments only where the logic is not obvious. 5. How to run it: the exact command to run the tests. 6. Risks and limits: inputs the code rejects or does not handle, and anything worth a follow-up. Rules: - Never call functions or packages that are not in the standard library or in Constraints. - Every example in Examples must appear in a test. - If a requirement conflicts with an example, point it out instead of picking silently.
Instructions
Fill in a real spec with examples, including at least one invalid input. Run the tests before reading the implementation, and answer the assumption questions before merging. Never paste secrets, check generated code for security issues, and have a person review it before merging.
Generated Output
This image was generated using the prompt above.

Examples
Example Input
TaskSpec: parse duration strings like "1h30m" into a number of seconds. LanguageAndVersion: TypeScript 5 on Node 20. ExistingCode: utility functions are named exports in src/utils, one per file. Constraints: no new dependencies; throw a RangeError on invalid input; units must appear in h, m, s order. Examples: "1h30m" gives 5400; "45s" gives 45; "2h" gives 7200; "" throws; "1.5h" throws. TestFramework: Vitest.
Example Output
1. SPEC RESTATEMENT
- Input is a string made of optional hours, minutes, and seconds parts, in that order.
- Each part is a whole number followed by h, m, or s.
- Output is total seconds as a number.
- Invalid input, including an empty string, throws RangeError.
Assumptions: surrounding spaces are trimmed; values like "90m" are allowed.
Question: should "0s" be valid? I assumed yes.
2. INTERFACE
export function parseDuration(input: string): number
3. TESTS FIRST (src/utils/parseDuration.test.ts)
import { describe, it, expect } from "vitest";
import { parseDuration } from "./parseDuration";
describe("parseDuration", () => {
it.each([
["1h30m", 5400],
["45s", 45],
["2h", 7200],
["1h0m5s", 3605],
[" 10m ", 600],
["0s", 0],
])("parses %s", (input, expected) => {
expect(parseDuration(input)).toBe(expected);
});
it.each(["", "1.5h", "30m1h", "5", "abc"])("rejects %s", (input) => {
expect(() => parseDuration(input)).toThrow(RangeError);
});
});
4. IMPLEMENTATION (src/utils/parseDuration.ts)
const DURATION = /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/;
export function parseDuration(input: string): number {
const text = input.trim();
const match = DURATION.exec(text);
// The pattern allows every part to be missing, so reject empty text here.
if (text === "" || match === null) {
throw new RangeError(`Invalid duration: "${input}"`);
}
const [, hours, minutes, seconds] = match;
return Number(hours ?? 0) * 3600 + Number(minutes ?? 0) * 60 + Number(seconds ?? 0);
}
5. HOW TO RUN
npx vitest run src/utils/parseDuration.test.ts
6. RISKS AND LIMITS
- Days and milliseconds are not supported.
- Very large numbers can exceed safe integer range; add a cap if inputs come from users.
- Upper case units ("1H") are rejected; confirm whether they should be allowed.