Skip to content

sensorViz Offline Checks

Five checks of sensorviz_core, the Qt-free half of sensorViz. They link only the core (and through it sensordata and sensoranalysis's Qt-free core; catalog_check also sqlite3), and are defined in core/CMakeLists.txt, so they build in a host build without BUILD_QT_APPS and prove the core needs no Qt. They open no window.

Like the other checks in this tree they are plain main() programs with their own CHECK() macro, built behind an option and run by hand:

cmake -DBUILD_SENSORVIZ_CHECKS=ON <build-dir>
cmake --build <build-dir> --target catalog_check plotspec_check preference_check \
    transforms_check viewmodel_check
<build-dir>/Release/bin/catalog_check
<build-dir>/Release/bin/plotspec_check
<build-dir>/Release/bin/preference_check
<build-dir>/Release/bin/transforms_check
<build-dir>/Release/bin/viewmodel_check

Each prints every failing check with its line, then a count, and exits non-zero if any failed.

catalog_check

Checks openLog() (stream_catalog.h), which reads a log into a StreamCatalog. It opens the committed fixtures, then edits a temporary copy of the IMUTag fixture (in the system temporary directory, removed afterwards) to reach what no fixture holds.

Area Cases
Description Tag type and profile name, info rows, time domain, collection start (IMUTag header; earliest epoch sample), the compass_raw record set's table, columns and time source
Calibration The newest row read, its epoch and constants; an empty table, text that is not JSON, and JSON with no magnetometer each leaving no calibration and the expected warning
IMU corrections Every magnetometer sample calibrated with compasscore::applyMagnetometer(), and every acceleration sample less the zero-g offset, compared bit for bit with the stored rows corrected independently; uncorrected when there is no calibration
Events RESYNC* and RESTART_RECOVERY, in any case, becoming the imu_resync marker in time order; other events ignored
Failure A missing file refused with the open error, the caller's catalog untouched

When openLog() replaced the Qt loader, a one-off comparison of the two over every log on hand (54, five tag types) found every field and every envelope point identical; see the toolkit-neutral core proposal.

plotspec_check

Checks buildPlotSpec() (plot_spec.h), the function that decides what the plot shows. It opens the committed fixtures in host/docs/fixtures/sensorviz/ through sensordata, makes their streams with the built-in display defaults, and checks the spec built for a range of plot states. Expected ranges are recomputed from the sensordata stream summaries, not taken from the code under test.

Area Cases
Traces and axes State order, unknown ids ignored, one shared axis per group and one per ungrouped stream, each axis's member traces, plot data handles, pen widths
Shared axes The IMU accel group linked to the padded union of its ranges and labelled with the group name; the first member's custom range fixing the whole axis; a lone member with its own label, auto-scaling; a magnitude joining its group, its fixed default range kept alone and dropped when shared; the first side override placing the axis; different units never sharing; independence from listing order
Fixed and auto ranges Activity and voltage defaults, a custom range overriding a default, pressure auto-scaling on its data range
Preferences Colour and side overrides
Time and markers The time extent over all traces; event markers only with traces visible
Metadata box and title The start row on elapsed-time logs only, sea level with altitude, declination with heading, a hidden title, the gap mode
Formatting The collection-start text (UTC, rounded to the second) and range padding

preference_check

Checks PreferenceStore and colorFromString() (preference_store.h). The expected file text and colors are what Qt's QJsonDocument and QColor produced for the same input, taken when the store replaced the Qt code.

Area Cases
Writing A two-tag file with every kind of override byte for byte, an empty store, escaped strings, and keys above U+FFFF ordered before U+E000 as UTF-16 orders them
Reading The written file read back and rewritten identically; no version; sides trimmed in any case; color names; entries without overrides dropped
Entries remember() storing and removing, forget()
Refusals Each error and its message, the first fault in key order, and the store left unchanged
Colors Hex forms including 12- and 16-bit channels rounded as Qt rounds them, names ignoring case, spaces and tabs, and the strings Qt refused

When the store replaced the Qt code, a one-off comparison against that code found identical output for 3,000 random preference sets and identical results for 63,000 loads of valid and mutated files, apart from the malformed-JSON differences listed in the toolkit-neutral core proposal, and identical colors for about 300,000 strings.

transforms_check

Checks the display transforms and TransformRegistry (transforms.h). It opens the fixtures with openLog(), sets up a ViewModel as sensorViz does after a load, and runs the registry through a sink that adds each output to the ViewModel and records it.

Area Cases
Applicability IMUTag: altitude and magnitudes, never the compass; CompassTag: the compass, no altitude
Outputs Which streams each fixture gets, in publishing order, shown or hidden
Values Every acceleration-magnitude sample against its three stored axes; every compass sample against compasscore::solveOrientation() of its raw row; heading and pitch against compasscore::displayAngles()
Parameters Sea-level pressure remaking only altitude and carrying a pressure range over; declination and battery direction remaking only the heading, keeping its visibility, by the right amount; compass parameters changing nothing on IMUTag; a new run starting again
Specs The parameter specs the dialog and a web form are built from, and the ViewModel's parameters by id

Whether the outputs equal those of the Qt code they replaced is a question for sensorViz's --dump-state (State dump); this check holds the contracts. When the transforms moved, the dumps of 51 logs and two dataprocessing outputs were identical before and after.

session_cli

Not a check but a third client of the core, beside the Qt app and the future Rust one: it opens a log with Session and writes the state dump, or prints the hover readout at a time. Everything it prints comes from Session, so it shows the core's boundary is real.

cmake --build <build-dir> --target session_cli
<build-dir>/Release/bin/session_cli <log.db3> [--load-preferences <file>] --dump-state <out>
<build-dir>/Release/bin/session_cli <log.db3> [--load-preferences <file>] --hover <seconds>

Its dump of a log must equal the Qt app's --dump-state up to the activity filter step, which only the Qt app has:

sensorviz --load-log <log> --dump-state /tmp/qt.txt --no-user-prompts
session_cli <log> --dump-state /tmp/cli.txt
sed '/^== activity filter/,$d' /tmp/qt.txt | diff - /tmp/cli.txt

When it was added, that held for all 53 logs on hand (51, and two dataprocessing outputs), and with a preference file loaded.

viewmodel_check

Checks ViewModel (view_model.h), the view state behind the menus, with synthetic streams.

Area Cases
Streams Load defaults, a derived stream listed after its inputs, replacement in place with the old plot data reported, removal clearing the stream's range
Visibility Default visibility, derived streams always shown, unknown ids ignored, drawing order
Changes Every setter returns, and reports to the listener, exactly what changed, and nothing when nothing did
Ranges and appearance Explicit and linked ranges, clearing, color and side overrides over defaults
Session settings Title, UTC offset, cursors, gap mode and transform parameters, kept across a new log
Preferences What is captured (including the visibility rule that counts derived streams' defaults, kept so saved files match earlier versions), what is applied, unknown ids dropped, round trips, empty preferences restoring defaults
Plot The PlotState and PlotSpec built from the state

What the spec looks like drawn, and the Qt adapter around the ViewModel, are checked by comparing the documentation capture suites before and after a change; see Documentation Capture Hooks.