11test_that(" predict_selection_score returns correct structure" , {
2- gmat <- gen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
3- pmat <- phen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
4- cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [,- 1 ], wcol = 1 )
5-
6- scores <- predict_selection_score(cindex , data = seldata [,3 : 9 ], genotypes = seldata [,2 ])
7-
2+ gmat <- gen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
3+ pmat <- phen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
4+ cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [, - 1 ], wcol = 1 )
5+
6+ scores <- predict_selection_score(cindex , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ])
7+
88 expect_true(is.data.frame(scores ))
99 expect_true(" Genotypes" %in% colnames(scores ))
10- expect_equal(nrow(scores ), nlevels(as.factor(seldata [,2 ])))
10+ expect_equal(nrow(scores ), nlevels(as.factor(seldata [, 2 ])))
1111})
1212
1313test_that(" predict_selection_score includes rank columns" , {
14- gmat <- gen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
15- pmat <- phen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
16- cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [,- 1 ], wcol = 1 )
17-
18- scores <- predict_selection_score(cindex , data = seldata [,3 : 9 ], genotypes = seldata [,2 ])
19-
14+ gmat <- gen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
15+ pmat <- phen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
16+ cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [, - 1 ], wcol = 1 )
17+
18+ scores <- predict_selection_score(cindex , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ])
19+
2020 # Check that rank columns exist for each index
2121 rank_cols <- colnames(scores )[grepl(" _Rank$" , colnames(scores ))]
2222 expect_true(length(rank_cols ) > 0 )
2323})
2424
2525test_that(" predict_selection_score ranks are valid" , {
26- gmat <- gen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
27- pmat <- phen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
28- cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [,- 1 ], wcol = 1 )
29-
30- scores <- predict_selection_score(cindex , data = seldata [,3 : 9 ], genotypes = seldata [,2 ])
31-
26+ gmat <- gen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
27+ pmat <- phen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
28+ cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [, - 1 ], wcol = 1 )
29+
30+ scores <- predict_selection_score(cindex , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ])
31+
3232 # Get rank columns
3333 rank_cols <- colnames(scores )[grepl(" _Rank$" , colnames(scores ))]
34-
34+
3535 for (col in rank_cols ) {
3636 # Ranks should be numeric
3737 expect_true(is.numeric(scores [[col ]]))
38-
38+
3939 # Ranks should be in valid range
4040 n_genotypes <- nrow(scores )
4141 expect_true(all(scores [[col ]] > = 1 & scores [[col ]] < = n_genotypes ))
42-
42+
4343 # Check that all ranks from 1 to n are present (accounting for ties)
4444 expect_true(min(scores [[col ]]) > = 1 )
4545 expect_true(max(scores [[col ]]) < = n_genotypes )
4646 }
4747})
4848
4949test_that(" predict_selection_score higher scores get lower ranks" , {
50- gmat <- gen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
51- pmat <- phen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
52- cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [,- 1 ], wcol = 1 )
53-
54- scores <- predict_selection_score(cindex , data = seldata [,3 : 9 ], genotypes = seldata [,2 ])
55-
50+ gmat <- gen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
51+ pmat <- phen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
52+ cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [, - 1 ], wcol = 1 )
53+
54+ scores <- predict_selection_score(cindex , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ])
55+
5656 # Get first score and rank columns
5757 score_col <- colnames(scores )[! colnames(scores ) %in% c(" Genotypes" , grep(" _Rank$" , colnames(scores ), value = TRUE ))]
5858 rank_col <- paste0(score_col [1 ], " _Rank" )
59-
59+
6060 # Check that higher scores have lower (better) ranks
6161 for (i in 1 : nrow(scores )) {
6262 for (j in 1 : nrow(scores )) {
@@ -68,34 +68,96 @@ test_that("predict_selection_score higher scores get lower ranks", {
6868})
6969
7070test_that(" predict_selection_score works with multiple indices" , {
71- gmat <- gen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
72- pmat <- phen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
73- cindex <- lpsi(ncomb = 2 , pmat = pmat , gmat = gmat , wmat = weight [,- 1 ], wcol = 1 )
74-
75- scores <- predict_selection_score(cindex , data = seldata [,3 : 9 ], genotypes = seldata [,2 ])
76-
71+ gmat <- gen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
72+ pmat <- phen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
73+ cindex <- lpsi(ncomb = 2 , pmat = pmat , gmat = gmat , wmat = weight [, - 1 ], wcol = 1 )
74+
75+ scores <- predict_selection_score(cindex , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ])
76+
7777 # Should have multiple index scores and corresponding ranks
7878 all_cols <- colnames(scores )
7979 rank_cols <- all_cols [grepl(" _Rank$" , all_cols )]
8080 score_cols <- all_cols [grepl(" ^I_" , all_cols )]
81- score_cols <- score_cols [! grepl(" _Rank$" , score_cols )] # Remove rank columns
82-
81+ score_cols <- score_cols [! grepl(" _Rank$" , score_cols )] # Remove rank columns
82+
8383 expect_equal(length(rank_cols ), length(score_cols ))
84- expect_true(length(score_cols ) > 1 ) # Multiple indices
84+ expect_true(length(score_cols ) > 1 ) # Multiple indices
8585})
8686
8787test_that(" predict_selection_score handles error cases" , {
88- gmat <- gen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
89- pmat <- phen_varcov(seldata [,3 : 9 ], seldata [,2 ], seldata [,1 ])
90- cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [,- 1 ], wcol = 1 )
91-
88+ gmat <- gen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
89+ pmat <- phen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
90+ cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [, - 1 ], wcol = 1 )
91+
9292 # Test with wrong genotypes length
9393 expect_error(
94- predict_selection_score(cindex , data = seldata [,3 : 9 ], genotypes = seldata [1 : 10 ,2 ])
94+ predict_selection_score(cindex , data = seldata [, 3 : 9 ], genotypes = seldata [1 : 10 , 2 ])
9595 )
96-
96+
9797 # Test with not a data frame
9898 expect_error(
99- predict_selection_score(as.list(cindex ), data = seldata [,3 : 9 ], genotypes = seldata [,2 ])
99+ predict_selection_score(as.list(cindex ), data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ])
100+ )
101+ })
102+
103+ # ==============================================================================
104+ # NEW COVERAGE TESTS — targeting previously uncovered lines
105+ # ==============================================================================
106+
107+ test_that(" predict_selection_score additional input validations (lines 21-59)" , {
108+ gmat <- gen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
109+ pmat <- phen_varcov(seldata [, 3 : 9 ], seldata [, 2 ], seldata [, 1 ])
110+ cindex <- lpsi(ncomb = 1 , pmat = pmat , gmat = gmat , wmat = weight [, - 1 ], wcol = 1 )
111+
112+ # line 21: missing ID column
113+ cindex_no_id <- cindex
114+ cindex_no_id $ ID <- NULL
115+ expect_error(
116+ predict_selection_score(cindex_no_id , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ]),
117+ " index_df must contain an ID column"
118+ )
119+
120+ # line 25: missing b.* columns
121+ cindex_no_b <- cindex
122+ b_cols <- grep(" ^b\\ ." , names(cindex_no_b ), value = TRUE )
123+ for (col in b_cols ) cindex_no_b [[col ]] <- NULL
124+ expect_error(
125+ predict_selection_score(cindex_no_b , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ]),
126+ " index_df must contain b.* columns"
127+ )
128+
129+ # line 31: data contains no traits (ncol = 0)
130+ empty_data <- matrix (nrow = nrow(seldata ), ncol = 0 )
131+ expect_error(
132+ predict_selection_score(cindex , data = empty_data , genotypes = seldata [, 2 ]),
133+ " data must contain at least one trait column"
134+ )
135+
136+ # line 51: ID must contain comma-separated indices (causing NA parser result)
137+ cindex_bad_id_format <- cindex
138+ cindex_bad_id_format $ ID [1 ] <- " 1, 2, letters"
139+ suppressWarnings(
140+ expect_error(
141+ predict_selection_score(cindex_bad_id_format , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ]),
142+ " ID must contain comma-separated trait indices"
143+ )
144+ )
145+
146+ # line 54: ID indices exceed number of columns in data
147+ cindex_out_of_bounds <- cindex
148+ cindex_out_of_bounds $ ID [1 ] <- paste(1 : 10 , collapse = " , " ) # data only has 7 columns
149+ expect_error(
150+ predict_selection_score(cindex_out_of_bounds , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ]),
151+ " ID indices exceed number of columns in data"
152+ )
153+
154+ # line 59: Number of b coefficients does not match ID length
155+ cindex_mismatched_b <- cindex
156+ # artificially add an extra index to ID without adding a b_col
157+ # original ID has 7 indices, let's make it 8
158+ cindex_mismatched_b $ ID [1 ] <- paste0(cindex_mismatched_b $ ID [1 ], " , 1" )
159+ expect_error(
160+ predict_selection_score(cindex_mismatched_b , data = seldata [, 3 : 9 ], genotypes = seldata [, 2 ]),
161+ " Number of b coefficients does not match ID length"
100162 )
101163})
0 commit comments