Skip to content

Raise test coverage to 100% (mark unreachable defensive branches)#5

Merged
billdenney merged 2 commits into
mainfrom
increase-coverage
Jun 28, 2026
Merged

Raise test coverage to 100% (mark unreachable defensive branches)#5
billdenney merged 2 commits into
mainfrom
increase-coverage

Conversation

@billdenney

Copy link
Copy Markdown
Member

Baseline R-side + compiled coverage was 99.45% (covr 3.6.5, type="tests"),
with exactly three uncovered lines, all of which are unreachable defensive
branches rather than untested logic:

  • R/thin.R:77 - the is.array(image) && length(dim(image)) == 2L recursion
    target in as_binary_matrix(). In R (>= 4.2, the package's floor) every
    object with a length-2 dim attribute also satisfies is.matrix(), so the
    is.matrix() branch above always handles 2-D arrays first. Verified by
    exhaustively tracing every array/data.frame/list-array input: none reach
    this line.
  • src/lee.cpp:42 - default: on_boundary = 0; for a sub value outside 0-3.
    sub is driven only by the internal for (int sub = 0; sub < 4; sub++)
    loop, so out-of-range values never occur.
  • src/distance_transform.cpp:235 - default: Rcpp::stop(...) for an unknown
    metric code. The R wrapper validates metric with match.arg() and maps it
    to codes 0/1/2 only, so an out-of-range code never reaches the C++.

Per the skip-coverage policy these three (and only these) are wrapped in
# nocov with a one-line category + reason comment. After the markers,
non-nocov coverage is 100% on every R and C++ file.

Also adds strict exact-value tests (the existing suite leaned on
expect_lt/expect_gt bounds):

  • tests/testthat/test-coercion-helpers.R (new) - pins as_binary_matrix()
    foreground-collapse and dimension behaviour, the 2-D-array dispatch
    equivalence, the documented error messages, and restore_storage()
    round-trips, all with expect_identical.
  • exact skeletons for zhang_suen/guo_hall/thinImage in test-thin.R.
  • exact medial-axis skeleton + Euclidean distance map in test-medial-axis.R.
  • exact full-matrix manhattan/chessboard/euclidean DTs in
    test-distance-transform.R.

devtools::test(): 0 failures. lintr::lint_package(): 0 lints.
R CMD check --as-cran: 0 errors, 0 warnings, 1 NOTE (pre-existing
non-portable compilation-flag note on Ubuntu).

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

billdenney and others added 2 commits June 28, 2026 14:12
Baseline R-side + compiled coverage was 99.45% (covr 3.6.5, type="tests"),
with exactly three uncovered lines, all of which are unreachable defensive
branches rather than untested logic:

- R/thin.R:77 - the `is.array(image) && length(dim(image)) == 2L` recursion
  target in as_binary_matrix(). In R (>= 4.2, the package's floor) every
  object with a length-2 `dim` attribute also satisfies is.matrix(), so the
  is.matrix() branch above always handles 2-D arrays first. Verified by
  exhaustively tracing every array/data.frame/list-array input: none reach
  this line.
- src/lee.cpp:42 - `default: on_boundary = 0;` for a `sub` value outside 0-3.
  `sub` is driven only by the internal `for (int sub = 0; sub < 4; sub++)`
  loop, so out-of-range values never occur.
- src/distance_transform.cpp:235 - `default: Rcpp::stop(...)` for an unknown
  metric code. The R wrapper validates `metric` with match.arg() and maps it
  to codes 0/1/2 only, so an out-of-range code never reaches the C++.

Per the skip-coverage policy these three (and only these) are wrapped in
`# nocov` with a one-line category + reason comment. After the markers,
non-nocov coverage is 100% on every R and C++ file.

Also adds strict exact-value tests (the existing suite leaned on
expect_lt/expect_gt bounds):
- tests/testthat/test-coercion-helpers.R (new) - pins as_binary_matrix()
  foreground-collapse and dimension behaviour, the 2-D-array dispatch
  equivalence, the documented error messages, and restore_storage()
  round-trips, all with expect_identical.
- exact skeletons for zhang_suen/guo_hall/thinImage in test-thin.R.
- exact medial-axis skeleton + Euclidean distance map in test-medial-axis.R.
- exact full-matrix manhattan/chessboard/euclidean DTs in
  test-distance-transform.R.

devtools::test(): 0 failures. lintr::lint_package(): 0 lints.
R CMD check --as-cran: 0 errors, 0 warnings, 1 NOTE (pre-existing
non-portable compilation-flag note on Ubuntu).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two defensively-unreachable `# nocov` guards previously fell back
*silently* when their impossible state was reached. A silent fallback on
an "impossible" branch masks the very bug it would signal. Convert both
to loud errors that name the violated invariant and the upstream
guarantee that makes the branch unreachable, so if the impossible ever
happens it is caught rather than hidden. The `# nocov` markers are kept
(the branches remain unreachable from R) with their comments relabelled
as fail-fast assertions.

- R/thin.R as_binary_matrix(): the length-2-`dim` array branch used to
  silently recurse. In R (>= 4.2) every length-2-`dim` object already
  satisfies is.matrix() and is handled by the branch above, so this is
  unreachable; now stop() reports the broken base-R invariant.
- src/lee.cpp lee_can_delete(): the switch `default:` used to silently
  set on_boundary = 0 for a sub-iteration index outside 0-3, but the
  driving loop is `for (sub = 0; sub < 4; sub++)`; now Rcpp::stop()
  reports the corrupted loop bound. Kept on one line so the single
  `// # nocov` excludes the whole statement (matches distance_transform.cpp).

src/distance_transform.cpp's `default:` guard was already a loud
Rcpp::stop() and is left unchanged.

Validation: devtools::test() 0 failures; coverage 100% of non-nocov
lines; lintr clean; R CMD check --as-cran 0E/0W/1N (pre-existing Ubuntu
compilation-flag NOTE).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
R/thin.R 100.00% <ø> (+2.85%) ⬆️
src/distance_transform.cpp 100.00% <ø> (+0.83%) ⬆️
src/lee.cpp 100.00% <ø> (+2.27%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@billdenney billdenney merged commit 38e8da9 into main Jun 28, 2026
9 checks passed
@billdenney billdenney deleted the increase-coverage branch June 28, 2026 15:13
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