Skip to content

Commit 65641e7

Browse files
Merge pull request #1 from NIDAP-Community/dev-sovacool
test: create tests
2 parents 298b47e + 058a365 commit 65641e7

5 files changed

Lines changed: 315 additions & 49 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@
22

33
Code Ocean capsule: MOSuite - filter differential expression analysis results
44

5+
[![tests](https://github.com/NIDAP-Community/MOSuite-filter-diff/actions/workflows/tests.yml/badge.svg)](https://github.com/NIDAP-Community/MOSuite-filter-diff/actions/workflows/tests.yml)
6+
57
- [Code Ocean Capsule](https://poc-nci.codeocean.io/capsule/8221739/tree) | [Latest Release](https://poc-nci.codeocean.io/capsule/0936928/tree/latest)
68
- [MOSuite R package docs](https://ccbr.github.io/MOSuite/)

code/main.R

Lines changed: 163 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/env Rscript
2-
rlang::global_entrace()
32
library(argparse)
43
library(glue)
54
library(MOSuite)
@@ -13,58 +12,173 @@ setup_capsule_environment()
1312
# parse CLI arguments
1413
parser <- ArgumentParser()
1514

16-
parser$add_argument("--feature_id_colname", type="character", default=NULL, help="Column name for feature IDs")
17-
parser$add_argument("--significance_column", type="character", default="adjpval", help="Column name for significance")
18-
parser$add_argument("--significance_cutoff", type="double", default=0.05, help="Significance cutoff threshold")
19-
parser$add_argument("--change_column", type="character", default="logFC", help="Column name for change")
20-
parser$add_argument("--change_cutoff", type="double", default=1, help="Change cutoff threshold")
21-
parser$add_argument("--filtering_mode", type="character", default="any", help="Filter mode: any or all")
22-
parser$add_argument("--include_estimates", type="character", default="FC,logFC,tstat,pval,adjpval", help="Comma-separated list of estimates to include")
23-
parser$add_argument("--round_estimates", type="logical", default=TRUE, help="Round estimates")
24-
parser$add_argument("--rounding_decimal_for_percent_cells", type="integer", default=0, help="Decimal places for percent labels")
25-
parser$add_argument("--contrast_filter", type="character", default="none", help="Filter contrasts: keep, remove, or none")
26-
parser$add_argument("--contrasts", type="character", default="", help="Comma-separated list of contrasts")
27-
parser$add_argument("--groups", type="character", default="", help="Comma-separated list of groups")
28-
parser$add_argument("--groups_filter", type="character", default="none", help="Filter groups: keep, remove, or none")
29-
parser$add_argument("--label_font_size", type="double", default=6, help="Font size for labels")
30-
parser$add_argument("--label_distance", type="double", default=1, help="Distance of labels from bars")
31-
parser$add_argument("--y_axis_expansion", type="double", default=0.08, help="Y-axis expansion")
32-
parser$add_argument("--fill_colors", type="character", default="steelblue1,whitesmoke", help="Comma-separated fill colors")
33-
parser$add_argument("--pie_chart_in_3d", type="logical", default=TRUE, help="Draw pie charts in 3D")
34-
parser$add_argument("--bar_width", type="double", default=0.4, help="Bar width")
35-
parser$add_argument("--draw_bar_border", type="logical", default=TRUE, help="Draw bar borders")
36-
parser$add_argument("--plot_type", type="character", default="bar", help="Plot type: bar or pie")
37-
parser$add_argument("--plot_titles_fontsize", type="integer", default=12, help="Font size for plot titles")
15+
parser$add_argument(
16+
"--feature_id_colname",
17+
type = "character",
18+
default = NULL,
19+
help = "Column name for feature IDs"
20+
)
21+
parser$add_argument(
22+
"--significance_column",
23+
type = "character",
24+
default = "adjpval",
25+
help = "Column name for significance"
26+
)
27+
parser$add_argument(
28+
"--significance_cutoff",
29+
type = "double",
30+
default = 0.05,
31+
help = "Significance cutoff threshold"
32+
)
33+
parser$add_argument(
34+
"--change_column",
35+
type = "character",
36+
default = "logFC",
37+
help = "Column name for change"
38+
)
39+
parser$add_argument(
40+
"--change_cutoff",
41+
type = "double",
42+
default = 1,
43+
help = "Change cutoff threshold"
44+
)
45+
parser$add_argument(
46+
"--filtering_mode",
47+
type = "character",
48+
default = "any",
49+
help = "Filter mode: any or all"
50+
)
51+
parser$add_argument(
52+
"--include_estimates",
53+
type = "character",
54+
default = "FC,logFC,tstat,pval,adjpval",
55+
help = "Comma-separated list of estimates to include"
56+
)
57+
parser$add_argument(
58+
"--round_estimates",
59+
type = "logical",
60+
default = TRUE,
61+
help = "Round estimates"
62+
)
63+
parser$add_argument(
64+
"--rounding_decimal_for_percent_cells",
65+
type = "integer",
66+
default = 0,
67+
help = "Decimal places for percent labels"
68+
)
69+
parser$add_argument(
70+
"--contrast_filter",
71+
type = "character",
72+
default = "none",
73+
help = "Filter contrasts: keep, remove, or none"
74+
)
75+
parser$add_argument(
76+
"--contrasts",
77+
type = "character",
78+
default = "",
79+
help = "Comma-separated list of contrasts"
80+
)
81+
parser$add_argument(
82+
"--groups",
83+
type = "character",
84+
default = "",
85+
help = "Comma-separated list of groups"
86+
)
87+
parser$add_argument(
88+
"--groups_filter",
89+
type = "character",
90+
default = "none",
91+
help = "Filter groups: keep, remove, or none"
92+
)
93+
parser$add_argument(
94+
"--label_font_size",
95+
type = "double",
96+
default = 6,
97+
help = "Font size for labels"
98+
)
99+
parser$add_argument(
100+
"--label_distance",
101+
type = "double",
102+
default = 1,
103+
help = "Distance of labels from bars"
104+
)
105+
parser$add_argument(
106+
"--y_axis_expansion",
107+
type = "double",
108+
default = 0.08,
109+
help = "Y-axis expansion"
110+
)
111+
parser$add_argument(
112+
"--fill_colors",
113+
type = "character",
114+
default = "steelblue1,whitesmoke",
115+
help = "Comma-separated fill colors"
116+
)
117+
parser$add_argument(
118+
"--pie_chart_in_3d",
119+
type = "logical",
120+
default = TRUE,
121+
help = "Draw pie charts in 3D"
122+
)
123+
parser$add_argument(
124+
"--bar_width",
125+
type = "double",
126+
default = 0.4,
127+
help = "Bar width"
128+
)
129+
parser$add_argument(
130+
"--draw_bar_border",
131+
type = "logical",
132+
default = TRUE,
133+
help = "Draw bar borders"
134+
)
135+
parser$add_argument(
136+
"--plot_type",
137+
type = "character",
138+
default = "bar",
139+
help = "Plot type: bar or pie"
140+
)
141+
parser$add_argument(
142+
"--plot_titles_fontsize",
143+
type = "integer",
144+
default = 12,
145+
help = "Font size for plot titles"
146+
)
38147

39148
args <- parser$parse_args()
40149

41150
# load multiOmicDataSet from data directory
42151
moo <- load_moo_from_data_dir()
43152

44153
# run MOSuite
45-
moo |>
46-
filter_diff(
47-
feature_id_colname = args$feature_id_colname,
48-
significance_column = args$significance_column,
49-
significance_cutoff = args$significance_cutoff,
50-
change_column = args$change_column,
51-
change_cutoff = args$change_cutoff,
52-
filtering_mode = args$filtering_mode,
53-
include_estimates = parse_optional_vector(args$include_estimates),
54-
round_estimates = args$round_estimates,
55-
rounding_decimal_for_percent_cells = args$rounding_decimal_for_percent_cells,
56-
contrast_filter = args$contrast_filter,
57-
contrasts = parse_optional_vector(args$contrasts),
58-
groups = parse_optional_vector(args$groups),
59-
groups_filter = args$groups_filter,
60-
label_font_size = args$label_font_size,
61-
label_distance = args$label_distance,
62-
y_axis_expansion = args$y_axis_expansion,
63-
fill_colors = parse_optional_vector(args$fill_colors),
64-
pie_chart_in_3d = args$pie_chart_in_3d,
65-
bar_width = args$bar_width,
66-
draw_bar_border = args$draw_bar_border,
67-
plot_type = args$plot_type,
68-
plot_titles_fontsize = args$plot_titles_fontsize
69-
) |>
70-
write_rds(file.path(getOption("moo_plots_dir"), "..", "moo", "moo.rds"))
154+
moo |>
155+
filter_diff(
156+
feature_id_colname = args$feature_id_colname,
157+
significance_column = args$significance_column,
158+
significance_cutoff = args$significance_cutoff,
159+
change_column = args$change_column,
160+
change_cutoff = args$change_cutoff,
161+
filtering_mode = args$filtering_mode,
162+
include_estimates = parse_optional_vector(args$include_estimates),
163+
round_estimates = args$round_estimates,
164+
rounding_decimal_for_percent_cells = args$rounding_decimal_for_percent_cells,
165+
contrast_filter = args$contrast_filter,
166+
contrasts = parse_optional_vector(args$contrasts),
167+
groups = parse_optional_vector(args$groups),
168+
groups_filter = args$groups_filter,
169+
label_font_size = args$label_font_size,
170+
label_distance = args$label_distance,
171+
y_axis_expansion = args$y_axis_expansion,
172+
fill_colors = parse_optional_vector(args$fill_colors),
173+
pie_chart_in_3d = args$pie_chart_in_3d,
174+
bar_width = args$bar_width,
175+
draw_bar_border = args$draw_bar_border,
176+
plot_type = args$plot_type,
177+
plot_titles_fontsize = args$plot_titles_fontsize
178+
) |>
179+
write_rds(file.path(
180+
getOption("moo_plots_dir"),
181+
"..",
182+
"moo",
183+
"moo-diff-filt.rds"
184+
))

tests/data/moo-diff.rds

9.69 MB
Binary file not shown.

tests/testthat.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
library(testthat)
2+
test_dir(file.path('tests', 'testthat'), stop_on_failure = TRUE)

tests/testthat/test-main.R

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
test_that("code/run executes successfully with default CLI arguments", {
2+
# Create temporary workspace
3+
workspace <- tempfile("mosuite_filter_diff_test_")
4+
dir.create(workspace)
5+
on.exit(unlink(workspace, recursive = TRUE), add = TRUE)
6+
7+
# Set up directory structure
8+
code_dir <- file.path(workspace, "code")
9+
data_dir <- file.path(workspace, "data")
10+
results_dir <- file.path(code_dir, "..", "results")
11+
dir.create(code_dir)
12+
dir.create(data_dir)
13+
dir.create(results_dir)
14+
15+
# Get test data from package tests directory
16+
repo_root <- normalizePath(file.path(dirname(getwd()), ".."))
17+
test_data_file <- file.path(repo_root, "tests", "data", "moo-diff.rds")
18+
19+
expect_true(
20+
file.exists(test_data_file),
21+
info = paste("Test data file should exist at", test_data_file)
22+
)
23+
file.copy(test_data_file, file.path(data_dir, "moo.rds"))
24+
25+
# Copy main.R and run script to workspace
26+
file.copy(
27+
file.path(repo_root, "code", "main.R"),
28+
file.path(code_dir, "main.R")
29+
)
30+
file.copy(
31+
file.path(repo_root, "code", "run"),
32+
file.path(code_dir, "run")
33+
)
34+
35+
# Run the script from code directory
36+
old_wd <- getwd()
37+
setwd(code_dir)
38+
on.exit(setwd(old_wd), add = TRUE)
39+
40+
# Execute run script with default CLI arguments
41+
exit_code <- system2(
42+
"bash",
43+
args = c(
44+
"run",
45+
"--significance_column=adjpval",
46+
"--significance_cutoff=0.05",
47+
"--change_column=logFC",
48+
"--change_cutoff=1",
49+
"--filtering_mode=any"
50+
)
51+
)
52+
53+
# Check for successful execution
54+
expect_equal(exit_code, 0, info = "run script should execute without error")
55+
expect_true(
56+
file.exists(file.path(results_dir, "moo", "moo-diff-filt.rds")),
57+
info = "Output file moo-diff-filt.rds should be created"
58+
)
59+
60+
# Validate output is a valid MOO object
61+
moo <- readr::read_rds(file.path(results_dir, "moo", "moo-diff-filt.rds"))
62+
expect_true(
63+
S7::S7_inherits(moo, MOSuite::multiOmicDataSet),
64+
info = "Output should be an S7 multiOmicDataSet object"
65+
)
66+
67+
# Validate diff results exist
68+
expect_true(
69+
"diff" %in% names(moo@analyses),
70+
info = "Output should have diff results in moo@analyses"
71+
)
72+
})
73+
74+
test_that("code/run executes with custom CLI arguments", {
75+
# Create temporary workspace
76+
workspace <- tempfile("mosuite_filter_diff_custom_test_")
77+
dir.create(workspace)
78+
on.exit(unlink(workspace, recursive = TRUE), add = TRUE)
79+
80+
# Set up directory structure
81+
code_dir <- file.path(workspace, "code")
82+
data_dir <- file.path(workspace, "data")
83+
results_dir <- file.path(code_dir, "..", "results")
84+
dir.create(code_dir)
85+
dir.create(data_dir)
86+
dir.create(results_dir)
87+
88+
# Get test data from package tests directory
89+
repo_root <- normalizePath(file.path(dirname(getwd()), ".."))
90+
test_data_file <- file.path(repo_root, "tests", "data", "moo-diff.rds")
91+
92+
# Copy test data to workspace
93+
file.copy(test_data_file, file.path(data_dir, "moo.rds"))
94+
95+
# Copy main.R and run script to workspace
96+
file.copy(
97+
file.path(repo_root, "code", "main.R"),
98+
file.path(code_dir, "main.R")
99+
)
100+
file.copy(
101+
file.path(repo_root, "code", "run"),
102+
file.path(code_dir, "run")
103+
)
104+
105+
# Run the script from code directory
106+
old_wd <- getwd()
107+
setwd(code_dir)
108+
on.exit(setwd(old_wd), add = TRUE)
109+
110+
# Execute run script with custom CLI arguments
111+
exit_code <- system2(
112+
"bash",
113+
args = c(
114+
"run",
115+
"--significance_column=pval",
116+
"--significance_cutoff=0.01",
117+
"--change_column=logFC",
118+
"--change_cutoff=2",
119+
"--filtering_mode=all",
120+
"--round_estimates=TRUE",
121+
"--plot_type=bar"
122+
)
123+
)
124+
125+
# Check for successful execution
126+
expect_equal(
127+
exit_code,
128+
0,
129+
info = "run script with custom args should execute without error"
130+
)
131+
expect_true(
132+
file.exists(file.path(results_dir, "moo", "moo-diff-filt.rds")),
133+
info = "Output file moo-diff-filt.rds should be created with custom args"
134+
)
135+
136+
# Validate output is a valid MOO object
137+
moo <- readr::read_rds(file.path(results_dir, "moo", "moo-diff-filt.rds"))
138+
expect_true(
139+
S7::S7_inherits(moo, MOSuite::multiOmicDataSet),
140+
info = "Output should be an S7 multiOmicDataSet object"
141+
)
142+
143+
# Validate diff results exist
144+
expect_true(
145+
"diff" %in% names(moo@analyses),
146+
info = "Output should have diff results in moo@analyses"
147+
)
148+
})

0 commit comments

Comments
 (0)