Skip to content

Commit a85d684

Browse files
committed
Setup code coverage and its monitoring via GHA.
1 parent 948ebcc commit a85d684

10 files changed

Lines changed: 312 additions & 0 deletions

File tree

.Rbuildignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
^data-raw$
55
^README\.Rmd$
66
^CODE_OF_CONDUCT\.md$
7+
^codecov\.yml$
8+
^\.github$

.github/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.html
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2+
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
8+
name: test-coverage.yaml
9+
10+
permissions: read-all
11+
12+
jobs:
13+
test-coverage:
14+
runs-on: ubuntu-latest
15+
env:
16+
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- uses: r-lib/actions/setup-r@v2
22+
with:
23+
use-public-rspm: true
24+
25+
- uses: r-lib/actions/setup-r-dependencies@v2
26+
with:
27+
extra-packages: any::covr, any::xml2
28+
needs: coverage
29+
30+
- name: Test coverage
31+
run: |
32+
cov <- covr::package_coverage(
33+
quiet = FALSE,
34+
clean = FALSE,
35+
install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package")
36+
)
37+
print(cov)
38+
covr::to_cobertura(cov)
39+
shell: Rscript {0}
40+
41+
- uses: codecov/codecov-action@v5
42+
with:
43+
# Fail if error if not on PR, or if on PR and token is given
44+
fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }}
45+
files: ./cobertura.xml
46+
plugins: noop
47+
disable_search: true
48+
token: ${{ secrets.CODECOV_TOKEN }}
49+
50+
- name: Show testthat output
51+
if: always()
52+
run: |
53+
## --------------------------------------------------------------------
54+
find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true
55+
shell: bash
56+
57+
- name: Upload test results
58+
if: failure()
59+
uses: actions/upload-artifact@v4
60+
with:
61+
name: coverage-test-failures
62+
path: ${{ runner.temp }}/package

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ Imports:
2424
Depends:
2525
R (>= 3.5)
2626
LazyData: true
27+
Suggests: tinytest

README.Rmd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ knitr::opts_chunk$set(
1616
# inphr
1717

1818
<!-- badges: start -->
19+
[![Codecov test coverage](https://codecov.io/gh/tdaverse/inphr/graph/badge.svg)](https://app.codecov.io/gh/tdaverse/inphr)
1920
<!-- badges: end -->
2021

2122
The goal of {inphr} is to provide a set of functions for performing null

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
<!-- badges: start -->
77

8+
[![Codecov test
9+
coverage](https://codecov.io/gh/tdaverse/inphr/graph/badge.svg)](https://app.codecov.io/gh/tdaverse/inphr)
810
<!-- badges: end -->
911

1012
The goal of {inphr} is to provide a set of functions for performing null

codecov.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
comment: false
2+
3+
coverage:
4+
status:
5+
project:
6+
default:
7+
target: auto
8+
threshold: 1%
9+
informational: true
10+
patch:
11+
default:
12+
target: auto
13+
threshold: 1%
14+
informational: true
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Test basic functionality with mock data
2+
test_two_sample_test_basic <- function() {
3+
# Mock persistence sets
4+
ps1 <- trefoils1[1:5] # Assuming trefoils1 is a persistence set
5+
ps2 <- trefoils2[1:5] # Assuming trefoils2 is a persistence set
6+
7+
# Mock parse_inputs function
8+
parse_inputs <- function(x, y, dimension, p, ncores) {
9+
list(
10+
D = matrix(runif(100), 10, 10),
11+
sample_sizes = c(5, 5)
12+
)
13+
}
14+
15+
# Mock null_spec function
16+
null_spec <- function(...) NULL
17+
18+
result <- two_sample_test(ps1, ps2, B = 10L)
19+
expect_true(is.numeric(result))
20+
expect_true(result >= 0 && result <= 1)
21+
}
22+
23+
# Test parameter validation
24+
test_two_sample_test_params <- function() {
25+
ps1 <- trefoils1[1:5] # Assuming trefoils1 is a persistence set
26+
ps2 <- trefoils2[1:5] # Assuming trefoils2 is a persistence set
27+
28+
expect_error(two_sample_test(ps1, ps2, dimension = -1L))
29+
expect_error(two_sample_test(ps1, ps2, p = 0L))
30+
expect_error(two_sample_test(ps1, ps2, B = 0L))
31+
expect_error(two_sample_test(ps1, ps2, npc = "invalid"))
32+
}
33+
34+
# Test with distance matrix input
35+
test_two_sample_test_dist <- function() {
36+
D <- as.dist(matrix(runif(100), 10, 10))
37+
sample_sizes <- c(5L, 5L)
38+
39+
result <- two_sample_test(D, sample_sizes, B = 10L)
40+
expect_true(is.numeric(result))
41+
expect_true(result >= 0 && result <= 1)
42+
}
43+
44+
# Test verbose output
45+
test_two_sample_test_verbose <- function() {
46+
ps1 <- trefoils1[1:5] # Assuming trefoils1 is a persistence set
47+
ps2 <- trefoils2[1:5] # Assuming trefoils2 is a persistence set
48+
49+
expect_silent(two_sample_test(ps1, ps2, B = 10L, verbose = FALSE))
50+
}
51+
52+
# Test different npc methods
53+
test_two_sample_test_npc <- function() {
54+
ps1 <- trefoils1[1:5] # Assuming trefoils1 is a persistence set
55+
ps2 <- trefoils2[1:5] # Assuming trefoils2 is a persistence set
56+
57+
result_tippett <- two_sample_test(ps1, ps2, B = 10L, npc = "tippett")
58+
result_fisher <- two_sample_test(ps1, ps2, B = 10L, npc = "fisher")
59+
60+
expect_true(is.numeric(result_tippett))
61+
expect_true(is.numeric(result_fisher))
62+
}
63+
64+
# Run all tests
65+
test_two_sample_test <- function() {
66+
test_two_sample_test_basic()
67+
test_two_sample_test_params()
68+
test_two_sample_test_dist()
69+
test_two_sample_test_verbose()
70+
test_two_sample_test_npc()
71+
}
72+
73+
test_two_sample_test()
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
test_that("two_sample_test works with persistence sets", {
2+
testthat::skip_if_not_installed("phutil")
3+
testthat::skip_if_not_installed("flipr")
4+
5+
# Mock the parse_inputs function to avoid actual computation
6+
mockD <- matrix(1:16, 4, 4)
7+
class(mockD) <- "dist"
8+
mock_result <- list(D = mockD, sample_sizes = c(2, 2))
9+
10+
testthat::local_mocked_bindings(
11+
parse_inputs = function(...) mock_result,
12+
null_spec = function(y, parameters) y
13+
)
14+
15+
# Create a mock PlausibilityFunction class
16+
MockPF <- R6::R6Class(
17+
"PlausibilityFunction",
18+
public = list(
19+
alternative = NULL,
20+
nperms = NULL,
21+
aggregator = NULL,
22+
initialize = function(...) {
23+
},
24+
get_value = function(...) 0.042
25+
)
26+
)
27+
28+
# Mock the flipr package
29+
testthat::local_mocked_bindings(
30+
PlausibilityFunction = MockPF,
31+
stat_t_ip = function() {
32+
},
33+
stat_f_ip = function() {
34+
},
35+
.package = "flipr"
36+
)
37+
38+
# Test with default parameters
39+
result <- two_sample_test(
40+
x = list(),
41+
y = list(),
42+
B = 100L
43+
)
44+
expect_equal(result, 0.042)
45+
})
46+
47+
test_that("two_sample_test handles verbose parameter correctly", {
48+
testthat::skip_if_not_installed("phutil")
49+
testthat::skip_if_not_installed("flipr")
50+
51+
# Mock the parse_inputs function to avoid actual computation
52+
mockD <- matrix(1:16, 4, 4)
53+
class(mockD) <- "dist"
54+
mock_result <- list(D = mockD, sample_sizes = c(2, 2))
55+
56+
testthat::local_mocked_bindings(
57+
parse_inputs = function(...) mock_result,
58+
null_spec = function(y, parameters) y
59+
)
60+
61+
# Create a mock PlausibilityFunction class
62+
MockPF <- R6::R6Class(
63+
"PlausibilityFunction",
64+
public = list(
65+
alternative = NULL,
66+
nperms = NULL,
67+
aggregator = NULL,
68+
initialize = function(...) {
69+
},
70+
get_value = function(...) 0.042
71+
)
72+
)
73+
74+
# Mock the flipr package
75+
testthat::local_mocked_bindings(
76+
PlausibilityFunction = MockPF,
77+
stat_t_ip = function() {
78+
},
79+
stat_f_ip = function() {
80+
},
81+
.package = "flipr"
82+
)
83+
84+
# Test with verbose = TRUE
85+
expect_snapshot(
86+
two_sample_test(
87+
x = list(),
88+
y = list(),
89+
B = 100L,
90+
verbose = TRUE
91+
)
92+
)
93+
})
94+
95+
test_that("two_sample_test sets correct parameters for plausibility function", {
96+
testthat::skip_if_not_installed("phutil")
97+
testthat::skip_if_not_installed("flipr")
98+
99+
# Mock the parse_inputs function
100+
mockD <- matrix(1:16, 4, 4)
101+
class(mockD) <- "dist"
102+
mock_result <- list(D = mockD, sample_sizes = c(2, 2))
103+
104+
testthat::local_mocked_bindings(
105+
parse_inputs = function(...) mock_result,
106+
null_spec = function(y, parameters) y
107+
)
108+
109+
# Create a testable mock PlausibilityFunction class that records parameters
110+
params_set <- list()
111+
MockPF <- R6::R6Class(
112+
"PlausibilityFunction",
113+
public = list(
114+
alternative = NULL,
115+
nperms = NULL,
116+
aggregator = NULL,
117+
initialize = function(...) {
118+
params_set <<- list(...)
119+
},
120+
get_value = function(...) 0.042
121+
)
122+
)
123+
124+
# Mock the flipr package
125+
testthat::local_mocked_bindings(
126+
PlausibilityFunction = MockPF,
127+
stat_t_ip = function() {
128+
},
129+
stat_f_ip = function() {
130+
},
131+
.package = "flipr"
132+
)
133+
134+
# Test with custom B and npc parameters
135+
custom_B <- 500L
136+
custom_npc <- "fisher"
137+
138+
result <- two_sample_test(
139+
x = list(),
140+
y = list(),
141+
B = custom_B,
142+
npc = custom_npc
143+
)
144+
145+
# Verify correct parameters were set
146+
expect_equal(params_set[[4]], mockD) # D parameter
147+
expect_equal(params_set[[5]], 2) # sample_sizes[1]
148+
149+
# Check the PlausibilityFunction properties were set correctly
150+
expect_equal(MockPF$new()$alternative, "right_tail")
151+
expect_equal(MockPF$new()$nperms, custom_B)
152+
expect_equal(MockPF$new()$aggregator, custom_npc)
153+
})

tests/tinytest.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
if (requireNamespace("tinytest", quietly = TRUE)) {
2+
tinytest::test_package("inphr")
3+
}

0 commit comments

Comments
 (0)