When does this default overwrite a valid zero?
Trace a one-line AI draft. Separate a missing value from a valid zero.
The question
Patchwell is a fictional team that builds scheduling software. This is an authored practice case. A draft adds a default for the number of reminders. Users may choose zero to disable reminders.
Missing or null reminders means 3. An integer from 0 through 5 is valid. Negative, fractional, or larger values must be rejected.
const reminders = request.reminders || 3;
| Input | Expected | |
|---|---|---|
| Ordinary choice | 2 | 2 |
| Missing choice | undefined | 3 |
Authored example. Values are supplied for this case.
“Would you approve the draft? Show a failing input, a narrow repair, and the tests you need.”
Not saved by this site. Your browser may restore text when you navigate back.
A strong answer, step by step
Open each step in turn. This is one strong answer, not the only one.
Step 1: Trace a valid zero
What would you do here? Open the move you’d make.
Ask AI whether the code looks correct
Tempting, but it misses something. A second opinion does not establish the behavior.
Trace the input 0
The strong move. It is valid under the stated contract and disproves the draft.
See how a strong candidate says it
“For reminders = 0, JavaScript treats 0 as false. The expression returns 3, so someone who disabled reminders gets three. The missing-value test cannot catch that.”
Why it works: A concrete trace establishes a user-visible failure.
Step 2: Separate defaulting from validation
What would you do here? Open the move you’d make.
Default nullish values and validate the range
The strong move. This preserves zero and rejects invalid input.
Replace || with ?? and stop
Tempting, but it misses something. The range and type requirements remain unchecked.
See how a strong candidate says it
“I would use request.reminders ?? 3 for the missing-or-null default, then validate that the value is an integer between 0 and 5. Nullish defaulting alone would still accept -1 or a string.”
Why it works: A fix must preserve both parts of the contract.
Step 3: Choose discriminating tests
What would you do here? Open the move you’d make.
Add five more tests with the input 2
Tempting, but it misses something. Repeated happy paths do not cover the defect.
Add zero plus rejection tests
The strong move. The tests distinguish the defect from separate validation gaps.
See how a strong candidate says it
“I would test 0, null, missing, 5, 6, -1, 1.5, and the string "0". The zero case fails before the change; invalid values must exercise the rejection path.”
Why it works: Each selected input tests a different contract boundary.
Step 4: Explain the review decision
What would you do here? Open the move you’d make.
Block with a repro and a narrow request
The strong move. The author can act on the evidence.
Approve because the suite passes
Tempting, but it misses something. The suite omits a valid value.
See how a strong candidate says it
“I would block this change on the zero defect. I would request the narrow defaulting and validation repair, with a regression test. I would not rewrite the notification scheduler in this review.”
Why it works: It states severity and keeps the repair bounded.
The answer, in short
- Decision
- Request a small repair before approval.
- Because
- A valid zero is overwritten, and invalid inputs are not rejected.
- What would change it
- A different documented contract for zero would change the expected output.
Common traps
- Calling every falsy value “missing”.
- Treating ?? as input validation.
Check your answer
- Did you trace 0 to the returned value?
- Did you distinguish defaulting from validation?
- Did you choose a test that fails before the repair?
- Did you state the smallest change and approval decision?
Last reviewed Nov 10, 2026