Skip to content

Commit fd35115

Browse files
committed
refactor(tests): update integration test setup
- Create helper functions (`load_*()`) to load or create data for a FIMS model run, or run a FIMS model with wrappers to save the fit output. These functions check if the corresponding `.RDS` file exists; if not, they generate the data or run the model and save the output to an `.RDS` file. If the file exists, they read and return the object from the `.RDS` file. This ensures that test data is generated only once and is available for subsequent test runs, speeding up the process. - Add error handling (e.g., `tryCatch()`) in data loading functions to provide clearer messages when file operations fail. - Update README to document new helper functions for loading data and running FIMS with wrappers. - Rename `test-integration-caa-mle.R` to `test-integration-caa-mle-without-wrappers.R` so it can be filtered when running tests (`devtools::test(filter = "xxx")`), speeding up single-test execution. - Update snapshot tests outputs from `.md` files to `.csv` files. - Replace nan with -999 in JSON files. Thanks to @msupernaw for the fix to issue #940.
1 parent 4f18d74 commit fd35115

30 files changed

Lines changed: 24943 additions & 5318 deletions

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"updatePackages": true
1919
},
2020
"ghcr.io/rocker-org/devcontainer-features/r-packages:1": {
21-
"packages": "covr,dplyr,devtools,ggplot2,jsonlite,methods,Rcpp,RcppEigen,scales,snowfall,TMB,tibble,tidyr,usethis,spelling",
21+
"packages": "covr,dplyr,devtools,diffviewer,ggplot2,jsonlite,methods,Rcpp,RcppEigen,scales,snowfall,TMB,tibble,tidyr,usethis,spelling",
2222
"installSystemRequirements": true
2323
},
2424
// option to run rstudio. you can type rserver into the command line to

inst/WORDLIST

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ DWORD
277277
dynam
278278
elif
279279
ELT
280+
emph
280281
emplace
281282
emptyDoubleLogistic
282283
emptyLogistic

inst/include/utilities/fims_json.hpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ enum JsonValueType {
4949
*/
5050
class JsonValue {
5151
public:
52+
/** Represents the string representation of NaN in JSON. */
53+
static std::string NaN_Representation;
54+
5255
/** Default constructor, initializes to Null value. */
5356
JsonValue() : type(JsonValueType::Null) {}
5457

@@ -100,6 +103,9 @@ class JsonValue {
100103
JsonArray array; /**< JSON array. */
101104
};
102105

106+
/**< Default representation for NaN in JSON. */
107+
std::string JsonValue::NaN_Representation = "999";
108+
103109
/**
104110
* Parses JSON strings and generates JSON values.
105111
*/
@@ -181,8 +187,37 @@ class JsonParser {
181187
break;
182188
}
183189
}
190+
// Replace NaN with the specified representation
191+
JsonParser::replaceNaN(result);
184192
return result;
185193
}
194+
195+
/**
196+
* @brief Replace occurrences of "NaN" or "nan" in a string with the
197+
* specified representation.
198+
* @param s The string to modify.
199+
*/
200+
static void replaceNaN(std::string &s)
201+
{
202+
std::string target = "NaN";
203+
std::string replacement = JsonValue::NaN_Representation;
204+
size_t pos = 0;
205+
206+
while ((pos = s.find(target, pos)) != std::string::npos)
207+
{
208+
s.replace(pos, target.size(), replacement);
209+
pos += replacement.size(); // move past the replacement
210+
}
211+
212+
target = "nan";
213+
pos = 0;
214+
215+
while ((pos = s.find(target, pos)) != std::string::npos)
216+
{
217+
s.replace(pos, target.size(), replacement);
218+
pos += replacement.size(); // move past the replacement
219+
}
220+
}
186221

187222
private:
188223
/** Skip whitespace characters in the input string. */

tests/README.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,8 @@ Prepare the test data in the new file or in a separate file if you plan on reusi
1717
- In-line test data: make the data directly in the new test file within the `setup` section.
1818
- C++ reusable test data: create a fixture file, e.g., `tests/gtest/test_XXX_test_fixture.hpp`, to prepare reusable unit-test data, or create an integration file, e.g., `tests/gtest/integration/XXX.hpp`, to set up integration-test data for C++ tests.
1919
- If you used a test fixture from GoogleTest to use the same data configuration for multiple tests, `TearDown()` can be used to clean up the test and then the test fixture will be deleted. See [GoogleTest user's guide](https://google.github.io/googletest/primer.html#same-data-multiple-tests) for more details.
20-
- R reusable test data: add code to the `prepare_test_data()` function in [`tests/testthat/helper-integration-tests-setup-run.R`](https://github.com/NOAA-FIMS/FIMS/blob/main/tests/testthat/helper-integration-tests-setup-run.R), including code to save the new data object, e.g., `base::saveRDS(object, file = testthat::test_path("fixtures", "data_name.RDS"))`, and call `prepare_test_data()` in the `setup` section of the new test file to load the data using
21-
```r
22-
if (!file.exists(test_path("fixtures", "data_name.RDS"))) {
23-
prepare_test_data()
24-
}
25-
```
26-
- Use pre-existing integration data, e.g., `tests/testthat/fixtures/integration_test_data_components.RData` and `tests/testthat/fixtures/integration_test_data.RData`, by loading them within the `setup` section, e.g., `load(test_path("fixtures", "integration_test_data.RData"))` or within `prepare_test_data()`, where these data objects can be updated by running `R/data1.R`.
20+
- R reusable test data: add code to the [`tests/testthat/helper-integration-tests-setup-wrappers.R`](https://github.com/NOAA-FIMS/FIMS/blob/main/tests/testthat/helper-integration-tests-setup-wrappers.R) file, including code to save a new data or fit object for tests that use wrapper functions, e.g., `base::saveRDS(object, file = testthat::test_path("fixtures", "data_name.RDS"))` or `base::saveRDS(object, file = testthat::test_path("fixtures", "fit_name.RDS"))`, and call `load_fit_*()` in the `setup` section of the new test file to load the data.
21+
- Use pre-existing integration data, e.g., `tests/testthat/fixtures/integration_test_data_components.RData` and `tests/testthat/fixtures/integration_test_data.RData`, by loading them within the `setup` section, e.g., `load(test_path("fixtures", "integration_test_data.RData"))`, where these data objects can be updated by running `R/data1.R`.
2722

2823
### :pencil: Edit the code in the new test file
2924

@@ -33,8 +28,8 @@ Follow the structure of the new test file to write appropriate correctness, edge
3328

3429
The following :hammer: helper functions are available to assist with writing integration tests in R.
3530

36-
- `setup_and_run_FIMS_without_wrappers()`: Set up a FIMS model without wrappers (in [`tests/testthat/helper-integration-tests-setup-run.R`](https://github.com/NOAA-FIMS/FIMS/blob/main/tests/testthat/helper-integration-tests-setup-run.R)).
37-
- `setup_and_run_FIMS_with_wrappers()`: Set up a FIMS model with wrappers (in [`tests/testthat/helper-integration-tests-setup-run.R`](https://github.com/NOAA-FIMS/FIMS/blob/main/tests/testthat/helper-integration-tests-setup-run.R)).
31+
- `setup_and_run_FIMS_without_wrappers()`: Set up a FIMS model without wrappers (in [`tests/testthat/helper-integration-tests-setup-without-wrappers.R`](https://github.com/NOAA-FIMS/FIMS/blob/main/tests/testthat/helper-integration-tests-setup-without-wrappers.R)).
32+
- `load_*()`: Load or create data for a FIMS model run, or run a FIMS model with wrappers to save the fit output (in [tests/testthat/helper-integration-tests-setup-wrappers.R](https://github.com/NOAA-FIMS/FIMS/blob/main/tests/testthat/helper-integration-tests-setup-wrappers.R)).
3833
- `verify_fims_deterministic()`: Compare the model output from a FIMS deterministic run against the expected "truth" from an operating model (in [`tests/testthat/helper-integration-tests-validation.R`](https://github.com/NOAA-FIMS/FIMS/blob/main/tests/testthat/helper-integration-tests-validation.R)).
3934
- `verify_fims_nll()`: Compare the negative log likelihood (NLL) from a FIMS model against the expected NLL calculated from an operating model (in [`tests/testthat/helper-integration-tests-validation.R`](https://github.com/NOAA-FIMS/FIMS/blob/main/tests/testthat/helper-integration-tests-validation.R)).
4035
- `validate_fims()`: Compare the output from a FIMS model where parameters are estimated against the expected "truth" from an operating model (in [`tests/testthat/helper-integration-tests-validation.R`](https://github.com/NOAA-FIMS/FIMS/blob/main/tests/testthat/helper-integration-tests-validation.R)).

0 commit comments

Comments
 (0)