@@ -1016,10 +1016,12 @@ test_that("Enhanced stub targeting: content-based targeting works", {
10161016 )
10171017
10181018 # Check that styles are applied correctly
1019+ # With multi-column stub, styles are applied to all 3 columns for each targeted row
10191020 styles <- gt ::: dt_styles_get(styled_table )
1020- expect_equal(nrow(styles ), 2 ) # Should target 2 Ford rows
1021- expect_equal(unique(styles $ rownum ), c(1 , 2 ))
1022- expect_equal(unique(styles $ locname ), " stub" )
1021+ expect_equal(nrow(styles ), 6 ) # 2 Ford rows * 3 columns
1022+ expect_setequal(unique(styles $ rownum ), c(1 , 2 ))
1023+ expect_equal(unique(styles $ locname ), " stub_column" )
1024+ expect_setequal(unique(styles $ colname ), c(" mfr" , " model" , " trim" ))
10231025
10241026 # Test table renders without error
10251027 expect_no_error(as_raw_html(styled_table ))
@@ -1043,10 +1045,12 @@ test_that("Enhanced stub targeting: multi-value targeting works", {
10431045 )
10441046
10451047 # Check that styles are applied correctly
1048+ # With multi-column stub, styles are applied to all 3 columns for each targeted row
10461049 styles <- gt ::: dt_styles_get(styled_table )
1047- expect_equal(nrow(styles ), 4 ) # Should target 4 rows (2 Ford + 2 BMW)
1048- expect_equal(unique(styles $ rownum ), c(1 , 2 , 3 , 4 ))
1049- expect_equal(unique(styles $ locname ), " stub" )
1050+ expect_equal(nrow(styles ), 12 ) # 4 rows (2 Ford + 2 BMW) * 3 columns
1051+ expect_setequal(unique(styles $ rownum ), c(1 , 2 , 3 , 4 ))
1052+ expect_equal(unique(styles $ locname ), " stub_column" )
1053+ expect_setequal(unique(styles $ colname ), c(" mfr" , " model" , " trim" ))
10501054})
10511055
10521056test_that(" Enhanced stub targeting: column-specific targeting works" , {
@@ -1092,10 +1096,12 @@ test_that("Enhanced stub targeting: model-specific targeting works", {
10921096 )
10931097
10941098 # Check that styles are applied correctly
1099+ # With multi-column stub, styles are applied to all 3 columns for each targeted row
10951100 styles <- gt ::: dt_styles_get(styled_table )
1096- expect_equal(nrow(styles ), 2 ) # Should target 2 rows (GT and A4)
1097- expect_equal(unique(styles $ rownum ), c(1 , 5 ))
1098- expect_equal(unique(styles $ locname ), " stub" )
1101+ expect_equal(nrow(styles ), 6 ) # 2 rows (GT and A4) * 3 columns
1102+ expect_setequal(unique(styles $ rownum ), c(1 , 5 ))
1103+ expect_equal(unique(styles $ locname ), " stub_column" )
1104+ expect_setequal(unique(styles $ colname ), c(" mfr" , " model" , " trim" ))
10991105})
11001106
11011107test_that(" Enhanced stub targeting: backward compatibility with numeric indices" , {
@@ -1117,9 +1123,100 @@ test_that("Enhanced stub targeting: backward compatibility with numeric indices"
11171123
11181124 # Check that styles are applied correctly
11191125 styles <- gt ::: dt_styles_get(styled_table )
1120- expect_equal(nrow(styles ), 3 ) # Should target 3 rows
1121- expect_equal(unique(styles $ rownum ), c(1 , 3 , 5 ))
1122- expect_equal(unique(styles $ locname ), " stub" )
1126+ # With multi-column stub, styles should be applied to all 3 columns for each of 3 rows
1127+ expect_equal(nrow(styles ), 9 ) # 3 rows * 3 columns
1128+ expect_setequal(unique(styles $ rownum ), c(1 , 3 , 5 ))
1129+ expect_equal(unique(styles $ locname ), " stub_column" )
1130+ expect_setequal(unique(styles $ colname ), c(" mfr" , " model" , " trim" ))
1131+ })
1132+
1133+ test_that(" cells_stub(columns = NULL) targets all stub columns" , {
1134+
1135+ # `cells_stub(columns = NULL)` should target all stub columns in a multi-column stub
1136+ # Test with explicit columns = NULL
1137+ styled_table_null <-
1138+ exibble | >
1139+ gt(rowname_col = c(" group" , " char" )) | >
1140+ tab_style(
1141+ style = cell_text(align = " right" ),
1142+ locations = cells_stub(columns = NULL )
1143+ )
1144+
1145+ # Check that styles are applied to both stub columns
1146+ styles_null <- gt ::: dt_styles_get(styled_table_null )
1147+ expect_equal(unique(styles_null $ locname ), " stub_column" )
1148+ expect_setequal(unique(styles_null $ colname ), c(" group" , " char" ))
1149+ expect_equal(nrow(styles_null ), 16 ) # 8 rows * 2 columns
1150+
1151+ # Test with default (no columns argument)
1152+ styled_table_default <-
1153+ exibble | >
1154+ gt(rowname_col = c(" group" , " char" )) | >
1155+ tab_style(
1156+ style = cell_fill(color = " steelblue" ),
1157+ locations = cells_stub()
1158+ )
1159+
1160+ # Check that styles are applied to both stub columns
1161+ styles_default <- gt ::: dt_styles_get(styled_table_default )
1162+ expect_equal(unique(styles_default $ locname ), " stub_column" )
1163+ expect_setequal(unique(styles_default $ colname ), c(" group" , " char" ))
1164+ expect_equal(nrow(styles_default ), 16 ) # 8 rows * 2 columns
1165+
1166+ # Check that rendered HTML contains the styles for both columns
1167+ html_output <- as_raw_html(styled_table_default )
1168+ # The style should be applied to multiple stub cells (not just the first column)
1169+ expect_true(grepl(" #4682B4" , html_output )) # steelblue
1170+
1171+ # Compare with single-column stub (backward compatibility)
1172+ styled_table_single <-
1173+ sza | >
1174+ dplyr :: filter(latitude == 20 & tst < = " 1000" ) | >
1175+ dplyr :: select(- latitude ) | >
1176+ dplyr :: filter(! is.na(sza )) | >
1177+ tidyr :: pivot_wider(
1178+ names_from = " tst" ,
1179+ values_from = sza ,
1180+ names_sort = TRUE
1181+ ) | >
1182+ gt(rowname_col = " month" ) | >
1183+ sub_missing(missing_text = " " ) | >
1184+ tab_style(
1185+ style = list (
1186+ cell_fill(color = " darkblue" ),
1187+ cell_text(color = " white" )
1188+ ),
1189+ locations = cells_stub()
1190+ )
1191+
1192+ # Single-column stub should use "stub" locname for backward compatibility
1193+ styles_single <- gt ::: dt_styles_get(styled_table_single )
1194+ expect_equal(unique(styles_single $ locname ), " stub" )
1195+ })
1196+
1197+ test_that(" cells_stub() footnotes target all stub columns in multi-column stub" , {
1198+
1199+ # cells_stub() should apply footnotes to all stub columns in a multi-column stub
1200+ footnoted_table <-
1201+ head(exibble , 4 ) | >
1202+ gt(rowname_col = c(" group" , " char" )) | >
1203+ tab_footnote(
1204+ footnote = " Test" ,
1205+ locations = cells_stub()
1206+ )
1207+
1208+ # Check that footnotes are applied to both stub columns
1209+ footnotes <- gt ::: dt_footnotes_get(footnoted_table )
1210+ expect_setequal(unique(footnotes $ colname ), c(" group" , " char" ))
1211+ expect_equal(nrow(footnotes ), 8 )
1212+ # 4 rows * 2 columns
1213+
1214+ # Check that rendered HTML contains footnote marks in all stub cells
1215+ html_output <- as_raw_html(footnoted_table )
1216+
1217+ # The footnote mark "1" should appear multiple times (once per stub cell)
1218+ # Count occurrences of the footnote mark class in stub cells
1219+ expect_true(grepl(" Test" , html_output )) # Footnote text is present
11231220})
11241221
11251222test_that(" Enhanced stub targeting: error handling for invalid targets" , {
0 commit comments