From b13aa73e317ca2d21b9e6793af2441f37d7bb121 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 31 Oct 2026 06:36:04 +0000 Subject: [PATCH 1/3] Add maglab/magmap tests, coverage CI, AGENTS.md Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- .github/workflows/test-coverage.yaml | 31 +++++++++++++++++++++++ AGENTS.md | 28 ++++++++++++++++++++ tests/testthat/test-maglab-magmap.R | 38 ++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 .github/workflows/test-coverage.yaml create mode 100644 AGENTS.md create mode 100644 tests/testthat/test-maglab-magmap.R diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml new file mode 100644 index 0000000..501df57 --- /dev/null +++ b/.github/workflows/test-coverage.yaml @@ -0,0 +1,31 @@ +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +name: test-coverage + +jobs: + test-coverage: + runs-on: ubuntu-24.04 + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::covr + needs: coverage + + - name: Test coverage + run: | + cov <- covr::package_coverage(quiet = FALSE) + print(cov) + covr::to_cobertura(cov) + shell: Rscript {0} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..6820133 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,28 @@ +# AGENTS.md + +Guidance for AI agents and contributors working on `magicaxis` (R package for base-graphics scientific plotting with minor ticks and log axes). + +## Layout +- `/R` one file per main function (`magaxis.R`, `magplot.R`, `magimage.R`, `magmap.R`, ...). `NAMESPACE` uses `exportPattern("^[[:alpha:]]+")`, so any function whose name starts with a letter is exported; prefix internal helpers with `.`. +- `/man` hand-written Rd files (no roxygen) — update the matching `.Rd` when changing arguments. +- `/tests/testthat` testthat (edition 3) tests; `/vignettes` knitr vignettes; `/data`, `/inst` supporting data. +- Extra `...` arguments are routed to base graphics via `ParmOff` (a GitHub-only dependency, `asgr/ParmOff`, see `Remotes` in `DESCRIPTION`). + +## Commands +```r +devtools::load_all(); devtools::test() # run tests +devtools::check() # or R CMD check +covr::package_coverage() # coverage +``` + +## Testing conventions +- Tests that draw must open a null device (`pdf(nullfile())` + `on.exit(dev.off())`), as in the `with_null_dev` helper in `tests/testthat/test-functions.R`; never rely on an interactive device. +- Prefer asserting on return values/structure; for pure plotting use `expect_no_error`. +- Add a test with any bug fix or new argument. + +## CI +- `.github/workflows/R-CMD-check.yaml`: R CMD check on Windows/macOS/Ubuntu. +- `.github/workflows/test-coverage.yaml`: covr coverage on Ubuntu. + +## Style +Keep the existing terse base-R style; do not reformat unrelated code. Bump `Version`/`Date` in `DESCRIPTION` for releases. diff --git a/tests/testthat/test-maglab-magmap.R b/tests/testthat/test-maglab-magmap.R new file mode 100644 index 0000000..2b433ec --- /dev/null +++ b/tests/testthat/test-maglab-magmap.R @@ -0,0 +1,38 @@ +## Tests for maglab and magmap (pure computation, no plotting). + +library(magicaxis) + +test_that("maglab returns tickat, labat and exp", { + out <- maglab(c(0, 10)) + expect_named(out, c("tickat", "labat", "exp")) + expect_true(all(is.finite(out$labat))) + expect_equal(out$tickat, out$labat) +}) + +test_that("maglab trim=TRUE keeps labels within limits", { + out <- maglab(c(0.5, 9.5), trim = TRUE) + expect_true(all(out$labat >= 0.5 & out$labat <= 9.5)) +}) + +test_that("maglab log=TRUE gives power-of-ten label locations", { + out <- maglab(c(1, 1000), log = TRUE) + expect_true(all(abs(log10(out$labat) - round(log10(out$labat))) < 1e-8)) + expect_true(min(out$labat) <= 1 && max(out$labat) >= 1000) +}) + +test_that("maglab usemultloc requires log=TRUE", { + expect_error(maglab(c(1, 100), usemultloc = TRUE, log = FALSE)) +}) + +test_that("magmap output lies within the requested range", { + out <- magmap(seq(1, 100), range = c(0, 1)) + expect_true(all(out$map >= 0 & out$map <= 1)) + expect_length(out$map, 100) +}) + +test_that("magmap flip=TRUE reverses a linear mapping", { + x <- seq(1, 10) + a <- magmap(x, type = "num", locut = 1, hicut = 10, range = c(0, 1))$map + b <- magmap(x, type = "num", locut = 1, hicut = 10, range = c(0, 1), flip = TRUE)$map + expect_equal(a, 1 - b) +}) From 289be566df44eca939198c1092daece0c177f231 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Nov 2026 04:15:03 +0000 Subject: [PATCH 2/3] Install xml2 for coverage export Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- .github/workflows/test-coverage.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 501df57..aff8ce3 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -20,7 +20,7 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::covr + extra-packages: any::covr, any::xml2 needs: coverage - name: Test coverage From 90c6cfd3dfcf7082f970f0e95da8b3791fbbe015 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Nov 2026 04:15:39 +0000 Subject: [PATCH 3/3] Limit coverage workflow token permissions Co-authored-by: asgr <5617132+asgr@users.noreply.github.com> --- .github/workflows/test-coverage.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index aff8ce3..5ef7c2c 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -9,6 +9,8 @@ name: test-coverage jobs: test-coverage: runs-on: ubuntu-24.04 + permissions: + contents: read env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: