Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
87 lines (56 sloc) 2.99 KB
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# reactor
<!-- badges: start -->
[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental)
<!-- badges: end -->
When developing Shiny apps there is a lot of reactivity problems that can arise when one `reactive` or `observe` element triggers other elements. In some cases these can create cascading reactivity (the horror). The goal of `reactor` is to diagnose these reactivity problems and then plan unit tests to avert them during development to make development less painful.
## Installation
And the development version from [GitHub](https://github.com/) with:
``` r
# install.packages("remotes")
remotes::install_github("yonicd/reactor")
```
## Example
This is a basic example which shows you how to solve a common problem:
```{r example}
library(reactor)
```
## Simple App
### Good App
In this app the plot is only rendered when the `input$n` is updated.
- We expect the reactive element that creates the plot to be invalidated only once.
![](https://github.com/yonicd/reactor/raw/media/good_app.gif)
```{r,echo = FALSE}
details::details('inst/examples/good_app.R',summary = 'Good App Script')
```
### Bad App
In this app the plot is rendered every time reactive elements in `input` are invalidated.
- This kind of setup can cause a lot of unwanted reactivity in larger apps with many elements.
- We expect the reactive element that creates the plot to be invalidated more than once.
- Notice how on the app initialization the chunk is rendered twice.
![](https://github.com/yonicd/reactor/raw/media/bad_app.gif)
```{r,echo = FALSE}
details::details('inst/examples/bad_app.R',summary = 'Bad App Script')
```
### Testing
Using `reactor` we can test this expectation!
If we run the test on the `good app` the test will pass and if we run it on the `bad app` then it will fail signaling a problem.
To run a test you can use standard `testthat` functions like `testthat::test_dir()`, or you can use a `reactor` function `reactor::test_app()`.
To use `test_app` just name the test file `reactor-*.R` instead of `test-*.R` this will have two benefits.
1. These tests need an interactive environment, multiple cores and an internet connection. Most CI's do not have this and `covr` will not pass the tests. This allows you to run the tests using `test_dir` which does have the necessary characteristics to run the tests.
2. Allows the app tests to be isolated from the other unit tests thus allowing for `covr` and `testthat` to run on R CMD CHECK without needing to add `skip_*` into the app test files.
![](https://github.com/yonicd/reactor/raw/media/example.gif)
```{r,echo=FALSE}
details::details('tests/testthat/reactor-reactivity.R',summary = 'Reactivity Test Script')
```
You can’t perform that action at this time.