Skip to content

test: cover the infrastructure branches nothing reached - #859

Merged
blaipr merged 1 commit into
mainfrom
test/cover-the-infrastructure-branches-nothing-reached
Aug 23, 2026
Merged

test: cover the infrastructure branches nothing reached#859
blaipr merged 1 commit into
mainfrom
test/cover-the-infrastructure-branches-nothing-reached

Conversation

@blaipr

@blaipr blaipr commented Aug 23, 2026

Copy link
Copy Markdown
Member

Error paths and secondary branches in four widely-used infrastructure classes, none of
which had a test: the router's error handling, Util's reflection helpers, the two
constants Functions.php computes at load time, and Crypt's ASCII key branch.

Router: the routing-miss catch is asserted to be distinct from the generic Throwable
catch (an onError spy that stays uncalled), that a responder exception reaches a
registered error handler with the router, message, class and throwable, and that it is
rethrown when none is registered.

Functions.php: MODULES_PATH and LOG_FILE are computed from APP_PATH at load time, and
the suite's own bootstrap has already required the file before any test runs — so the
constants cannot be recomputed in-process and the file cannot be re-required (that
fatals on the function redeclarations). Each test spawns a child with a fresh APP_ROOT
and asserts the exact computed value, which is also how initModule()'s non-array return
is covered.

Two branches are left uncovered deliberately, both established by measurement rather
than assumed:

  • Version::checkVersion()'s 32-bit arm, behind PHP_INT_SIZE > 4. PHP_INT_SIZE is 8 on
    every 64-bit build, so the branch is unreachable here; covering it would mean running
    the suite on a 32-bit PHP.
  • Crypt::makeSecuredKey()'s catch. No password content reaches it — empty, embedded NUL,
    five megabytes, invalid UTF-8 were all tried — because the password is reduced to a
    fixed-length digest before it meets the library's primitives. Only a broken runtime
    (no openssl, exhausted CSPRNG) throws there.
  • Functions.php's if (!defined('MODULES_PATH')) guard in initModule() is dead: the
    constant is defined unconditionally as the first executable line of the same file.

The ASCII arm of Crypt::unlockSecuredKey() is covered through reflection because both
of its callers hard-code the other value. That is worth knowing rather than hiding: it
is currently dead in the call graph, and the test pins what it returns if a caller ever
uses it — the returned text is itself a usable key.

Error paths and secondary branches in four widely-used infrastructure classes, none of
which had a test: the router's error handling, Util's reflection helpers, the two
constants Functions.php computes at load time, and Crypt's ASCII key branch.

Router: the routing-miss catch is asserted to be distinct from the generic Throwable
catch (an onError spy that stays uncalled), that a responder exception reaches a
registered error handler with the router, message, class and throwable, and that it is
rethrown when none is registered.

Functions.php: MODULES_PATH and LOG_FILE are computed from APP_PATH at load time, and
the suite's own bootstrap has already required the file before any test runs — so the
constants cannot be recomputed in-process and the file cannot be re-required (that
fatals on the function redeclarations). Each test spawns a child with a fresh APP_ROOT
and asserts the exact computed value, which is also how initModule()'s non-array return
is covered.

Two branches are left uncovered deliberately, both established by measurement rather
than assumed:

- Version::checkVersion()'s 32-bit arm, behind `PHP_INT_SIZE > 4`. PHP_INT_SIZE is 8 on
  every 64-bit build, so the branch is unreachable here; covering it would mean running
  the suite on a 32-bit PHP.
- Crypt::makeSecuredKey()'s catch. No password content reaches it — empty, embedded NUL,
  five megabytes, invalid UTF-8 were all tried — because the password is reduced to a
  fixed-length digest before it meets the library's primitives. Only a broken runtime
  (no openssl, exhausted CSPRNG) throws there.
- Functions.php's `if (!defined('MODULES_PATH'))` guard in initModule() is dead: the
  constant is defined unconditionally as the first executable line of the same file.

The ASCII arm of Crypt::unlockSecuredKey() is covered through reflection because both
of its callers hard-code the other value. That is worth knowing rather than hiding: it
is currently dead in the call graph, and the test pins what it returns if a caller ever
uses it — the returned text is itself a usable key.
@blaipr
blaipr merged commit 23462cb into main Aug 23, 2026
8 checks passed
@blaipr
blaipr deleted the test/cover-the-infrastructure-branches-nothing-reached branch August 23, 2026 22:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant