CS Fundamentals intermediate 12 min

Prove a Conditional Before Shipping It

Generate a truth table to catch a conditional that is correct in prose but wrong in code.

Scenario

A feature should show only when the user is active and either owns the record or has admin access. The pull request contains active && owner || admin — compact, plausible, and wrong in a way that only shows up for inactive admins. In JavaScript and most C-family languages && binds tighter than ||, so this parses as (active && owner) || admin, which lets an inactive admin through. Operator precedence bugs survive code review because everyone reads the intent, not the parse.

Broken input

active && owner || admin

Goal

Use Truth Table Generator to enumerate every boolean combination before approving the condition. Eight rows take seconds to read; a production incident about an inactive admin seeing the feature takes considerably longer.

Tool sequence

  1. Open Truth Table Generator.
  2. Enter active && owner || admin exactly as written in the PR — the generator applies real operator precedence, which is the thing under test.
  3. Scan the rows where the result is true and look for active = false combinations.
  4. The row active=F, owner=F, admin=T → true is the bug: admin bypasses the active check.
  5. Enter the corrected active && (owner || admin) and confirm every true row now has active = T, then paste both tables into the PR review.

Checkpoint output

active owner admin | active && owner || admin | active && (owner || admin)
  F      F     T   |          true  ← bug     |          false
  T      F     T   |          true            |          true
  T      T     F   |          true            |          true

The unparenthesized expression is true for an inactive admin; the parenthesized version gates everything behind active as intended.

Common mistakes

  • Trusting natural-language intent ("active and owner or admin") instead of checking how &&/|| precedence actually parses it.
  • Testing only the happy path and one failure path — the bug lives in row 2 of 8, not row 1 or 8.
  • Changing parentheses without re-generating the full table to confirm nothing else flipped.
  • Assuming the linter would catch it — most linters only warn on mixed &&/|| without parentheses if that rule is enabled.

Related tools and lessons