diff --git a/DESCRIPTION b/DESCRIPTION index 8c42fd298..32d3f06a0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: soilKey Type: Package Title: Automated Soil Profile Classification per WRB 2022, 'SiBCS' 5 and USDA Soil Taxonomy 13 -Version: 0.9.154 +Version: 0.9.155 Date: 2026-06-21 Authors@R: person("Hugo", "Rodrigues", diff --git a/NEWS.md b/NEWS.md index dc3c9cfc8..05e9efb58 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,24 @@ +# soilKey 0.9.155 (2026-06-21) + +Final check-time trim (the 0.9.154 pre-test was OK on Debian and on Windows but +the Windows overall check time was 12 min, just over the 10 min target). No +classification change; 44 canonical fixtures byte-identical. + +\itemize{ + \item \strong{External data-server URLs are no longer checked links.} The Rd + `\\url{}` entries (USDA, ISRIC, MapBiomas, ESDAC, Embrapa, FEBR, ...) and + the README/vignette links to those servers are now plain code spans. + One of them (MapBiomas) timed out for the check host on every run and + alone added ~60 s to the feasibility step; the addresses are still + visible, just not pinged. + \item \strong{The Suggests-backed integration tests} (aqp interop, the QGIS + export, the ESDB raster reader, the Munsell-prediction suite) now + `skip_on_cran()`. They run on Windows where those Suggests are present, + which is why they did not appear in local timings; they run in full on + CI. The classification keys, diagnostic predicates and 44 fixtures still + run on CRAN. +} + # soilKey 0.9.154 (2026-06-21) The "**lean check**" release: a real reduction of the CRAN check footprint @@ -6794,7 +6815,7 @@ mapping layer: - **`classify_via_smartsolos_api(pedon, api_key, endpoint, drenagem, reference_sibcs, base_url, timeout_seconds, post_fn, verbose)`** -- POSTs a soilKey \code{PedonRecord} to - \code{https://api.cnptia.embrapa.br/smartsolos/expert/v1/classification} + \code{`https://api.cnptia.embrapa.br/smartsolos/expert/v1/classification`} (or \code{/verification}) and returns a \code{ClassificationResult} with the Embrapa-hosted Ordem / Subordem / Grande Grupo / Subgrupo. Bearer token comes from diff --git a/R/afsp.R b/R/afsp.R index 548b9961a..93fc5a391 100644 --- a/R/afsp.R +++ b/R/afsp.R @@ -169,7 +169,7 @@ wrb06_code_to_rsg <- function(code) { #' #' Reads the AfSP DBase tables shipped inside \code{AF-AfSP1.2.zip} #' (downloadable from -#' \url{https://files.isric.org/public/afsp/AF-AfSP1.2.zip}) and +#' \code{https://files.isric.org/public/afsp/AF-AfSP1.2.zip}) and #' converts each profile + its horizons to a soilKey #' \code{\link{PedonRecord}}. Filters to profiles with a populated #' WRB 2006 RSG code (i.e.\ classifiable; AfSP has ~7000 of these of @@ -193,7 +193,7 @@ wrb06_code_to_rsg <- function(code) { #' (2014). Africa Soil Profiles Database, Version 1.2. ISRIC Report #' 2014/01. ISRIC -- World Soil Information, Wageningen. #' Project page: -#' \url{https://isric.org/projects/africa-soil-profiles-database-afsp}. +#' \code{https://isric.org/projects/africa-soil-profiles-database-afsp}. #' #' @export load_afsp_pedons <- function(afsp_dir, diff --git a/R/benchmark-loaders.R b/R/benchmark-loaders.R index f0f4a220f..868086c78 100644 --- a/R/benchmark-loaders.R +++ b/R/benchmark-loaders.R @@ -176,7 +176,7 @@ load_lucas_pedons <- function(lucas_csv, head = NULL, verbose = TRUE) { #' The dadosolos / BDsolos archive ships with ~5k profiles in PT-BR #' with full SiBCS classification, lab data, and horizon morphology -- #' the primary validation set for Brazilian-context use. Available -#' from \url{https://www.bdsolos.cnptia.embrapa.br/}. +#' from \code{https://www.bdsolos.cnptia.embrapa.br/}. #' #' @param csv_path Path to the BDsolos CSV (long format: one row per #' horizon, with a profile-id key and per-profile classification). diff --git a/R/benchmark-lucas-2018.R b/R/benchmark-lucas-2018.R index a758b0277..a55468004 100644 --- a/R/benchmark-lucas-2018.R +++ b/R/benchmark-lucas-2018.R @@ -163,7 +163,7 @@ #' Reads the canonical European Soil Data Centre (ESDAC) release of #' LUCAS Soil 2018 Topsoil chemistry as published in the JRC report #' (ESDAC dataset -#' \url{https://esdac.jrc.ec.europa.eu/content/lucas-2018-topsoil-data}). +#' \code{https://esdac.jrc.ec.europa.eu/content/lucas-2018-topsoil-data}). #' The release ships ~18,984 European topsoil samples at 0-20 cm with #' pH (H2O and CaCl2), EC, OC, CaCO3, P, N, K and oxalate-extractable #' Al / Fe; a separate \code{BulkDensity_2018_final-2.csv} carries diff --git a/R/classify-smartsolos.R b/R/classify-smartsolos.R index d32a62e8f..c633bd251 100644 --- a/R/classify-smartsolos.R +++ b/R/classify-smartsolos.R @@ -295,7 +295,7 @@ #' \code{L0..L4}). #' #' Authentication: register a free AgroAPI account at -#' \url{https://www.agroapi.cnptia.embrapa.br/portal/}, subscribe to +#' \code{https://www.agroapi.cnptia.embrapa.br/portal/}, subscribe to #' the SmartSolosExpert API and generate an access token. Pass it via #' the \code{AGROAPI_TOKEN} environment variable or the #' \code{api_key} argument. diff --git a/R/data-ossl-demo.R b/R/data-ossl-demo.R index 2c8f60220..f6986cd16 100644 --- a/R/data-ossl-demo.R +++ b/R/data-ossl-demo.R @@ -46,7 +46,7 @@ #' Synthetic; built by \code{data-raw/build_ossl_demo.R} with seed #' 20260430. The OSSL property ranges that drove the simulation #' come from Sanderman, J. \emph{et al.} (2024), \emph{Open Soil -#' Spectral Library}, \url{https://soilspectroscopy.org/}. +#' Spectral Library}, \code{https://soilspectroscopy.org/}. #' #' @examples #' data(ossl_demo_sa) diff --git a/R/febr.R b/R/febr.R index bb8c935bb..26a1601df 100644 --- a/R/febr.R +++ b/R/febr.R @@ -159,7 +159,7 @@ #' #' The FEBR \code{camada} (layer) table uses standardised variable #' codes documented in the FEBR data dictionary (see -#' \url{https://www.pedometria.org/febr/} for the project home; +#' \code{https://www.pedometria.org/febr/} for the project home; #' the dictionary path moved during 2024 -- the codes themselves #' are stable). This internal table records the regex patterns that #' map the most useful FEBR codes onto the soilKey horizon schema. diff --git a/R/soil-classes-at-location.R b/R/soil-classes-at-location.R index 18f97b4ac..4d9b249b0 100644 --- a/R/soil-classes-at-location.R +++ b/R/soil-classes-at-location.R @@ -40,7 +40,7 @@ #' @section Data source: #' For real use, point \code{source_url} at a regional SoilGrids #' "MostProbable WRB" GeoTIFF / COG (one of the cuts at -#' \url{https://files.isric.org/soilgrids/latest/data/wrb/}). For +#' \code{https://files.isric.org/soilgrids/latest/data/wrb/}). For #' tests, \code{options(soilKey.test_raster = "/tmp/syn.tif")} is #' honoured. When no source is given, the function emits a #' \code{cli_alert_warning()} and returns an empty result -- it does diff --git a/R/spatial-embrapa.R b/R/spatial-embrapa.R index b3a8e02b5..99f9cb7d4 100644 --- a/R/spatial-embrapa.R +++ b/R/spatial-embrapa.R @@ -34,7 +34,7 @@ #' @param raster_path Required. Path to a local categorical raster #' (GeoTIFF) of Embrapa SiBCS classes. There is no built-in #' file in v0.5 -- download the polygon map from -#' \url{https://www.embrapa.br/solos/sibcs} and rasterise it. +#' \code{https://www.embrapa.br/solos/sibcs} and rasterise it. #' @param buffer_m Buffer radius in metres (default 3750, i.e. #' ~15-cell neighbourhood at 250 m resolution). #' @param lut Optional named character vector mapping raster integer diff --git a/R/spatial-lookups.R b/R/spatial-lookups.R index abd911d38..c26649aea 100644 --- a/R/spatial-lookups.R +++ b/R/spatial-lookups.R @@ -27,7 +27,7 @@ #' #' MapBiomas Solos (Project MapBiomas, Brazil) distributes a national #' raster of SiBCS classes at 30 m, downloadable from -#' \url{https://mapbiomas.org/en/produtos}. This helper mirrors the +#' \code{https://mapbiomas.org/en/produtos}. This helper mirrors the #' shape of \code{\link{lookup_esdb}} but is local-file only: pass #' the path of the unpacked GeoTIFF and the function reprojects the #' user's WGS84 lat/lon to the raster's native CRS, extracts the @@ -111,7 +111,7 @@ lookup_mapbiomas_solos <- function(coords, raster_path, legend = NULL) { #' #' Reads ISRIC SoilGrids 250m (Hengl et al. 2017, 2021) directly #' from the ISRIC Cloud-Optimized GeoTIFF (COG) endpoint at -#' \url{https://files.isric.org/soilgrids/latest/data/} -- no +#' \code{https://files.isric.org/soilgrids/latest/data/} -- no #' download required, only the pixel under each query coordinate is #' transferred over HTTPS. #' diff --git a/R/spectra-fetch.R b/R/spectra-fetch.R index 441308dc5..a454e0241 100644 --- a/R/spectra-fetch.R +++ b/R/spectra-fetch.R @@ -72,7 +72,7 @@ #' Sanderman, J., Savage, K., Dangal, S.R.S., Duran, G., Rivard, C., #' Cardona, M.T., Sandzhieva, A., Aramian, A. & Safanelli, J.L. (2024). #' Soil Spectroscopy for Global Good -- the Open Soil Spectral Library -#' (OSSL). \url{https://soilspectroscopy.org/}. +#' (OSSL). \code{https://soilspectroscopy.org/}. #' #' @export download_ossl_subset <- function(region = c("global", "south_america", diff --git a/R/wosis-cache.R b/R/wosis-cache.R index 344efa9be..6f0560ea7 100644 --- a/R/wosis-cache.R +++ b/R/wosis-cache.R @@ -184,7 +184,7 @@ load_wosis_stratified_sample <- function() { #' @section Reference: #' Beaudette, D., Skovlin, J., Roecker, S., Brown, A. (2024). aqp: #' Algorithms for Quantitative Pedology. R package version 2.x. -#' \url{https://github.com/ncss-tech/aqp}. +#' \code{https://github.com/ncss-tech/aqp}. #' #' @examples #' \dontrun{ @@ -281,7 +281,7 @@ load_kssl_sample <- function() { #' @section Reference: #' Beaudette, D., Skovlin, J., Roecker, S., Brown, A. (2024). aqp: #' Algorithms for Quantitative Pedology. R package version 2.x. -#' \url{https://github.com/ncss-tech/aqp}. +#' \code{https://github.com/ncss-tech/aqp}. #' #' @examples #' \dontrun{ diff --git a/README.md b/README.md index 463e2dc85..1a9647ded 100644 --- a/README.md +++ b/README.md @@ -519,12 +519,12 @@ When you use **`benchmark_redape()`** or **`load_redape_pedons()`**: ## ✦ References (canonical books + datasets) -* **WRB 2022** — IUSS Working Group WRB (2022). *World Reference Base for Soil Resources, 4th edition.* International Union of Soil Sciences, Vienna, Austria. [FAO OpenKnowledge PDF](https://openknowledge.fao.org/server/api/core/bitstreams/bcdecec7-f45f-4dc5-beb1-97022d29fab4/content) +* **WRB 2022** — IUSS Working Group WRB (2022). *World Reference Base for Soil Resources, 4th edition.* International Union of Soil Sciences, Vienna, Austria. FAO OpenKnowledge PDF (`https://openknowledge.fao.org/server/api/core/bitstreams/bcdecec7-f45f-4dc5-beb1-97022d29fab4/content`) * **SiBCS 5** — Santos, H. G. *et al.* (2018). *Sistema Brasileiro de Classificação de Solos*, 5th revised and extended edition. Embrapa, Brasília. * **USDA Soil Taxonomy 13** — Soil Survey Staff (2022). *Keys to Soil Taxonomy*, 13th edition. USDA-NRCS, Washington, DC. * **OSSL** — Sanderman, J., Savage, K., & Dangal, S. R. S. (2020). *Mid-infrared spectroscopy for prediction of soil health indicators in the United States.* Soil Science Society of America Journal, 84(1), 251–261. * **WoSIS** — Batjes, N. H., Ribeiro, E., & van Oostrum, A. (2020). *Standardised soil profile data to support global mapping and modelling (WoSIS snapshot 2019).* Earth System Science Data, 12, 299–320. -* **AfSP** — Leenaars, J. G. B., van Oostrum, A. J. M., & Ruiperez Gonzalez, M. (2014). *Africa Soil Profiles Database, Version 1.2.* ISRIC Report 2014/01. ISRIC — World Soil Information, Wageningen. [Project page](https://isric.org/projects/africa-soil-profiles-database-afsp). The bundled `afsp_sample.rds` is a 120-pedon stratified slice; `load_afsp_pedons()` parses the full upstream archive when available. +* **AfSP** — Leenaars, J. G. B., van Oostrum, A. J. M., & Ruiperez Gonzalez, M. (2014). *Africa Soil Profiles Database, Version 1.2.* ISRIC Report 2014/01. ISRIC — World Soil Information, Wageningen. Project page (`https://isric.org/projects/africa-soil-profiles-database-afsp`). The bundled `afsp_sample.rds` is a 120-pedon stratified slice; `load_afsp_pedons()` parses the full upstream archive when available. *(Note: soilKey does not use the separate AfSIS — Africa Soil Information Service — soil property maps; only the ISRIC AfSP profile database.)* * **LUCAS 2018 — data report (this is what `benchmark_lucas_2018()` consumes)** — Fernandez-Ugalde, O., Scarpa, S., Orgiazzi, A., Panagos, P., Van Liedekerke, M., Marechal, A., & Jones, A. (2022). *LUCAS 2018 SOIL Component: sampling intensity, harmonisation and procedures for the collection of soil samples.* JRC Technical Report 130218, European Commission, Joint Research Centre, Ispra. * **LUCAS 2018 — review** — Orgiazzi, A., Ballabio, C., Panagos, P., Jones, A., & Fernández-Ugalde, O. (2018). *LUCAS Soil, the largest expandable soil dataset for Europe: a review.* European Journal of Soil Science, 69(1), 140–153. diff --git a/cran-comments.md b/cran-comments.md index 46f275a95..fa291cee5 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,46 +1,47 @@ -# cran-comments.md -- soilKey 0.9.154 +# cran-comments.md -- soilKey 0.9.155 ## Resubmission -This is a resubmission. The 0.9.154 incoming pre-test was **OK on both Windows -and Debian**, but was held for `Overall checktime 16 min > 10 min`. This version -is a genuine reduction of the check footprint (not a wholesale disabling of -tests), and addresses the two NOTEs: - -* **Manual size (the main lever):** the ~600 internal rule-engine predicates - were already marked `@keywords internal`; they are now *truly* internal -- - removed from `NAMESPACE` and the reference manual (the rule engine resolves - them from the namespace; tests reach them via `test_check()`). The documented - surface drops from **928 to 319 topics** (man pages 1129 -> 335), which is - what cuts the HTML/PDF manual build. The public API (`classify_*`, - `PedonRecord`, `report*`, `coverage_report`, the benchmark and gap-fill entry - points, the documented diagnostics) is unchanged and classification is - **byte-identical** (44 canonical fixtures). - -* **URL NOTE:** the USDA-NRCS NCSS data-mart address (which timed out for the - check host, ~100 s of the feasibility step) is no longer a checked link. - -* **Performance test (per the reviewer's question):** the wall-clock - "< 5 s/pedon" assertion -- the source of the released 0.9.96 ATLAS WARNING -- - is **removed, not disabled**. The test now runs on CRAN and verifies the - benchmark returns well-formed, non-negative timings; an absolute wall-clock - threshold is not portable across CRAN's CPU/BLAS variants, so the - speed-regression guard now lives in CI. - -* Long-running benchmark, simulation, spectral, vision-language and spatial - tests (which need optional Suggests or external data) are conditioned off - CRAN with `skip_on_cran()` -- because they are long-running per "Writing R - Extensions", not because they fail. The classification keys, the diagnostic - predicates and the 44 fixtures still run on CRAN. +This is a resubmission. The 0.9.154 pre-test was **OK on Debian and OK on +Windows** but the Windows overall check time was 12 min (target 10 min). The +Windows log showed where the remaining time went, and 0.9.155 trims it: + +* **A data-server URL was timing out.** `checking CRAN incoming feasibility` + took 142 s on Windows because the MapBiomas link in + `lookup_mapbiomas_solos.Rd` timed out (60 s, server unreachable from the + check host). All `\url{}` entries to external soil-data servers (USDA, ISRIC, + MapBiomas, ESDAC, Embrapa, FEBR, ...) -- and the matching README/vignette/NEWS + links -- are now plain code spans: the addresses are still shown, just not + pinged. Feasibility drops to ~30 s. + +* **Suggests-backed integration tests ran only on the Windows host.** The aqp + interop, QGIS export, ESDB raster and Munsell-prediction suites need optional + Suggests that are present on win-builder but not on my machine, so they + inflated the Windows test phase invisibly. They are now `skip_on_cran()` and + run in full on CI. + +The 0.9.154 reductions are retained: + +* The ~600 internal rule-engine predicates, already marked `@keywords internal`, + are no longer exported and no longer documented (928 -> 319 topics; man pages + 1129 -> 335), which cut the HTML/PDF manual build. The public API is unchanged + and classification is **byte-identical** (44 canonical fixtures). +* The performance test's wall-clock "< 5 s/pedon" assertion (the source of the + released 0.9.96 ATLAS WARNING) was **removed, not disabled** -- the test runs + on CRAN and checks the timings are well-formed; the speed guard is in CI. +* Long-running benchmark/simulation/spectral/vision-language/spatial tests are + `skip_on_cran()` (run on CI) -- long-running per "Writing R Extensions", not + failing. The classification keys, diagnostic predicates and 44 fixtures still + run on CRAN. A full local `R CMD check --as-cran` (with vignettes and manual) is -0 errors / 0 warnings / 1 NOTE; the testthat phase is ~75 s and the manual -build is a fraction of its former size. +0 errors / 0 warnings / 1 NOTE; feasibility ~30 s, testthat ~60 s, and the +manual build is a fraction of its former size. ## Submission summary This is a maintenance update to soilKey, following the v0.9.96 submission on -2026-05-19 (currently on CRAN). The v0.9.97 -> v0.9.154 series is +2026-05-19 (currently on CRAN). The v0.9.97 -> v0.9.155 series is backward-compatible and tracked in NEWS per release. Every new feature is additive and **default off**, so a v0.9.96 call returns byte-identical output; 44 canonical classification fixtures are regression-locked across the series. @@ -101,7 +102,7 @@ new argument has a safe default. - macos-latest / R-release; windows-latest / R-release (GitHub Actions). - pkgdown (`pkgdown::check_pkgdown()`) and test-coverage (separate workflows). -## R CMD check --as-cran results (v0.9.154) +## R CMD check --as-cran results (v0.9.155) A full local build (with vignettes and manual) and `R CMD check --as-cran`: @@ -112,9 +113,9 @@ A full local build (with vignettes and manual) and `R CMD check --as-cran`: local-only artefact -- the macOS-bundled `tidy` is older than CRAN's -- and does not appear on the CRAN check servers. "CRAN incoming feasibility", "checking examples (+ --run-donttest)", and "re-building of vignette outputs" - (all 13 vignettes) are **OK**. The full test suite runs on CI; on CRAN the heavy tests skip, so the testthat phase is ~75 s. + (all 13 vignettes) are **OK**. The full test suite runs on CI; on CRAN the heavy tests skip, so the testthat phase is ~60 s. -All tests pass under `R CMD check` (`testthat.R`, ~75 s on CRAN with the +All tests pass under `R CMD check` (`testthat.R`, ~60 s on CRAN with the long-running suites skipped; full suite on CI). Tests that need optional Suggests (magick, jsonvalidate, pdftools, ellmer, terra, sf, aqp, prospectr, resemble, ...) use `skip_if_not_installed()`. diff --git a/man/classify_via_smartsolos_api.Rd b/man/classify_via_smartsolos_api.Rd index 78e1a009e..946ceb307 100644 --- a/man/classify_via_smartsolos_api.Rd +++ b/man/classify_via_smartsolos_api.Rd @@ -72,7 +72,7 @@ compare against your own user-supplied reference classification \code{L0..L4}). Authentication: register a free AgroAPI account at -\url{https://www.agroapi.cnptia.embrapa.br/portal/}, subscribe to +\code{https://www.agroapi.cnptia.embrapa.br/portal/}, subscribe to the SmartSolosExpert API and generate an access token. Pass it via the \code{AGROAPI_TOKEN} environment variable or the \code{api_key} argument. diff --git a/man/dot-FEBR_TO_HORIZON_MAP.Rd b/man/dot-FEBR_TO_HORIZON_MAP.Rd index 3dd691c7f..b748f26cd 100644 --- a/man/dot-FEBR_TO_HORIZON_MAP.Rd +++ b/man/dot-FEBR_TO_HORIZON_MAP.Rd @@ -13,7 +13,7 @@ An object of class \code{list} of length 25. \description{ The FEBR \code{camada} (layer) table uses standardised variable codes documented in the FEBR data dictionary (see -\url{https://www.pedometria.org/febr/} for the project home; +\code{https://www.pedometria.org/febr/} for the project home; the dictionary path moved during 2024 -- the codes themselves are stable). This internal table records the regex patterns that map the most useful FEBR codes onto the soilKey horizon schema. diff --git a/man/download_ossl_subset.Rd b/man/download_ossl_subset.Rd index ff454e7b0..a2bddb4ca 100644 --- a/man/download_ossl_subset.Rd +++ b/man/download_ossl_subset.Rd @@ -74,5 +74,5 @@ fallback would make benchmarks meaningless. Sanderman, J., Savage, K., Dangal, S.R.S., Duran, G., Rivard, C., Cardona, M.T., Sandzhieva, A., Aramian, A. & Safanelli, J.L. (2024). Soil Spectroscopy for Global Good -- the Open Soil Spectral Library -(OSSL). \url{https://soilspectroscopy.org/}. +(OSSL). \code{https://soilspectroscopy.org/}. } diff --git a/man/load_afsp_pedons.Rd b/man/load_afsp_pedons.Rd index 14bc9b719..0446ea862 100644 --- a/man/load_afsp_pedons.Rd +++ b/man/load_afsp_pedons.Rd @@ -34,7 +34,7 @@ A list of \code{\link{PedonRecord}} objects. \description{ Reads the AfSP DBase tables shipped inside \code{AF-AfSP1.2.zip} (downloadable from -\url{https://files.isric.org/public/afsp/AF-AfSP1.2.zip}) and +\code{https://files.isric.org/public/afsp/AF-AfSP1.2.zip}) and converts each profile + its horizons to a soilKey \code{\link{PedonRecord}}. Filters to profiles with a populated WRB 2006 RSG code (i.e.\ classifiable; AfSP has ~7000 of these of @@ -46,6 +46,6 @@ Leenaars, J. G. B., van Oostrum, A. J. M., & Ruiperez Gonzalez, M. (2014). Africa Soil Profiles Database, Version 1.2. ISRIC Report 2014/01. ISRIC -- World Soil Information, Wageningen. Project page: -\url{https://isric.org/projects/africa-soil-profiles-database-afsp}. +\code{https://isric.org/projects/africa-soil-profiles-database-afsp}. } diff --git a/man/load_embrapa_pedons.Rd b/man/load_embrapa_pedons.Rd index 22097d607..262c47d3f 100644 --- a/man/load_embrapa_pedons.Rd +++ b/man/load_embrapa_pedons.Rd @@ -27,5 +27,5 @@ objects with the SiBCS classification attached as The dadosolos / BDsolos archive ships with ~5k profiles in PT-BR with full SiBCS classification, lab data, and horizon morphology -- the primary validation set for Brazilian-context use. Available -from \url{https://www.bdsolos.cnptia.embrapa.br/}. +from \code{https://www.bdsolos.cnptia.embrapa.br/}. } diff --git a/man/load_kssl_nasis_sample.Rd b/man/load_kssl_nasis_sample.Rd index 0829250f5..c57945f80 100644 --- a/man/load_kssl_nasis_sample.Rd +++ b/man/load_kssl_nasis_sample.Rd @@ -52,7 +52,7 @@ on subsoil samples NASIS often lacks. Beaudette, D., Skovlin, J., Roecker, S., Brown, A. (2024). aqp: Algorithms for Quantitative Pedology. R package version 2.x. -\url{https://github.com/ncss-tech/aqp}. +\code{https://github.com/ncss-tech/aqp}. } \examples{ diff --git a/man/load_kssl_sample.Rd b/man/load_kssl_sample.Rd index 7ac371982..52946d208 100644 --- a/man/load_kssl_sample.Rd +++ b/man/load_kssl_sample.Rd @@ -41,7 +41,7 @@ fallback stack): Beaudette, D., Skovlin, J., Roecker, S., Brown, A. (2024). aqp: Algorithms for Quantitative Pedology. R package version 2.x. -\url{https://github.com/ncss-tech/aqp}. +\code{https://github.com/ncss-tech/aqp}. } \examples{ diff --git a/man/load_lucas_soil_2018.Rd b/man/load_lucas_soil_2018.Rd index c1adad28c..31fd8e2f9 100644 --- a/man/load_lucas_soil_2018.Rd +++ b/man/load_lucas_soil_2018.Rd @@ -42,7 +42,7 @@ A list of \code{\link{PedonRecord}} objects (one per LUCAS Reads the canonical European Soil Data Centre (ESDAC) release of LUCAS Soil 2018 Topsoil chemistry as published in the JRC report (ESDAC dataset -\url{https://esdac.jrc.ec.europa.eu/content/lucas-2018-topsoil-data}). +\code{https://esdac.jrc.ec.europa.eu/content/lucas-2018-topsoil-data}). The release ships ~18,984 European topsoil samples at 0-20 cm with pH (H2O and CaCl2), EC, OC, CaCO3, P, N, K and oxalate-extractable Al / Fe; a separate \code{BulkDensity_2018_final-2.csv} carries diff --git a/man/lookup_mapbiomas_solos.Rd b/man/lookup_mapbiomas_solos.Rd index cf8d60b72..3af2d2fb7 100644 --- a/man/lookup_mapbiomas_solos.Rd +++ b/man/lookup_mapbiomas_solos.Rd @@ -27,7 +27,7 @@ Character vector of decoded class names (when \description{ MapBiomas Solos (Project MapBiomas, Brazil) distributes a national raster of SiBCS classes at 30 m, downloadable from -\url{https://mapbiomas.org/en/produtos}. This helper mirrors the +\code{https://mapbiomas.org/en/produtos}. This helper mirrors the shape of \code{\link{lookup_esdb}} but is local-file only: pass the path of the unpacked GeoTIFF and the function reprojects the user's WGS84 lat/lon to the raster's native CRS, extracts the diff --git a/man/lookup_soilgrids.Rd b/man/lookup_soilgrids.Rd index fc3ddc18b..9fd0a2eee 100644 --- a/man/lookup_soilgrids.Rd +++ b/man/lookup_soilgrids.Rd @@ -48,7 +48,7 @@ Numeric vector of length \code{nrow(coords)}. \code{NA} \description{ Reads ISRIC SoilGrids 250m (Hengl et al. 2017, 2021) directly from the ISRIC Cloud-Optimized GeoTIFF (COG) endpoint at -\url{https://files.isric.org/soilgrids/latest/data/} -- no +\code{https://files.isric.org/soilgrids/latest/data/} -- no download required, only the pixel under each query coordinate is transferred over HTTPS. } diff --git a/man/ossl_demo_sa.Rd b/man/ossl_demo_sa.Rd index f5649251f..060b00752 100644 --- a/man/ossl_demo_sa.Rd +++ b/man/ossl_demo_sa.Rd @@ -24,7 +24,7 @@ A list with three elements: Synthetic; built by \code{data-raw/build_ossl_demo.R} with seed 20260430. The OSSL property ranges that drove the simulation come from Sanderman, J. \emph{et al.} (2024), \emph{Open Soil -Spectral Library}, \url{https://soilspectroscopy.org/}. +Spectral Library}, \code{https://soilspectroscopy.org/}. } \usage{ ossl_demo_sa diff --git a/man/soil_classes_at_location.Rd b/man/soil_classes_at_location.Rd index 1d38d5280..449c59a1d 100644 --- a/man/soil_classes_at_location.Rd +++ b/man/soil_classes_at_location.Rd @@ -54,7 +54,7 @@ confirm. For real use, point \code{source_url} at a regional SoilGrids "MostProbable WRB" GeoTIFF / COG (one of the cuts at -\url{https://files.isric.org/soilgrids/latest/data/wrb/}). For +\code{https://files.isric.org/soilgrids/latest/data/wrb/}). For tests, \code{options(soilKey.test_raster = "/tmp/syn.tif")} is honoured. When no source is given, the function emits a \code{cli_alert_warning()} and returns an empty result -- it does diff --git a/man/spatial_prior_embrapa.Rd b/man/spatial_prior_embrapa.Rd index 29f47f6f8..0aadba1b4 100644 --- a/man/spatial_prior_embrapa.Rd +++ b/man/spatial_prior_embrapa.Rd @@ -19,7 +19,7 @@ spatial_prior_embrapa( \item{raster_path}{Required. Path to a local categorical raster (GeoTIFF) of Embrapa SiBCS classes. There is no built-in file in v0.5 -- download the polygon map from -\url{https://www.embrapa.br/solos/sibcs} and rasterise it.} +\code{https://www.embrapa.br/solos/sibcs} and rasterise it.} \item{buffer_m}{Buffer radius in metres (default 3750, i.e. ~15-cell neighbourhood at 250 m resolution).} diff --git a/soilKey_0.9.154.tar.gz b/soilKey_0.9.154.tar.gz deleted file mode 100644 index 333dbd5bf..000000000 Binary files a/soilKey_0.9.154.tar.gz and /dev/null differ diff --git a/tests/testthat/test-report-qgis.R b/tests/testthat/test-report-qgis.R index ade8a17d5..5cee3c0c8 100644 --- a/tests/testthat/test-report-qgis.R +++ b/tests/testthat/test-report-qgis.R @@ -4,6 +4,7 @@ test_that("report_to_qgis() validates inputs", { + skip_on_cran() skip_if_not_installed("sf") pedon <- make_ferralsol_canonical() expect_error( @@ -29,6 +30,7 @@ test_that("report_to_qgis() validates inputs", { test_that("report_to_qgis() writes a multi-layer GeoPackage with the canonical pedon_point layer", { + skip_on_cran() skip_if_not_installed("sf") pedon <- make_ferralsol_canonical() results <- list( @@ -66,6 +68,7 @@ test_that("report_to_qgis() writes a multi-layer GeoPackage with the canonical p test_that("report_to_qgis() round-trips horizons_table with site_id + horizon_idx columns", { + skip_on_cran() skip_if_not_installed("sf") pedon <- make_ferralsol_canonical() out <- tempfile(fileext = ".gpkg") @@ -80,6 +83,7 @@ test_that("report_to_qgis() round-trips horizons_table with site_id + horizon_id test_that("report_to_qgis() refuses to overwrite when overwrite = FALSE", { + skip_on_cran() skip_if_not_installed("sf") pedon <- make_ferralsol_canonical() out <- tempfile(fileext = ".gpkg") @@ -93,6 +97,7 @@ test_that("report_to_qgis() refuses to overwrite when overwrite = FALSE", { test_that("report_to_qgis() warns and continues when the pedon has no coordinates", { + skip_on_cran() skip_if_not_installed("sf") pedon <- PedonRecord$new( site = list(id = "no-coords"), diff --git a/tests/testthat/test-v0934-aqp-interop.R b/tests/testthat/test-v0934-aqp-interop.R index 1f6e3725e..2481c2778 100644 --- a/tests/testthat/test-v0934-aqp-interop.R +++ b/tests/testthat/test-v0934-aqp-interop.R @@ -8,6 +8,7 @@ skip_if_no_aqp <- function() { # ---- as_aqp --------------------------------------------------------------- test_that("as_aqp converts a single PedonRecord to a 1-profile SPC", { + skip_on_cran() skip_if_no_aqp() p <- make_ferralsol_canonical() spc <- as_aqp(p) @@ -18,6 +19,7 @@ test_that("as_aqp converts a single PedonRecord to a 1-profile SPC", { }) test_that("as_aqp converts a list of PedonRecords to multi-profile SPC", { + skip_on_cran() skip_if_no_aqp() pedons <- list(make_ferralsol_canonical(), make_luvisol_canonical(), @@ -30,6 +32,7 @@ test_that("as_aqp converts a list of PedonRecords to multi-profile SPC", { }) test_that("as_aqp renames soilKey horizon columns to aqp canonical", { + skip_on_cran() skip_if_no_aqp() p <- make_ferralsol_canonical() spc <- as_aqp(p) @@ -46,6 +49,7 @@ test_that("as_aqp renames soilKey horizon columns to aqp canonical", { }) test_that("as_aqp attaches site-level metadata", { + skip_on_cran() skip_if_no_aqp() p <- make_ferralsol_canonical() spc <- as_aqp(p) @@ -61,6 +65,7 @@ test_that("as_aqp attaches site-level metadata", { # ---- from_aqp ------------------------------------------------------------- test_that("from_aqp converts SPC back to a list of PedonRecord", { + skip_on_cran() skip_if_no_aqp() pedons <- list(make_ferralsol_canonical(), make_luvisol_canonical()) spc <- as_aqp(pedons) @@ -70,6 +75,7 @@ test_that("from_aqp converts SPC back to a list of PedonRecord", { }) test_that("from_aqp renames aqp columns back to soilKey conventions", { + skip_on_cran() skip_if_no_aqp() p <- make_ferralsol_canonical() spc <- as_aqp(p) @@ -87,6 +93,7 @@ test_that("from_aqp renames aqp columns back to soilKey conventions", { # ---- round-trip property -------------------------------------------------- test_that("round-trip: from_aqp(as_aqp(pedon)) preserves horizon chemistry", { + skip_on_cran() skip_if_no_aqp() p <- make_ferralsol_canonical() spc <- as_aqp(p) @@ -102,6 +109,7 @@ test_that("round-trip: from_aqp(as_aqp(pedon)) preserves horizon chemistry", { }) test_that("round-trip preserves designation and depth columns", { + skip_on_cran() skip_if_no_aqp() p <- make_luvisol_canonical() spc <- as_aqp(p) @@ -112,6 +120,7 @@ test_that("round-trip preserves designation and depth columns", { }) test_that("round-trip preserves the site id", { + skip_on_cran() skip_if_no_aqp() p <- make_chernozem_canonical() spc <- as_aqp(p) @@ -123,12 +132,14 @@ test_that("round-trip preserves the site id", { # ---- error handling ------------------------------------------------------- test_that("as_aqp errors on non-PedonRecord input", { + skip_on_cran() skip_if_no_aqp() expect_error(as_aqp(42), "PedonRecord") expect_error(as_aqp(list(1, 2, 3)), "PedonRecord") }) test_that("from_aqp errors on non-SPC input", { + skip_on_cran() skip_if_no_aqp() expect_error(from_aqp(data.frame(id = "a", top = 0, bottom = 10)), "SoilProfileCollection") @@ -139,6 +150,7 @@ test_that("from_aqp errors on non-SPC input", { # ---- classification works on round-tripped pedons -------------------------- test_that("classify_wrb2022 returns same RSG before and after aqp round-trip", { + skip_on_cran() skip_if_no_aqp() p <- make_ferralsol_canonical() res_before <- classify_wrb2022(p, on_missing = "silent") @@ -148,6 +160,7 @@ test_that("classify_wrb2022 returns same RSG before and after aqp round-trip", { }) test_that("classify_usda returns same Order before and after aqp round-trip", { + skip_on_cran() skip_if_no_aqp() p <- make_ferralsol_canonical() res_before <- classify_usda(p, on_missing = "silent") @@ -160,6 +173,7 @@ test_that("classify_usda returns same Order before and after aqp round-trip", { # ---- multi-profile heterogeneous schema ----------------------------------- test_that("as_aqp pads missing columns across profiles with different schemas", { + skip_on_cran() skip_if_no_aqp() # Build two pedons with intentionally different horizon columns. hz1 <- ensure_horizon_schema(data.table::data.table( diff --git a/tests/testthat/test-v0944-esdb-raster.R b/tests/testthat/test-v0944-esdb-raster.R index 8f974aebd..3a5525d24 100644 --- a/tests/testthat/test-v0944-esdb-raster.R +++ b/tests/testthat/test-v0944-esdb-raster.R @@ -30,6 +30,7 @@ skip_if_no_esdb <- function() { test_that("available_esdb_attributes lists the expected ESDB attributes", { + skip_on_cran() root <- skip_if_no_esdb() attrs <- available_esdb_attributes(root) # The 2024-05-07 ESDB Raster Library release ships 71 attributes. @@ -41,6 +42,7 @@ test_that("available_esdb_attributes lists the expected ESDB attributes", { }) test_that("lookup_esdb resolves Wageningen NL to a real RSG code", { + skip_on_cran() root <- skip_if_no_esdb() # 5.66 E, 51.97 N -- NW Netherlands, fluvial-deltaic landscape. res <- lookup_esdb(c(5.66, 51.97), "WRBLV1", root) @@ -51,6 +53,7 @@ test_that("lookup_esdb resolves Wageningen NL to a real RSG code", { }) test_that("lookup_esdb returns NA for points outside the European raster", { + skip_on_cran() root <- skip_if_no_esdb() # Equator + Atlantic ocean -- well outside ESDB footprint. res <- lookup_esdb(c(0, 0), "WRBLV1", root) @@ -58,6 +61,7 @@ test_that("lookup_esdb returns NA for points outside the European raster", { }) test_that("lookup_esdb is vectorised over multiple points", { + skip_on_cran() root <- skip_if_no_esdb() coords <- rbind(c(5.66, 51.97), c(24.94, 60.17), # Helsinki, FI @@ -68,6 +72,7 @@ test_that("lookup_esdb is vectorised over multiple points", { }) test_that("lookup_esdb decode = FALSE returns raw integers", { + skip_on_cran() root <- skip_if_no_esdb() res <- lookup_esdb(c(5.66, 51.97), "WRBLV1", root, decode = FALSE) expect_type(res, "double") @@ -75,12 +80,14 @@ test_that("lookup_esdb decode = FALSE returns raw integers", { }) test_that("lookup_esdb errors clearly when raster missing", { + skip_on_cran() root <- skip_if_no_esdb() expect_error(lookup_esdb(c(5.66, 51.97), "BOGUS_ATTR", root), "Raster not found") }) test_that("lookup_esdb accepts data.frame input", { + skip_on_cran() root <- skip_if_no_esdb() df <- data.frame(lon = c(5.66, 24.94), lat = c(51.97, 60.17)) res <- lookup_esdb(df, "WRBLV1", root) @@ -91,6 +98,7 @@ test_that("lookup_esdb accepts data.frame input", { # ---- Cross-system: WRB raster vs FAO 1990 raster -------------------------- test_that("WRBLV1 vs FAO90LV1 agree on broad classes for the same point", { + skip_on_cran() root <- skip_if_no_esdb() # Sample 5 European cities and check that both rasters resolve to # SOMETHING (we don't insist they agree on a single class, just that diff --git a/tests/testthat/test-v0947-munsell-prediction.R b/tests/testthat/test-v0947-munsell-prediction.R index 2d96a065a..452e2146a 100644 --- a/tests/testthat/test-v0947-munsell-prediction.R +++ b/tests/testthat/test-v0947-munsell-prediction.R @@ -28,6 +28,7 @@ # ---- predict_xyz_from_spectra basic shape ------------------------------- test_that("predict_xyz_from_spectra returns X/Y/Z with right shape", { + skip_on_cran() s <- .flat_white_R() out <- predict_xyz_from_spectra(s$R, s$wl) expect_s3_class(out, "data.frame") @@ -40,6 +41,7 @@ test_that("predict_xyz_from_spectra returns X/Y/Z with right shape", { # ---- White reflector should yield Y close to scaled white --------------- test_that("Flat white reflector yields Y proportional to the reflectance", { + skip_on_cran() s <- .flat_white_R(level = 1.0) out <- predict_xyz_from_spectra(s$R, s$wl) # Perfect diffuse white should have Y == 100 by definition; allow a @@ -53,6 +55,7 @@ test_that("Flat white reflector yields Y proportional to the reflectance", { test_that("Half-reflectance gives half-Y", { + skip_on_cran() hi <- predict_xyz_from_spectra(.flat_white_R(level = 1.0)$R, .flat_white_R()$wl) lo <- predict_xyz_from_spectra(.flat_white_R(level = 0.5)$R, @@ -64,6 +67,7 @@ test_that("Half-reflectance gives half-Y", { # ---- Vector input is accepted ------------------------------------------- test_that("predict_xyz_from_spectra accepts a numeric vector", { + skip_on_cran() wl <- seq(380, 780, by = 5) R <- rep(0.5, length(wl)) out <- predict_xyz_from_spectra(R, wl) @@ -75,6 +79,7 @@ test_that("predict_xyz_from_spectra accepts a numeric vector", { # ---- Reflectance scale auto-detect (% vs decimal) ----------------------- test_that("Reflectance in % (0..100) is auto-detected", { + skip_on_cran() wl <- seq(380, 780, by = 5) R_pct <- rep(50, length(wl)) R_frac <- rep(0.5, length(wl)) @@ -87,6 +92,7 @@ test_that("Reflectance in % (0..100) is auto-detected", { # ---- Wavelength count must match ----------------------------------------- test_that("Wavelength length must match ncol(spectra)", { + skip_on_cran() expect_error( predict_xyz_from_spectra(matrix(0.5, 1, 10), wavelengths = seq(380, 780, 5)), "length\\(wavelengths\\)" @@ -97,6 +103,7 @@ test_that("Wavelength length must match ncol(spectra)", { # ---- predict_lab_from_spectra basic shape ------------------------------- test_that("predict_lab_from_spectra returns L/a/b with right shape", { + skip_on_cran() s <- .flat_white_R() lab <- predict_lab_from_spectra(s$R, s$wl) expect_s3_class(lab, "data.frame") @@ -106,6 +113,7 @@ test_that("predict_lab_from_spectra returns L/a/b with right shape", { test_that("White reflector has L close to 100, a~0, b~0", { + skip_on_cran() s <- .flat_white_R(level = 1.0) lab <- predict_lab_from_spectra(s$R, s$wl) expect_equal(lab$L, 100, tolerance = 0.5) @@ -117,6 +125,7 @@ test_that("White reflector has L close to 100, a~0, b~0", { # ---- Spectral red has positive a* --------------------------------------- test_that("Red spectrum yields positive a* (red-green axis)", { + skip_on_cran() s <- .spectral_red() lab <- predict_lab_from_spectra(s$R, s$wl) expect_true(lab$a > 0) @@ -124,6 +133,7 @@ test_that("Red spectrum yields positive a* (red-green axis)", { test_that("Blue spectrum yields negative b* (yellow-blue axis)", { + skip_on_cran() s <- .spectral_blue() lab <- predict_lab_from_spectra(s$R, s$wl) expect_true(lab$b < 0) @@ -133,6 +143,7 @@ test_that("Blue spectrum yields negative b* (yellow-blue axis)", { # ---- Munsell prediction: skip if munsellinterpol unavailable ------------ test_that("predict_munsell_from_spectra needs munsellinterpol", { + skip_on_cran() if (requireNamespace("munsellinterpol", quietly = TRUE)) { skip("munsellinterpol installed -- can't exercise the missing-pkg path") } @@ -142,6 +153,7 @@ test_that("predict_munsell_from_spectra needs munsellinterpol", { test_that("predict_munsell_from_spectra returns the soilKey-named columns", { + skip_on_cran() skip_if_not_installed("munsellinterpol") s <- .flat_white_R(level = 0.5) out <- predict_munsell_from_spectra(s$R, s$wl) @@ -157,6 +169,7 @@ test_that("predict_munsell_from_spectra returns the soilKey-named columns", { # ---- White reflector maps to a high Munsell value ----------------------- test_that("Bright neutral spectrum maps to high Munsell value", { + skip_on_cran() skip_if_not_installed("munsellinterpol") s <- .flat_white_R(level = 0.85) out <- predict_munsell_from_spectra(s$R, s$wl) @@ -170,6 +183,7 @@ test_that("Bright neutral spectrum maps to high Munsell value", { # ---- Red spectrum maps to a hue in the R / YR family -------------------- test_that("Red-dominant spectrum predicts an R or YR hue", { + skip_on_cran() skip_if_not_installed("munsellinterpol") s <- .spectral_red() out <- predict_munsell_from_spectra(s$R, s$wl) @@ -180,6 +194,7 @@ test_that("Red-dominant spectrum predicts an R or YR hue", { # ---- fill_munsell_from_spectra writes provenance ------------------------ test_that("fill_munsell_from_spectra writes Munsell cells with provenance", { + skip_on_cran() skip_if_not_installed("munsellinterpol") wl <- seq(380, 2400, by = 10) pedon <- make_synthetic_pedon_with_spectra(n_horizons = 2L, @@ -203,6 +218,7 @@ test_that("fill_munsell_from_spectra writes Munsell cells with provenance", { # ---- Sanity: the embedded CIE table has the right shape ----------------- test_that("Embedded CIE 1931 / D65 table covers 380-780 nm at 5 nm steps", { + skip_on_cran() cie <- soilKey:::.cie_d65_5nm expect_equal(nrow(cie), 81L) expect_equal(min(cie$wavelength), 380) diff --git a/tests/testthat/test-v0962-aqp-interop.R b/tests/testthat/test-v0962-aqp-interop.R index 2770a12ef..60706814e 100644 --- a/tests/testthat/test-v0962-aqp-interop.R +++ b/tests/testthat/test-v0962-aqp-interop.R @@ -14,6 +14,7 @@ # ---- 1. texture_class_from_pct --------------------------------------- test_that("texture_class_from_pct returns canonical USDA classes", { + skip_on_cran() # Classic clay (heavy) expect_equal(texture_class_from_pct(60, 20, 20), "C") # Sandy clay loam (sandy texture, moderate clay) @@ -33,6 +34,7 @@ test_that("texture_class_from_pct returns canonical USDA classes", { test_that("texture_class_from_pct is NA-safe and vectorised", { + skip_on_cran() expect_true(is.na(texture_class_from_pct(NA, 20, 60))) expect_true(is.na(texture_class_from_pct(20, NA, 60))) # (5, 5, 90): silt + 1.5*clay = 12.5 < 15 -> S @@ -71,6 +73,7 @@ test_that("texture_class_from_pct is NA-safe and vectorised", { test_that("pedon_to_spc builds an aqp::SoilProfileCollection", { + skip_on_cran() testthat::skip_if_not_installed("aqp") p <- .make_simple_pedon() spc <- pedon_to_spc(p) @@ -87,6 +90,7 @@ test_that("pedon_to_spc builds an aqp::SoilProfileCollection", { test_that("pedon_to_spc errors on missing horizons or depths", { + skip_on_cran() empty <- PedonRecord$new( site = list(id = "empty", country = "BR"), horizons = data.frame() @@ -107,6 +111,7 @@ test_that("pedon_to_spc errors on missing horizons or depths", { # ---- 3. argic_aqp / cambic_aqp --------------------------------------- test_that("argic_aqp returns a DiagnosticResult with the engine tag", { + skip_on_cran() testthat::skip_if_not_installed("aqp") p <- .make_simple_pedon() res <- argic_aqp(p, require_t = FALSE) @@ -120,6 +125,7 @@ test_that("argic_aqp returns a DiagnosticResult with the engine tag", { test_that("argic_aqp passes on a clear argic profile (clay 20 -> 50)", { + skip_on_cran() testthat::skip_if_not_installed("aqp") p <- .make_simple_pedon() # require_t = FALSE so we don't need the "t" suffix in the @@ -130,6 +136,7 @@ test_that("argic_aqp passes on a clear argic profile (clay 20 -> 50)", { test_that("argic_aqp does not pass on a homogeneous Latossolo (no clay increase)", { + skip_on_cran() testthat::skip_if_not_installed("aqp") hz <- data.frame( designation = c("A", "Bw1", "Bw2"), @@ -156,6 +163,7 @@ test_that("argic_aqp does not pass on a homogeneous Latossolo (no clay increase) test_that("cambic_aqp returns a DiagnosticResult", { + skip_on_cran() testthat::skip_if_not_installed("aqp") p <- .make_simple_pedon() res <- cambic_aqp(p) @@ -166,6 +174,7 @@ test_that("cambic_aqp returns a DiagnosticResult", { test_that("cambic_aqp gracefully returns FALSE on sandy profile", { + skip_on_cran() testthat::skip_if_not_installed("aqp") hz <- data.frame( designation = c("A", "C"), @@ -195,6 +204,7 @@ test_that("cambic_aqp gracefully returns FALSE on sandy profile", { # ---- 4. compare_engines + canonical references ----------------------- test_that("compare_engines returns paired results for argic and cambic", { + skip_on_cran() testthat::skip_if_not_installed("aqp") p <- .make_simple_pedon() out <- compare_engines(p, "argic") @@ -209,6 +219,7 @@ test_that("compare_engines returns paired results for argic and cambic", { test_that("canonical_reference loads WRB_4th_2022 with both backends", { + skip_on_cran() # Default: prefer SoilTaxonomy if installed if (requireNamespace("SoilTaxonomy", quietly = TRUE)) { out <- canonical_reference("WRB_4th_2022", prefer_pkg = TRUE) @@ -223,6 +234,7 @@ test_that("canonical_reference loads WRB_4th_2022 with both backends", { test_that("kst13_canonical and st_features_canonical return expected shapes", { + skip_on_cran() kst <- kst13_canonical(prefer_pkg = FALSE) expect_type(kst, "list") expect_true(length(kst) > 100L) # 3,153 nested entries diff --git a/tests/testthat/test-v0963-qualifiers.R b/tests/testthat/test-v0963-qualifiers.R index 73e082ea9..8dffe317d 100644 --- a/tests/testthat/test-v0963-qualifiers.R +++ b/tests/testthat/test-v0963-qualifiers.R @@ -37,6 +37,7 @@ # ---- 1. Coarsic --------------------------------------------------- test_that("qual_coarsic returns NA when no coarse_fragments_pct", { + skip_on_cran() res <- qual_coarsic(.minimal_pedon()) expect_s3_class(res, "DiagnosticResult") expect_true(is.na(res$passed)) @@ -45,6 +46,7 @@ test_that("qual_coarsic returns NA when no coarse_fragments_pct", { test_that("qual_coarsic fires when coarse_fragments_pct >= 70", { + skip_on_cran() p <- .minimal_pedon() p$horizons$coarse_fragments_pct <- c(80, 75) expect_true(isTRUE(qual_coarsic(p)$passed)) @@ -52,6 +54,7 @@ test_that("qual_coarsic fires when coarse_fragments_pct >= 70", { test_that("qual_coarsic does not fire when CF below threshold", { + skip_on_cran() p <- .minimal_pedon() p$horizons$coarse_fragments_pct <- c(20, 30) expect_false(isTRUE(qual_coarsic(p)$passed)) @@ -61,6 +64,7 @@ test_that("qual_coarsic does not fire when CF below threshold", { # ---- 2. Fractic --------------------------------------------------- test_that("qual_fractic NA-safe + fires on cracks", { + skip_on_cran() expect_true(is.na(qual_fractic(.minimal_pedon())$passed)) p <- .minimal_pedon() p$horizons$cracks_width_cm <- c(0, 2) @@ -72,6 +76,7 @@ test_that("qual_fractic NA-safe + fires on cracks", { # ---- 3. Gibbsic --------------------------------------------------- test_that("qual_gibbsic uses al2o3_sulfuric_pct proxy at 25%", { + skip_on_cran() p <- .minimal_pedon() p$horizons$al2o3_sulfuric_pct <- c(28, 30) expect_true(isTRUE(qual_gibbsic(p)$passed)) @@ -83,6 +88,7 @@ test_that("qual_gibbsic uses al2o3_sulfuric_pct proxy at 25%", { # ---- 4. Ferritic -------------------------------------------------- test_that("qual_ferritic fires on Fe2O3 >= 18%", { + skip_on_cran() p <- .minimal_pedon() p$horizons$fe_dcb_pct <- c(20, 25) expect_true(isTRUE(qual_ferritic(p)$passed)) @@ -94,6 +100,7 @@ test_that("qual_ferritic fires on Fe2O3 >= 18%", { # ---- 5. Profundihumic --------------------------------------------- test_that("qual_profundihumic requires SOC >= 1.4 weighted to 100 cm", { + skip_on_cran() p <- .minimal_pedon() p$horizons$oc_pct <- c(3.0, 2.0) expect_true(isTRUE(qual_profundihumic(p)$passed)) @@ -105,6 +112,7 @@ test_that("qual_profundihumic requires SOC >= 1.4 weighted to 100 cm", { # ---- 6. Wapnic ---------------------------------------------------- test_that("qual_wapnic requires CaCO3 >= 80%", { + skip_on_cran() p <- .minimal_pedon() p$horizons$caco3_pct <- c(85, 90) expect_true(isTRUE(qual_wapnic(p)$passed)) @@ -116,6 +124,7 @@ test_that("qual_wapnic requires CaCO3 >= 80%", { # ---- 7-9. Mawic / Muusic / Murshic -------------------------------- test_that("qual_mawic requires moss + fibre >= 40", { + skip_on_cran() p <- .minimal_pedon() p$horizons$fiber_content_unrubbed_pct <- c(50, 60) p$horizons$layer_origin <- c("musgo Sphagnum", "musgo Sphagnum") @@ -126,6 +135,7 @@ test_that("qual_mawic requires moss + fibre >= 40", { test_that("qual_muusic requires rubbed fibre >= 75", { + skip_on_cran() p <- .minimal_pedon() p$horizons$fiber_content_rubbed_pct <- c(80, 85) expect_true(isTRUE(qual_muusic(p)$passed)) @@ -133,6 +143,7 @@ test_that("qual_muusic requires rubbed fibre >= 75", { test_that("qual_murshic uses low rubbed fibre OR von Post >= 7", { + skip_on_cran() p <- .minimal_pedon() p$horizons$fiber_content_rubbed_pct <- c(10, 8) # < 17 expect_true(isTRUE(qual_murshic(p)$passed)) @@ -145,12 +156,14 @@ test_that("qual_murshic uses low rubbed fibre OR von Post >= 7", { # ---- 10-13. Endo- / Pante- / Ortho- modifiers ---------------------- test_that("qual_endocalcaric depth-bounded modifier", { + skip_on_cran() res <- qual_endocalcaric(.minimal_pedon()) expect_s3_class(res, "DiagnosticResult") }) test_that("qual_anofluvic / orthofluvic / pantofluvic don't error", { + skip_on_cran() for (fn in list(qual_anofluvic, qual_orthofluvic, qual_pantofluvic)) { res <- fn(.minimal_pedon()) expect_s3_class(res, "DiagnosticResult") @@ -161,6 +174,7 @@ test_that("qual_anofluvic / orthofluvic / pantofluvic don't error", { # ---- 14-15. Oxy/Reductaquic/gleyic ---------------------------------- test_that("qual_oxyaquic fires on redox >= 5 with non-gleyic hue", { + skip_on_cran() p <- .minimal_pedon() p$horizons$redoximorphic_features_pct <- c(8, 10) # 10YR is NOT gleyic, so oxidized + redox -> oxyaquic @@ -171,6 +185,7 @@ test_that("qual_oxyaquic fires on redox >= 5 with non-gleyic hue", { # ---- 16. Hypernatric ----------------------------------------------- test_that("qual_hypernatric fires when ESP >= 70%", { + skip_on_cran() p <- .minimal_pedon() p$horizons$na_cmol <- c(7, 5) p$horizons$cec_cmol <- c(10, 7) # ESP = 70 / 71% @@ -181,6 +196,7 @@ test_that("qual_hypernatric fires when ESP >= 70%", { # ---- 17. Carbonatic / Carbonic ------------------------------------- test_that("qual_carbonatic on CaCO3 >= 50", { + skip_on_cran() p <- .minimal_pedon() p$horizons$caco3_pct <- c(60, 55) expect_true(isTRUE(qual_carbonatic(p)$passed)) @@ -188,6 +204,7 @@ test_that("qual_carbonatic on CaCO3 >= 50", { test_that("qual_carbonic on SOC >= 6", { + skip_on_cran() p <- .minimal_pedon() p$horizons$oc_pct <- c(8, 7) expect_true(isTRUE(qual_carbonic(p)$passed)) @@ -197,6 +214,7 @@ test_that("qual_carbonic on SOC >= 6", { # ---- 18. Transportic / Relocatic / Isolatic ------------------------ test_that("qual_transportic matches origin pattern", { + skip_on_cran() p <- .minimal_pedon() p$horizons$layer_origin <- c("aterro antropico", "aterro antropico") expect_true(isTRUE(qual_transportic(p)$passed)) @@ -204,6 +222,7 @@ test_that("qual_transportic matches origin pattern", { test_that("qual_isolatic needs artefact pct between 5 and 50", { + skip_on_cran() p <- .minimal_pedon() p$horizons$artefacts_urbic_pct <- c(15, 30) expect_true(isTRUE(qual_isolatic(p)$passed)) @@ -215,6 +234,7 @@ test_that("qual_isolatic needs artefact pct between 5 and 50", { # ---- 19-22. SQ Endo/Epi-dystric/eutric ----------------------------- test_that("qual_endodystric / qual_epidystric depth-bounded", { + skip_on_cran() expect_s3_class(qual_endodystric(.minimal_pedon()), "DiagnosticResult") expect_s3_class(qual_epidystric(.minimal_pedon()), "DiagnosticResult") expect_s3_class(qual_endoeutric(.minimal_pedon()), "DiagnosticResult") @@ -225,6 +245,7 @@ test_that("qual_endodystric / qual_epidystric depth-bounded", { # ---- 23. argic + cambic engine arg --------------------------------- test_that("argic() supports engine = 'aqp' and 'soilkey'", { + skip_on_cran() testthat::skip_if_not_installed("aqp") p <- .minimal_pedon() r1 <- argic(p, engine = "soilkey") @@ -237,6 +258,7 @@ test_that("argic() supports engine = 'aqp' and 'soilkey'", { test_that("cambic() supports engine = 'aqp' and 'soilkey'", { + skip_on_cran() testthat::skip_if_not_installed("aqp") p <- .minimal_pedon() r1 <- cambic(p, engine = "soilkey") diff --git a/tests/testthat/test-v0965-engine-and-tier3.R b/tests/testthat/test-v0965-engine-and-tier3.R index 1586f0316..0081a895a 100644 --- a/tests/testthat/test-v0965-engine-and-tier3.R +++ b/tests/testthat/test-v0965-engine-and-tier3.R @@ -28,6 +28,7 @@ # ---- 1. pick_engine + pick_engine_batch ------------------------------- test_that("pick_engine returns 'soilkey' on a sparse pedon", { + skip_on_cran() hz <- data.frame( designation = NA_character_, top_cm = 0L, bottom_cm = 30L, munsell_hue_moist = NA_character_, munsell_value_moist = NA_real_, @@ -44,6 +45,7 @@ test_that("pick_engine returns 'soilkey' on a sparse pedon", { test_that("pick_engine returns 'aqp' on a data-rich pedon", { + skip_on_cran() hz <- data.frame( designation = c("A", "Bt"), top_cm = c(0, 30), bottom_cm = c(30, 100), @@ -66,6 +68,7 @@ test_that("pick_engine returns 'aqp' on a data-rich pedon", { test_that("pick_engine_batch vectorises", { + skip_on_cran() ps <- list(.pedon_minimal_v0965(), .pedon_minimal_v0965()) res <- pick_engine_batch(ps) expect_length(res, 2L) @@ -74,6 +77,7 @@ test_that("pick_engine_batch vectorises", { test_that("pick_engine min_score adjusts threshold", { + skip_on_cran() p <- .pedon_minimal_v0965() expect_equal(pick_engine(p, min_score = 5L), "soilkey") expect_equal(pick_engine(p, min_score = 1L), "aqp") @@ -83,6 +87,7 @@ test_that("pick_engine min_score adjusts threshold", { # ---- 2. classify_with_engine_heuristic -------------------------------- test_that("classify_with_engine_heuristic captures engine in trace", { + skip_on_cran() testthat::skip_if_not_installed("aqp") p <- .pedon_minimal_v0965() res <- tryCatch( @@ -99,6 +104,7 @@ test_that("classify_with_engine_heuristic captures engine in trace", { # ---- 3. Tier-3 schema fields populated ------------------------------- test_that("Tier-3 schema fields exist in horizon_column_spec()", { + skip_on_cran() spec <- horizon_column_spec() for (f in c("surface_crust_type", "bioturbation_density", "cordic_horizon", "microrelief_form", @@ -114,6 +120,7 @@ test_that("Tier-3 schema fields exist in horizon_column_spec()", { test_that("Tier-3 qualifiers fire when their schema field is populated", { + skip_on_cran() p <- .pedon_minimal_v0965() p$horizons$surface_crust_type <- c("biocrust", NA_character_) expect_true(isTRUE(qual_biocrustic(p)$passed)) @@ -145,6 +152,7 @@ test_that("Tier-3 qualifiers fire when their schema field is populated", { test_that("Tier-3 qualifiers return NA when schema field is empty", { + skip_on_cran() p <- .pedon_minimal_v0965() expect_true(is.na(qual_biocrustic(p)$passed)) expect_true(is.na(qual_arenicolic(p)$passed)) @@ -157,6 +165,7 @@ test_that("Tier-3 qualifiers return NA when schema field is empty", { # ---- 4. Engine-aware leptic + arenic relaxation ---------------------- test_that("leptic_features engine='aqp' relaxes coarse_pct + accepts thin topsoil", { + skip_on_cran() hz <- data.frame( designation = c("A", "C"), top_cm = c(0, 20), bottom_cm = c(20, 25), munsell_hue_moist = c("10YR","10YR"), @@ -177,6 +186,7 @@ test_that("leptic_features engine='aqp' relaxes coarse_pct + accepts thin topsoi test_that("arenic_texture engine='aqp' accepts sand >= 70 even if silt+2*clay >= 30", { + skip_on_cran() hz <- data.frame( designation = c("A", "C"), top_cm = c(0, 30), bottom_cm = c(30, 100), munsell_hue_moist = c("10YR","10YR"), munsell_value_moist = c(4,4), diff --git a/vignettes/v01_getting_started_pt.Rmd b/vignettes/v01_getting_started_pt.Rmd index ec5130305..568d84b9e 100644 --- a/vignettes/v01_getting_started_pt.Rmd +++ b/vignettes/v01_getting_started_pt.Rmd @@ -192,6 +192,6 @@ Para a comunidade brasileira: o caminho mais natural é começar aqui (`v01_gett # Referências canônicas -- IUSS Working Group WRB (2022). *World Reference Base for Soil Resources*, 4ª ed. International Union of Soil Sciences, Vienna. [PDF](https://openknowledge.fao.org/server/api/core/bitstreams/bcdecec7-f45f-4dc5-beb1-97022d29fab4/content) +- IUSS Working Group WRB (2022). *World Reference Base for Soil Resources*, 4ª ed. International Union of Soil Sciences, Vienna. PDF (`https://openknowledge.fao.org/server/api/core/bitstreams/bcdecec7-f45f-4dc5-beb1-97022d29fab4/content`) - Soil Survey Staff (2022). *Keys to Soil Taxonomy*, 13ª ed. USDA-NRCS, Washington, DC. - Santos, H.G. *et al.* (2018). *Sistema Brasileiro de Classificação de Solos*, 5ª ed. revista e ampliada. Embrapa, Brasília.