Skip to content

Adds validate_input() -- previously named as "picks"#1642

Merged
gogonzo merged 41 commits into
mainfrom
redesign_extraction@main
May 19, 2026
Merged

Adds validate_input() -- previously named as "picks"#1642
gogonzo merged 41 commits into
mainfrom
redesign_extraction@main

Conversation

@gogonzo

@gogonzo gogonzo commented Oct 30, 2025

Copy link
Copy Markdown
Contributor

Closes insightsengineering/NEST-roadmap#36

Check also with:

Introduces validate_input as an alternative to shinyvalidate package. Function is easier to handle than shinyvalidate, as one can use validate_input() in reactive and display-validation-error on the input and throw shiny-validate-error in the same time. See tmg PR to see how it works

@gogonzo gogonzo added the core label Oct 30, 2025
@gogonzo gogonzo changed the title Redesign extraction@main picks Oct 30, 2025
@github-actions

github-actions Bot commented Oct 30, 2025

Copy link
Copy Markdown
Contributor

badge

Code Coverage Summary

Filename                          Stmts    Miss  Cover    Missing
------------------------------  -------  ------  -------  -----------------------------------------------------------------------------------------------------
R/after.R                            59      21  64.41%   42-52, 64, 69, 77-79, 81-89, 100, 104-105
R/checkmate.R                        24       0  100.00%
R/decorators-helpers.R               59       1  98.31%   97
R/dummy_functions.R                  61       2  96.72%   54, 56
R/include_css_js.R                   11       0  100.00%
R/init.R                            136       0  100.00%
R/module_bookmark_manager.R          99      54  45.45%   78-133
R/module_data_summary.R             177       8  95.48%   40, 50, 205, 236-240
R/module_filter_data.R               64       0  100.00%
R/module_filter_manager.R           210       7  96.67%   119-120, 316, 343, 355, 362-363
R/module_nested_tabs.R              411      42  89.78%   120, 178-183, 211, 315-330, 350-354, 409, 527-530, 534-537, 541-544
R/module_session_info.R              18       0  100.00%
R/module_snapshot_manager.R         276       9  96.74%   315-319, 386, 389-391
R/module_source_code.R               69       0  100.00%
R/module_teal_lockfile.R            131      53  59.54%   45-57, 60-62, 76, 86-88, 100-102, 110-119, 122, 124, 126-127, 142-146, 161-162, 177-186
R/module_teal_reporter.R            122       9  92.62%   60, 77-78, 81, 98, 128, 142, 144, 158
R/module_teal.R                     304      26  91.45%   130, 179, 235, 265-285, 315-316
R/module_transform_data.R           164      25  84.76%   77-81, 85-89, 106, 112, 119-120, 134-138, 188, 273-277
R/module_validate_error.R            73       0  100.00%
R/modules.R                         345      50  85.51%   170-174, 229-232, 332, 339, 353, 472, 570-576, 706-712, 725-733, 748-763, 796, 808-816
R/reporter_previewer_module.R        41      12  70.73%   41, 45, 68-85
R/teal_data_module-eval_code.R       23       0  100.00%
R/teal_data_module-within.R           7       0  100.00%
R/teal_data_module.R                 23       0  100.00%
R/teal_data_utils.R                  49       0  100.00%
R/teal_modifiers.R                   57       0  100.00%
R/teal_slices-store.R                29       0  100.00%
R/teal_slices.R                      48       2  95.83%   153-154
R/teal_transform_module.R            45       0  100.00%
R/TealAppDriver.R                   363     255  29.75%   68-73, 125, 133-162, 193-202, 212, 227-275, 300-575, 603-628, 683, 685-688, 707-721, 738-739, 750-767
R/utils.R                           291      49  83.16%   38, 408-457, 545-554
R/validate_inputs.R                  57       0  100.00%
R/validations.R                      58       0  100.00%
R/zzz.R                              23       1  95.65%   25
TOTAL                              3927     626  84.06%

Diff against main

Filename                       Stmts    Miss  Cover
---------------------------  -------  ------  --------
R/module_nested_tabs.R             0     -12  +2.92%
R/module_snapshot_manager.R       +4       0  +0.05%
R/module_teal.R                   +1      -2  +0.69%
R/TealAppDriver.R                 +8    -100  +29.75%
R/validate_inputs.R              +25       0  +100.00%
R/zzz.R                           +3      +1  -4.35%
TOTAL                            +41    -113  +3.08%

Results for commit: 830613b

Minimum allowed coverage is 80%

♻️ This comment has been updated with latest results

@github-actions

github-actions Bot commented Oct 30, 2025

Copy link
Copy Markdown
Contributor

Unit Tests Summary

  1 files   36 suites   4m 40s ⏱️
485 tests 417 ✅ 68 💤 0 ❌
752 runs  684 ✅ 68 💤 0 ❌

Results for commit 830613b.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 30, 2025

Copy link
Copy Markdown
Contributor

Unit Test Performance Difference

Test Suite $Status$ Time on main $±Time$ $±Tests$ $±Skipped$ $±Failures$ $±Errors$
module_session_info 💔 $18.26$ $+136.24$ $0$ $0$ $0$ $0$
module_teal 💔 $109.36$ $+3.32$ $+2$ $0$ $0$ $0$
shinytest2-disable_report 👶 $+0.34$ $+4$ $+4$ $0$ $0$
shinytest2-disable_src 👶 $+0.17$ $+2$ $+2$ $0$ $0$
shinytest2-show-rcode 👶 $+0.25$ $+3$ $+3$ $0$ $0$
shinytest2-teal_modifiers 👶 $+0.47$ $+7$ $+7$ $0$ $0$
shinytest2-validate_input 👶 $+0.41$ $+5$ $+5$ $0$ $0$
validate_input 👶 $+0.23$ $+20$ $0$ $0$ $0$
Additional test case details
Test Suite $Status$ Time on main $±Time$ Test Case
module_session_info 💔 $18.13$ $+136.36$ srv_session_info_lockfile_creation_process_is_invoked_for_teal.lockfile.mode_enabled_and_snapshot_is_copied_to_teal_app.lock_and_removed_after_session_ended
module_teal 👶 $+0.05$ srv_teal_snapshot_manager_is_disabled_by_teal.snapshot_manager.enable_FALSE
shinytest2-decorators 💀 $0.03$ $-0.03$ unnamed
shinytest2-disable_report 👶 $+0.10$ Add_to_report_button_is_not_disabled_by_default.
shinytest2-disable_report 👶 $+0.08$ Report_button_is_active_on_a_nested_module_by_default
shinytest2-disable_report 👶 $+0.08$ Report_button_is_disabled_on_a_module_changed_by_disable_report_
shinytest2-disable_report 👶 $+0.08$ Report_button_is_disabled_on_nested_modules_changed_by_disable_report_
shinytest2-disable_src 👶 $+0.08$ Show_R_Code_button_is_disabled_on_a_module
shinytest2-disable_src 👶 $+0.08$ Show_R_Code_is_disabled_on_nested_modules_changed_with_disable_src
shinytest2-reporter 💀 $0.01$ $-0.01$ unnamed
shinytest2-show-rcode 👶 $+0.08$ e2e_Module_with_Show_R_Code_has_code
shinytest2-show-rcode 👶 $+0.08$ e2e_Module_with_Show_R_Code_has_modal_with_two_dismiss_and_two_copy_to_clipboard_buttons
shinytest2-show-rcode 👶 $+0.09$ e2e_Module_with_Show_R_Code_initializes_with_visible_button
shinytest2-teal_data_module 💀 $0.01$ $-0.01$ unnamed
shinytest2-teal_data_module 👶 $+0.06$ e2e_teal_data_module_auto_closes_modal_when_once_FALSE_and_data_is_ready_no_submit_
shinytest2-teal_data_module 💀 $0.01$ $-0.01$ e2e_teal_data_module_doesn_t_auto_close_when_once_FALSE_and_data_is_ready_no_submit_
shinytest2-teal_data_module 💀 $0.01$ $-0.01$ e2e_teal_data_module_modal_close_button_is_enabled_from_disabled_when_data_is_ready
shinytest2-teal_data_module 👶 $+0.06$ e2e_teal_data_module_modal_stays_visible_on_startup_when_once_FALSE_and_need_submit_TRUE_
shinytest2-teal_modifiers 👶 $+0.06$ e2e_add_landing_modal_displays_landing_modal_on_app_startup
shinytest2-teal_modifiers 👶 $+0.08$ e2e_add_landing_modal_modal_can_be_dismissed
shinytest2-teal_modifiers 👶 $+0.06$ e2e_combined_modifiers_displays_all_customizations_when_chained_together
shinytest2-teal_modifiers 👶 $+0.06$ e2e_modify_footer_displays_custom_footer_in_the_app
shinytest2-teal_modifiers 👶 $+0.06$ e2e_modify_header_displays_custom_header_in_the_app
shinytest2-teal_modifiers 👶 $+0.06$ e2e_modify_title_sets_custom_title_in_the_page_title_head_title_displays_custom_favicon_in_the_app
shinytest2-teal_modifiers 👶 $+0.07$ e2e_modify_title_sets_custom_title_in_the_page_title_head_title_displays_custom_title_in_the_app
shinytest2-validate_input 👶 $+0.09$ e2e_validate_input_displays_validation_message_when_input_is_invalid_no_message_when_valid
shinytest2-validate_input 👶 $+0.08$ e2e_validate_input_validates_generic_fields
shinytest2-validate_input 👶 $+0.08$ e2e_validate_input_validates_many_inputs_and_linked_output_when_they_return_invalid_value
shinytest2-validate_input 👶 $+0.08$ validate_input_shinytest2_sequence_of_errors_with_parallel_validation
shinytest2-validate_input 👶 $+0.09$ validate_input_shinytest2_stale_messages_are_not_shown
validate_input 👶 $+0.02$ validate_input_condition_has_to_be_a_logical_1_or_function_with_nargs_length_inputId_
validate_input 👶 $+0.02$ validate_input_inputId_has_to_be_a_character_1_
validate_input 👶 $+0.01$ validate_input_message_has_to_be_a_character_1_
validate_input 👶 $+0.01$ validate_input_returns_NULL_when_condition_is_TRUE
validate_input 👶 $+0.04$ validate_input_throws_message_as_shiny.silent.error_when_condition_FALSE_
validate_input 👶 $+0.01$ validate_input_with_multiple_inputIds_doesn_t_throw_shiny.silent.error_if_all_inputs_are_valid
validate_input 👶 $+0.02$ validate_input_with_multiple_inputIds_throws_shiny.silent.error_when_any_input_is_invalid
validate_input 👶 $+0.02$ validate_input_works_with_function_condition_that_returns_FALSE_for_input_with_inputId_
validate_input 👶 $+0.01$ validate_input_works_with_function_condition_that_returns_TRUE_for_input_with_inputId_
validate_input 👶 $+0.02$ validate_with_multiple_need_input_1_validation
validate_input 👶 $+0.04$ validate_with_multiple_need_input_2_validations

Results for commit 1d5804a

♻️ This comment has been updated with latest results.

@m7pr

m7pr commented Nov 3, 2025

Copy link
Copy Markdown
Collaborator

8 failed tests in R CMD CHECK

[ FAIL 8 | WARN 3 | SKIP 56 | PASS 482 ]
 Error in `testthat::test_that("e2e: validate_input validates dateRangeInput")`: argument "code" is missing, with no default

does validate_input needs some default value?

https://github.com/insightsengineering/teal/actions/runs/19031248490/job/54345566087?pr=1642#step:44:618

@m7pr

m7pr commented Nov 3, 2025

Copy link
Copy Markdown
Collaborator

@gogonzo

gogonzo commented Nov 3, 2025

Copy link
Copy Markdown
Contributor Author

Ah ok, those are those 8 tests that do not have any body yet

https://github.com/insightsengineering/teal/pull/1642/files#diff-1701b89782ded4509f0394359d889ddd3b2ffdf2a3532c898cf75ed77dfe3201R117-R124

Yup, this is for the first volunteer

@averissimo averissimo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I've added missing tests with shinytest2

Pending CI run, but this feature has been heavily tested with tmg and tmc development

Comment thread tests/testthat/test-shinytest2-validate_input.R Outdated
@averissimo averissimo changed the title picks Adds validate_input() -- previously named as "picks" May 11, 2026
Comment thread tests/testthat/test-shinytest2-validate_input.R Outdated
Comment thread tests/testthat/test-shinytest2-validate_input.R Outdated
Comment thread tests/testthat/test-shinytest2-validate_input.R Outdated
Comment thread tests/testthat/test-shinytest2-validate_input.R
averissimo and others added 8 commits May 14, 2026 12:54
# Pull Request

<!--- Replace `#nnn` with your issue link for reference. -->

### Changes description

- [x] Resets message under input when it's changed to prevent outdated
errors
  - See screencast on first comment
- [x] ~Allows for multiple validation using `add` parameter _(instead of
1 by 1)_~
- ~Similar implementation to `checkmate::assert_***(..., add =
collection)`~
  - Needs alternate solution
- [x] Exports `validate_input` function
- [x] Fixes initialization problem


### Example app with some errors:

- Validate `picks` with non-empty
- Both inputs cannot choose the same letter

```r
#
pkgload::load_all("../teal.picks")
pkgload::load_all("../teal")

data <- within(teal_data(), letters <- data.frame(letter = head(LETTERS)))

picks_letters <- picks(
  datasets("letters", "letters"),
  variables("letter", "letter"),
  values(selected = NULL)
)

my_module <- module(
  label = "My Module",
  datanames = NULL,
  ui = function(id) {
    ns <- NS(id)
    teal.widgets::standard_layout(
      encoding = tagList(
        tags$h3("Letters"),
        teal.picks::picks_ui(ns("letters"), picks_letters),
        tags$h3("Letters2"),
        checkboxGroupInput(ns("letters2"), "Select letters:", choices = head(LETTERS), inline = TRUE),
      ),
      output = tagList(
        tags$h3("Sample plot"),
        plotOutput(ns("plot"))
      )
    )
  },
  server = function(id, data) {
    moduleServer(id, function(input, output, session) {
      selectors <- list(letters = picks_letters)
      anl_inputs <- picks_srv(picks = selectors, data = data)

      validated_q <- reactive({
        validate_input(
          "letters-values-selected",
          condition = length(anl_inputs$letters()$values$selected) > 0,
          message = "Select at least one letter."
        )
        validate_input(
          c("letters-values-selected", "letters2"),
          condition = all(!anl_inputs$letters()$values$selected %in% input$letters2),
          message = "Letters in the first group should not be in the second group."
        )
        data()
      })

      output$plot <- renderPlot({
        letters <- validated_q()$letters$letter
        tab <- rbind(
          Group1 = as.integer(letters %in% anl_inputs$letters()$values$selected),
          Group2 = as.integer(letters %in% input$letters2)
        )
        colnames(tab) <- letters
        barplot(
          tab,
          beside = TRUE, legend.text = TRUE, main = "Selected letters per group",
          col = c("steelblue", "tomato")
        )
      })
    })
  }
)

init(data = data, modules = my_module) |> shiny::runApp()
```

---------

Signed-off-by: André Veríssimo <211358+averissimo@users.noreply.github.com>
Co-authored-by: Dawid Kaledkowski <dawid.kaledkowski@gmail.com>
@gogonzo gogonzo enabled auto-merge (squash) May 19, 2026 08:59
@gogonzo gogonzo merged commit b88af7b into main May 19, 2026
28 checks passed
@gogonzo gogonzo deleted the redesign_extraction@main branch May 19, 2026 09:03
@github-actions github-actions Bot locked and limited conversation to collaborators May 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Design data extract and data merge

5 participants