8.9 KiB
Test Catalog — All 47 Tests
Every test in test/test_circuit/test/ enumerated: the circuit under test, what physics it validates, and the numerical expectation.
Baseline — hand-rolled MNA solver (25 tests)
passive.test.js — 11 tests
Tests the linear DC solver on textbook passives.
| # | Test | Circuit | Expected | Tolerance |
|---|---|---|---|---|
| 1 | Voltage divider | 9V → 1k + 2k | V(out) = 6.0 V | 3 decimals |
| 2 | Equal-R divider | 5V → 1k + 1k | V(b) = 2.5 V | 3 decimals |
| 3 | Ohm's law | 5V, 220Ω | I = 22.7 mA | 5 decimals |
| 4 | Three 3kΩ parallel | series with 1k | V(p) = 1.5 V | 3 decimals |
| 5 | Current source + R | 1 mA into 2.2kΩ | V = 2.2 V | 3 decimals |
| 6 | Pot wiper at 50% | 10k pot, 5V | V = 2.5 V | 2 decimals |
| 7 | Pot sweep 0→1 | 5 steps | monotonic increase | ≥ −10 mV slack |
| 8 | NTC resistance @ 25°C | β=3950 | R = 10 000 Ω | within 1 Ω |
| 9 | NTC temperature monotonicity | T ∈ {0, 25, 50} | R(0) > R(25) > R(50) | textbook ranges |
| 10 | NTC + 10k divider | T ∈ {0, 25, 50} | V_A0 matches expected per table | per-point tolerance |
| 11 | Switch open/closed | 5V → 1k → switch → GND | open: 4.9–5.0 V, closed: < 50 mV |
transient_rc.test.js — 3 tests
| # | Test | Circuit | Expected | Tolerance |
|---|---|---|---|---|
| 1 | RC charging @ τ | 10k, 100µF, 5V | V(τ) ≈ 3.16 V | ±5% |
| 2 | 5τ settling | 1k, 1µF, 3.3V | V(5τ) > 99% V | hard bound |
| 3 | Capacitor discharge | pre-charged 5V → 10k | V(τ) in [1.5, 2.2] V | manual bounds |
diodes.test.js — 7 tests
| # | Test | Circuit | Expected |
|---|---|---|---|
| 1 | Forward diode + 1k + 5V | Shockley default | V_d ∈ [0.55, 0.75] V, I ∈ [4, 5] mA |
| 2 | Reverse diode | diode blocks | V_a < 10 mV |
| 3 | Red LED + 220Ω + 5V | V_f ∈ [1.8, 2.3] V, I ∈ [10, 16] mA, brightness > 0.5 | |
| 4 | Blue LED higher Vf than red | V_blue > V_red, V_blue ∈ [2.8, 3.6] V | |
| 5 | LED brightness with supply | V ∈ {2.0, 3.0, 5.0} | monotonic, dim at 2V, bright at 5V |
| 6 | BJT switch ON | V_b = 5V, R_b = 10k | V_CE < 0.8 V |
| 7 | BJT switch OFF | V_b = 0 | V_CE > 4.9 V |
avr_blink.test.js — 2 tests
Uses the real fixtures/blink.hex (copied from Velxio's test fixtures).
| # | Test | What it validates |
|---|---|---|
| 1 | Toggles pin 13 | After 2 s of AVR time, observed ≥ 3 edge transitions on D13; both 0 and 1 states visible |
| 2 | Drives simulated LED | Pin-13 voltage fed into a VoltageSource, 220 Ω + red LED; LED brightness switches between < 1% and > 50% |
e2e_pot_pwm_led.test.js — 1 test
Uses potToPwmProgram() (hand-assembled: reads A0, writes to OCR0A for PWM on D6).
Circuit: +5V → pot (10k) → A0 / GND plus D6 → 220Ω → red LED → GND.
Sweep wiper 0.0 → 0.25 → 0.50 → 0.75 → 1.00:
| Wiper | V_A0 | PWM duty | I_LED | Brightness |
|---|---|---|---|---|
| 0.00 | 0.000 V | 0.0 % | 0.00 mA | 0.000 |
| 0.25 | 1.250 V | 24.7 % | 0.00 mA | 0.000 |
| 0.50 | 2.500 V | 49.8 % | 3.26 mA | 0.163 |
| 0.75 | 3.750 V | 74.9 % | 8.77 mA | 0.439 |
| 1.00 | 5.000 V | 100.0 % | 14.38 mA | 0.719 |
Assertions: duty at 0% < 5%, duty at 100% > 90%, brightness monotonic, final > 0.5, initial < 0.05.
e2e_thermistor.test.js — 1 test
Uses adcReadProgram() + NTC + pullup divider.
Circuit: +5V → 10kΩ → A0 → NTC → GND.
Per temperature T ∈ {0, 15, 25, 35, 50} °C:
| T_set | V_A0 | ADC raw | R_ntc (true) | R_meas (recovered) | T_meas |
|---|---|---|---|---|---|
| 0 °C | 3.854 V | 789 | 33 621 Ω | 33 718 Ω | −0.05 °C |
| 15 °C | 3.065 V | 627 | 15 837 Ω | 15 833 Ω | 15.01 °C |
| 25 °C | 2.500 V | 511 | 10 000 Ω | 9 980 Ω | 25.04 °C |
| 35 °C | 1.971 V | 403 | 6 506 Ω | 6 500 Ω | 35.02 °C |
| 50 °C | 1.320 V | 270 | 3 588 Ω | 3 586 Ω | 50.02 °C |
Assertion: |T_meas − T_set| < 1 °C at every point. Achieved: < 0.05 °C.
ngspice — spice_*.test.js (22 tests)
ngspice_smoke.test.js — 1 test
The minimal possible smoke test.
| # | Test | Netlist | Expected |
|---|---|---|---|
| 1 | Boot + voltage divider | V 9 → R 1k → R 2k → GND, .op |
V(out) = 6.0 |
spice_passive.test.js — 3 tests
All run with .op:
| # | Circuit | Expected |
|---|---|---|
| 1 | 9V → 1k + 2k | V(out) = 6 V |
| 2 | Three 3kΩ parallel + 1k series from 3V | V(p) = 1.5 V |
| 3 | 1 mA current source into 2.2kΩ | V(a) = 2.2 V |
spice_transient.test.js — 2 tests
| # | Test | .tran |
Expected |
|---|---|---|---|
| 1 | RC charging | 10m 3 | V(τ) ≈ 3.16 V, V(5τ) > 90% |
| 2 | RLC underdamped oscillation | 10u 30m, R=1Ω, L=10mH, C=10µF | zero-crossings imply f ≈ 503 Hz, ±15 % |
spice_ac.test.js — 2 tests
| # | Test | .ac |
Expected |
|---|---|---|---|
| 1 | RC low-pass Bode | 20 ppd, 10 Hz – 1 MHz | f₋₃dB ∈ [900, 1100] Hz; low-freq gain ≈ 0 dB; −20 dB/decade rolloff; phase @ cutoff ≈ −45° |
| 2 | Parallel-tank RLC bandpass | 30 ppd, 10 Hz – 1 MHz | peak near 5033 Hz (±20%), passive so max gain ≈ 0 dB; 10×f₀ rejection > 15 dB below peak |
spice_active.test.js — 6 tests
| # | Test | Analysis | Expected |
|---|---|---|---|
| 1 | Diode forward (1N4148 model) | .op |
V_a ∈ [0.55, 0.80] V |
| 2 | Bridge rectifier (4 diodes + sine 6V/50Hz) | .tran 0.1m 40m |
peak output 4.2–5.4 V, always positive |
| 3 | Common-emitter amp (2N2222, 12V, ~1kHz input, bypassed R_E) | .tran 10u 6m |
voltage gain > 30 |
| 4 | N-MOS Level-1 switch, V_gate=5V | .op |
V(drain) < 1.0 V |
| 5 | N-MOS Level-1 off, V_gate=0 | .op |
V(drain) > 4.9 V |
| 6 | Op-amp inverting amp (E-source, R_in=1k, R_f=10k) | .op |
V(out) ≈ −2.0 V |
spice_digital.test.js — 4 tests
All gates implemented with B-sources using u() step function.
| # | Gate | Rows tested |
|---|---|---|
| 1 | AND | 4 (truth table) |
| 2 | NAND | 4 |
| 3 | XOR | 4 |
| 4 | AND → RC low-pass | .tran 10u 20m — verifies filter ripple < 1.5 V, raw AND swings 0–5 V, filtered mean in (0, 5) |
spice_555_astable.test.js — 1 test
RC relaxation oscillator built from a Schmitt-switch (S-element with hysteresis).
- R = 10 kΩ, C = 10 nF
SMOD: Vt=2.5, Vh=0.833, Ron=100, Roff=1G.tran 0.5u 2m
Expected: output toggles, ≥ 3 rising edges detected in the steady-state window; measured frequency between 500 Hz and 50 kHz (wide range because behavioral model differs from ideal 555 math).
Typical measured: ~7 kHz.
spice_avr_mixed.test.js — 3 tests
The flagship mixed-signal demonstrator.
Test 1 — NTC → ngspice → ADC → sketch
For each T ∈ {0, 25, 50} °C:
- ngspice
.opsolves10k pullup + R_ntc(T) avr.setAnalogVoltage(0, V(a0))avr.runCycles(500_000)runsadcReadProgram()- Read
ADCH/ADCLregisters directly → reconstruct 10-bit result
Expected results match textbook within ±5 LSB:
| T | V(a0) from ngspice | ADC raw from avr8js |
|---|---|---|
| 0 °C | 3.854 V | 789 |
| 25 °C | 2.500 V | 512 |
| 50 °C | 1.320 V | 270 |
Test 2 — Sketch → PWM → ngspice RC → filtered DC
For V_A0 ∈ {1.0, 2.5, 4.0} V:
- Run
potToPwmProgram()with the given analog voltage - Read PWM duty (must match
V_A0 / 5± 0.05) - Feed
duty × 5as DC source intoR=10k, R_load=10MΩin ngspice .opgives filtered DC output — should match duty × 5 within 0.1 V
Measured:
| V_A0 | duty | V_filt | expected |
|---|---|---|---|
| 1.0 V | 20.0 % | 0.999 V | 1.00 V |
| 2.5 V | 50.2 % | 2.507 V | 2.51 V |
| 4.0 V | 80.0 % | 3.996 V | 4.00 V |
Test 3 — Co-simulation loop (AVRSpiceBridge)
The bridge runs the AVR in 1 ms slices, re-solving ngspice between each. Pot wiper is moved mid-test.
- wiper = 0.25 → 5 slices run → expected ADC ≈ 256 (0.25 × 1023). Measured: 256. Tolerance ±20 LSB.
- wiper moves to 0.75 → 5 more slices → expected ADC ≈ 767. Measured: 768.
Demonstrates that ngspice + avr8js can be cleanly co-simulated quasi-statically.
Pass/fail history
All 47 tests passed as of 2026-04-15. Running npm test from test/test_circuit/ is the canonical verification. Expected wall-clock: ~5 seconds on an i7.
Full command output:
✓ test/ngspice_smoke.test.js (1 test) 372ms
✓ test/spice_passive.test.js (3 tests) 358ms
✓ test/spice_transient.test.js (2 tests) 629ms
✓ test/spice_ac.test.js (2 tests) 340ms
✓ test/spice_active.test.js (6 tests) 600ms
✓ test/spice_digital.test.js (4 tests) 420ms
✓ test/spice_555_astable.test.js (1 test) 609ms
✓ test/spice_avr_mixed.test.js (3 tests) 800ms
✓ test/passive.test.js (11 tests) 8ms
✓ test/transient_rc.test.js (3 tests) 22ms
✓ test/diodes.test.js (7 tests) 15ms
✓ test/avr_blink.test.js (2 tests) 2400ms
✓ test/e2e_pot_pwm_led.test.js (1 test) 90ms
✓ test/e2e_thermistor.test.js (1 test) 121ms
Test Files 14 passed (14)
Tests 47 passed (47)
Duration ~5 s