Skip to content

Unit Test Results

261 total | 261 passed | 0 failed2026-04-22 11:42

By complexity

Level Count Description
smoke 13 no-crash / lifecycle only
format 37 string or schema format checks
behavioral 185 actual module behavior: output, state, counts
integration 28 multi-module pipeline or cross-device

See Testing standards for the full classification guide.

test_artnet.cpp

7/7 passedtest_artnet.cpp

  • smoke ArtNetOutModule - lifecycle without layer (should not crash)
  • behavioral ArtNetOutModule - sends packets when wired to a DriverLayer with pixels
  • behavioral ArtNetOutModule - multi-universe: 170 pixels use 1 universe, 171 use 2
  • behavioral ArtNetOutModule - packet header bytes are correct Art-Net OpDmx
  • smoke ArtNetInModule - lifecycle without layer (should not crash)
  • format ArtNetInModule - healthReport format
  • integration ArtNetOut loopback to ArtNetIn on 127.0.0.1

Brightness Modifier

8/8 passedtest_brightness_mod.cpp

  • behavioral BrightnessModifierModule - setup registers frequency control
  • behavioral BrightnessModifierModule - setControl updates live frequency
  • behavioral BrightnessModifierModule - loop() output scales with brightness from KvStore
  • behavioral BrightnessModifierModule - loop() uses KvStore default when key absent
  • behavioral DriverLayer - setInput source2 registers a second producer
  • behavioral DriverLayer - setInput source only still works (single source)
  • behavioral SineEffectModule - loop() publishes amplitude as KvStore 'brightness'
  • integration Phase 9 pipeline - SineEffectModule publishes brightness, BrightnessMod reads it

Controls and KV Store

26/26 passedtest_controls_and_kv.cpp

  • behavioral StatefulModule - addControl registers controls correctly
  • behavioral StatefulModule - clearControls resets count
  • behavioral StatefulModule - setControl float writes through to field
  • behavioral StatefulModule - setControl uint8 writes through to field
  • behavioral StatefulModule - setControl uint32 writes through to field
  • behavioral StatefulModule - setControl bool writes through to field
  • behavioral StatefulModule - setControl unknown key is a no-op
  • behavioral StatefulModule - setControl JsonVariant writes through to field
  • behavioral StatefulModule - onUpdate is called after setControl
  • behavioral StatefulModule - onUpdate is NOT called for unknown key
  • format StatefulModule - getSchema produces correct JSON structure
  • format StatefulModule - getSchema reflects current field value after setControl
  • format SineEffectModule - getSchema exposes frequency and amplitude
  • behavioral SineEffectModule - setControl updates live frequency
  • format PreviewModule - getSchema exposes logEveryN
  • behavioral KvStore - setFloat / getFloat round-trip
  • behavioral KvStore - setUint8 / getUint8 round-trip
  • behavioral KvStore - setBool / getBool round-trip
  • behavioral KvStore - getFloat returns default for unknown key
  • behavioral KvStore - getUint8 returns default for unknown key
  • behavioral KvStore - getBool returns default for unknown key
  • behavioral KvStore - getFloat returns default when key holds different type
  • behavioral KvStore - exists returns true for present key, false for absent
  • behavioral KvStore - setFloat updates an existing entry
  • behavioral KvStore - setFloat returns false when table is full
  • behavioral KvStore - clear removes all entries

Coord3D and Pixel Addressing

7/7 passedtest_coord3d.cpp

  • behavioral Coord3D - default construction is (0,0,0)
  • behavioral Coord3D - equality and inequality
  • behavioral coords_to_index - flat 2D grid (depth=1)
  • behavioral coords_to_index - 3D volume
  • behavioral index_to_coords - flat 2D grid (depth=1)
  • behavioral index_to_coords - 3D round-trip with coords_to_index
  • behavioral coords_to_index - matches EffectsLayer pixel layout

test_effects_2d.cpp

7/7 passedtest_effects_2d.cpp

  • behavioral GameOfLifeEffect - glider moves (+1,+1) after 4 generations
  • behavioral GameOfLifeEffect - extinction triggers re-seed
  • behavioral GameOfLifeEffect - renders non-zero pixels after loop
  • behavioral NoiseEffect2D - renders non-zero pixels
  • behavioral NoiseEffect2D - output varies with position (scale>0 produces spatial variation)
  • behavioral DistortionWaves2DEffect - renders non-zero pixels
  • behavioral DistortionWaves2DEffect - spatial variation across pixels

Health Checks

5/5 passedtest_health_checks.cpp

  • format SineEffectModule - healthReport format after one tick
  • format PreviewModule - healthReport format after one tick
  • behavioral Health check - SineEffectModule and Preview checksums match
  • behavioral Health check - zero-residue: PreviewModule state reset after teardown
  • format Scheduler - printHealthReports fires for participating modules

HTTP Server

18/18 passedtest_http_server.cpp

  • format SineEffectModule - getSchema includes category 'effect'
  • format BrightnessModifierModule - getSchema includes category 'modifier'
  • format EffectsLayer - getSchema includes category 'layer'
  • format DriverLayer - getSchema includes category 'layer'
  • behavioral SineEffectModule - setControl updates frequency live
  • behavioral SineEffectModule - setControl ignores unknown key
  • behavioral ModuleManager - getModulesJson emits id + name + category + controls
  • behavioral ModuleManager - setModuleControl returns true for valid id+key
  • behavioral ModuleManager - setModuleControl returns false for unknown module id
  • behavioral ModuleManager - setModuleControl returns false for unknown key
  • behavioral ModuleManager - flushIfDirty does not flush before debounce window
  • behavioral ModuleManager - getModulesJson reflects live value after setModuleControl
  • behavioral ModuleManager - flushIfDirty writes state file when debounce is 0
  • behavioral ModuleManager - addModule creates a root module at runtime
  • behavioral ModuleManager - addModule creates a child module with parent_id
  • behavioral ModuleManager - removeModule returns HasChildren when children exist
  • behavioral ModuleManager - removeModule returns NotFound for unknown id
  • behavioral ModuleManager - validateControls: all slider controls have valid min < max

REST and WebSocket Integration

13/13 passedtest_integration.cpp

  • integration integration/A: GET /api/modules returns 200 with a JSON array
  • integration integration/A: POST /api/control with valid id+key returns 200 ok:true
  • integration integration/A: POST /api/control with unknown module id returns 404
  • integration integration/A: POST /api/control with unknown key returns 404
  • integration integration/A: POST /api/control with malformed JSON returns 400
  • integration integration/A: GET /api/types returns array of known type names
  • integration integration/B: pixel snapshot header is stable across consecutive ticks
  • integration integration/B: pixel snapshot contains non-zero pixels after SineEffectModule runs
  • integration integration/B: GET /api/modules + pixel snapshot are consistent
  • integration integration/D: POST /api/control value appears in WS state within 600 ms
  • integration integration/E: first WS connection receives a valid state frame within 3 s
  • integration integration/E: WS state frame contains expected module ids
  • integration integration/D4: binary WS frame header byte and size match pixelSnapshot

Effect and Driver Layers

29/29 passedtest_layers.cpp

  • smoke EffectsLayer - zero residue after teardown
  • integration DriverLayer - zero sources produces all-black blend
  • integration DriverLayer - single producer passes through unchanged
  • integration DriverLayer - two producers blend to pixel-wise saturating add
  • smoke DriverLayer - zero residue after teardown
  • integration PreviewModule - reads blended output from DriverLayer
  • behavioral GridLayout - extent() returns configured dimensions
  • behavioral GridLayout - extent() via setProps
  • behavioral DriverLayer - props-only sizing (no Layout children, backward compat)
  • behavioral DriverLayer - GridLayout child overrides props size via onChildrenReady
  • behavioral DriverLayer - onChildrenReady called via addChild (addModule path)
  • behavioral EffectsLayer - onSizeChanged ignored when useDriverSize is false
  • behavioral EffectsLayer - full-extent driver sizing (start=0 end=1)
  • behavioral EffectsLayer - partial driver sizing via start/end props
  • behavioral EffectsLayer - resizes when driver resizes via onChildrenReady
  • behavioral EffectsLayer - EffectsLayer before DriverLayer setup ordering
  • behavioral GridLayout - saveState/loadState round-trips width/height/depth
  • integration DriverLayer - partial EffectsLayer (startX=0.5) does not OOB blend
  • behavioral EffectsLayer - saveState/loadState round-trips start/end fractions
  • behavioral EffectsLayer - onUpdate resizes buffer when start/end slider changes
  • behavioral GridLayout - requestMappings straight (identity for non-serpentine)
  • behavioral GridLayout - requestMappings serpentine reverses odd rows
  • behavioral EffectsLayer preferredCore returns 0
  • behavioral DriverLayer preferredCore returns 1
  • format DriverLayer healthReport contains expected fields
  • format DriverLayer healthReport reports source count
  • behavioral StatefulModule timing_ accumulates self loop() time
  • behavioral StatefulModule parent self-timing excludes child time
  • behavioral StatefulModule timing resets on runSetup

Logger

6/6 passedtest_logger.cpp

  • behavioral Logger - logLevelFromString parses all levels
  • behavioral Logger - logLevelFromString rejects unknown string
  • behavioral Logger - logLevelToString round-trips all levels
  • behavioral Logger - g_logLevel gate: LOG_SETUP suppressed below Setup level
  • behavioral Logger - WS push function receives stripped message
  • behavioral Logger - WS push not called when fn is null

Memory and Filesystem

3/3 passedtest_memory_stats.cpp

  • behavioral MemoryStats - filesystem stats are available
  • behavioral MemoryStats - memory sanity checks
  • behavioral MemoryStats - multiple snapshots are consistent

Module Manager

25/25 passedtest_module_manager.cpp

  • behavioral TypeRegistry - registered types are findable
  • behavioral TypeRegistry - create returns correct type
  • behavioral TypeRegistry - create returns nullptr for unknown type
  • behavioral EffectsLayer - setProps sets width and height
  • behavioral SineEffect - setProps and saveState/loadState round-trip
  • behavioral ModuleManager - loads config and registers all modules
  • integration ModuleManager - wires modules correctly (pipeline runs without crash)
  • behavioral ModuleManager - isPermanent returns true
  • behavioral ModuleManager - addModule happy path
  • behavioral ModuleManager - addModule duplicate id rejected
  • behavioral ModuleManager - addModule unknown type rejected
  • behavioral ModuleManager - removeModule happy path
  • behavioral ModuleManager - removeModule not found returns NotFound
  • behavioral ModuleManager - removeModule permanent module rejected
  • behavioral TypeRegistry - getTypes returns all registered type names
  • behavioral ModuleManager - addModule with valid parent_id succeeds
  • behavioral ModuleManager - addModule with invalid parent_id rejected
  • behavioral ModuleManager - removeModule with children returns HasChildren
  • behavioral ModuleManager - parent_id round-tripped through getModulesJson
  • behavioral ModuleManager - child module NOT registered in Scheduler (roots-only)
  • behavioral ModuleManager - child wired into parent's children_ list
  • behavioral ModuleManager - addModule child: added to parent, not Scheduler
  • behavioral ModuleManager - removeModule child: detached from parent, not Scheduler
  • integration ModuleManager - auto-creates default pipeline when no modules exist
  • integration ModuleManager - does NOT auto-create pipeline when DriverLayer+EffectsLayer exist

Network and WiFi

31/31 passedtest_network.cpp

  • behavioral NetworkModule - default device_name on PC starts with MM- and has length 7
  • behavioral NetworkModule - setProps overrides device_name
  • behavioral NetworkModule - loadState/saveState round-trip for device_name
  • format NetworkModule - getSchema includes device_name and mac_address
  • format NetworkModule - category is network
  • format NetworkModule - healthReport contains device= and mac=
  • behavioral EditStr - setControl round-trip via JsonVariant
  • behavioral EditStr - setControl(float) returns false for EditStr type
  • format EditStr - getSchema includes value for non-sensitive control
  • smoke WifiStaModule - lifecycle on PC does not crash
  • behavioral WifiStaModule - password absent from getControlValues (sensitive)
  • format WifiStaModule - password in getSchema without value field
  • behavioral WifiStaModule - saveState/loadState round-trip for ssid
  • format WifiStaModule - category is network
  • behavioral WifiStaModule - setControl ssid triggers pendingConnect via loop
  • behavioral WifiStaModule - password setLen is 0 when empty, actual length when set
  • behavioral WifiStaModule - password control uiType is password
  • smoke WifiApModule - lifecycle on PC does not crash
  • behavioral WifiApModule - setInput network accepted without crash
  • format WifiApModule - category is network
  • smoke EthernetModule - lifecycle does not crash
  • behavioral EthernetModule - status is unsupported after setup
  • format EthernetModule - category is network
  • format EthernetModule - healthReport contains eth=unsupported
  • smoke DeviceDiscoveryModule - lifecycle on PC does not crash
  • format DeviceDiscoveryModule - category is network
  • behavioral DeviceDiscoveryModule - setup registers broadcast_interval, status, and 8 device controls
  • format DeviceDiscoveryModule - healthReport starts with devices=0
  • behavioral DeviceDiscoveryModule - setInput network accepted without crash
  • behavioral DeviceDiscoveryModule - broadcast_interval saveState/loadState round-trip
  • behavioral DeviceDiscoveryModule - getControlValues includes status field

Preview Pipeline

3/3 passedtest_preview_e2e.cpp

  • integration Preview pipeline - non-zero output after 50 ticks
  • integration Preview pipeline - checksum varies across ticks
  • integration Preview pipeline - PreviewModule listed with fps>0 via HTTP

test_producer_consumer.cpp

7/7 passedtest_producer_consumer.cpp

  • behavioral buffer is null before setup
  • behavioral declareBuffer registers pointer, length and elemSize
  • behavioral bufferPtr gives read access to the underlying array
  • behavioral producer_ is null before wiring
  • behavioral setInput('producer', ...) wires the producer
  • behavioral setInput ignores unknown keys
  • behavioral consumer reads producer buffer after wiring

Scheduler

4/4 passedtest_scheduler.cpp

  • integration phase 1 sanity
  • behavioral Scheduler loopCore runs only matching-core modules
  • behavioral Scheduler loop() runs all modules via loopCore(0) then loopCore(1)
  • behavioral Scheduler loopCore timing is tracked per module

Sine Effect

3/3 passedtest_sine_effect.cpp

  • behavioral SineEffectModule - deterministic output for fixed frequency/amplitude
  • smoke SineEffectModule - zero residue after teardown
  • integration PreviewModule - consumer sees producer frame checksum via layers

Stateful Module

18/20 passedtest_stateful_module.cpp

  • behavioral sprint9/B: SystemStatusModule has 'progress' type controls
  • behavioral sprint9/B: SystemStatusModule progress controls have min=0 and max>0
  • behavioral sprint9/C: SystemStatusModule has 'button' type control for reboot
  • behavioral sprint9/C: SystemStatusModule reboot button is sensitive (absent from getControlValues)
  • format sprint9/D: SystemStatusModule string controls have string value in schema
  • behavioral sprint9/E: WifiApModule loadState/saveState round-trip for ap_password
  • behavioral sprint9/E: WifiApModule ap_password control is sensitive (not in getControlValues)
  • smoke sprint9/F: ModuleManager with disableStatePersistence does not write state files
  • behavioral sprint9/G: SineEffectModule frequency and amplitude are uint8_t
  • format sprint9/G: SineEffectModule getSchema includes integer=true for frequency
  • behavioral sprint9/G: SineEffectModule setControl with integer value clamps to uint8_t range
  • behavioral sprint9/G: SineEffectModule saveState/loadState round-trips integer frequency
  • behavioral sprint9/G: BrightnessModifierModule frequency is uint8_t
  • behavioral sprint9/G: BrightnessModifierModule setControl with integer value
  • behavioral sprint9: bool addControl with sensitive=true excludes value from getControlValues
  • behavioral sprint7/D: meta() const on uninitialised store returns empty document
  • behavioral sprint7/D: meta() stores and retrieves non-control fields
  • behavioral sprint7/D: meta() store survives teardown/runSetup cycle
  • behavioral R4S9/A: defVal captured from field initializer, not overwritten by setControl
  • behavioral R4S9/A: defVal is unchanged after saveState/loadState round-trip

System Status

14/14 passedtest_system_info.cpp

  • behavioral LogLevel enum ordering is cumulative
  • behavioral logLevelFromString parses all valid names
  • behavioral logLevelFromString rejects unknown names and nullptr
  • behavioral EffectsLayer heapSize equals 2 * width * height * sizeof(RGB)
  • behavioral DriverLayer heapSize equals width * height * sizeof(RGB)
  • behavioral EffectsLayer heapSize is non-zero for default-constructed (10x10x10) instance
  • format healthReport default writes empty string into buffer
  • format healthReport respects buffer length limit
  • smoke SystemStatusModule lifecycle: setup / loop / teardown
  • behavioral SystemStatusModule exposes key controls by name
  • format SystemStatusModule has no heap allocation
  • format SystemStatusModule classSize is sizeof(SystemStatusModule)
  • format SystemStatusModule healthReport writes non-empty string
  • format SystemStatusModule healthReport contains expected keys after loop1s sampling

System Utility Modules

10/10 passedtest_system_utils.cpp

  • smoke TasksModule - lifecycle does not crash
  • format TasksModule - healthReport format contains task_count=
  • format TasksModule - getSchema exposes tasks display and task_count display
  • behavioral TasksModule - task_count is non-negative after setup
  • smoke FileManagerModule - lifecycle does not crash
  • format FileManagerModule - healthReport format contains state_dir= and file_count=
  • format FileManagerModule - getSchema exposes files display, filename text, delete button
  • behavioral FileManagerModule - delete with empty filename sets error result
  • behavioral FileManagerModule - delete nonexistent file sets not-found result
  • behavioral FileManagerModule - delete existing file succeeds

WebSocket

17/17 passedtest_websocket.cpp

  • behavioral getControlValues returns empty object for module with no controls
  • behavioral getControlValues reflects live field values
  • behavioral getControlValues updates after second setControl
  • behavioral snapshot returns false before first loop()
  • behavioral snapshot returns true after first loop() and fills buffer
  • behavioral snapshot header: byte 0 is 0x01 (pixel frame type)
  • behavioral snapshot header: width and height encoded little-endian
  • behavioral snapshot payload size matches width * height * 3
  • behavioral snapshot pixel values are non-zero after SineEffectModule runs
  • behavioral getStateJson returns one entry per module
  • behavioral getStateJson entries have id, controls, and timing fields
  • behavioral getStateJson timing fps is positive after one tick
  • behavioral getStateJson control values reflect live state
  • behavioral pixelSnapshot returns true for consumer1 after one tick
  • behavioral pixelSnapshot returns false for unknown module id
  • behavioral getStateJson valid before and after runtime addModule (root)
  • behavioral getStateJson valid before and after runtime removeModule (child)