Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ jobs:

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
extra-packages: any::rcmdcheck, any::testthat
needs: check

- uses: r-lib/actions/check-r-package@v2
with:
Expand Down
24 changes: 24 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Working on `celestial`

`celestial` is an R package of astronomical utilities. Most functionality is in
`R/`, package metadata is in `DESCRIPTION` and `NAMESPACE`, and user-facing
function documentation is in `man/`. The `src/` directory contains the
Rcpp-backed implementation and generated Rcpp bindings.

## Tests and checks

- Add package tests under `tests/testthat/`, with descriptive
`test-<area>.R` filenames. Use `test_that()` and `expect_*()` from testthat.
- Run the focused suite with `Rscript -e 'testthat::test_local()'` and the package
check with `R CMD check .` when the required R dependencies are available.
- Keep tests deterministic; avoid network access and uncontrolled randomness.
- Keep `Suggests` and CI test dependencies in sync when adding test tools.

## Changes

- Preserve existing public function names, arguments, units, and return
structures unless a change explicitly calls for an API change.
- Update the relevant Rd documentation when changing a public function.
- Do not hand-edit `R/RcppExports.R` or `src/RcppExports.cpp`; regenerate these
bindings with Rcpp tooling when the C++ interface changes.
- Keep changes focused, and add tests for changed behavior and boundary cases.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Description: Contains a number of common astronomy utility functions for cosmolo
License: LGPL-3
LazyData: TRUE
Depends: R (>= 3.00), RANN, NISTunits, pracma
Suggests: plotrix, igraph
Suggests: plotrix, igraph, testthat (>= 3.0.0)
LinkingTo: Rcpp
NeedsCompilation: yes
Config/testthat/edition: 3
4 changes: 4 additions & 0 deletions tests/testthat.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
library(testthat)
library(celestial)

test_check("celestial")
28 changes: 28 additions & 0 deletions tests/testthat/test-coordinate-conversions.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
test_that("decimal degrees convert to formatted DMS and HMS", {
expect_equal(
deg2dms(c(-27.345, 12.5), type = "cat", sep = ":"),
c("-27:20:42.00", "+12:30:00.00")
)
expect_equal(
deg2hms(c(182.5, 0), type = "cat", sep = ":"),
c("12:10:00.00", "00:00:00.00")
)
})

test_that("DMS values and strings convert back to decimal degrees", {
expect_equal(
dms2deg(d = c(27, 12), m = c(20, 30), s = c(42, 0), sign = c(-1, 1)),
c(-27.345, 12.5)
)
expect_equal(
dms2deg(c("-27:20:42", "+12:30:00")),
c(-27.345, 12.5)
)
expect_equal(hms2deg(c("12:10:00", "00:00:00")), c(182.5, 0))
})

test_that("coordinate conversions reject values outside their domains", {
expect_error(deg2dms(91), "All deg values")
expect_error(dms2deg(d = 12, m = 60), "All m values")
expect_error(hms2deg(h = 25), "All h values")
})
29 changes: 29 additions & 0 deletions tests/testthat/test-coordinate-matching.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
test_that("coordinate matching returns matches and separations in requested units", {
reference <- rbind(c(10, 0), c(30, 0))
comparison <- rbind(c(10 + 1 / 3600, 0), c(80, 0))

matches <- coordmatch(reference, comparison, rad = 2, radunit = "asec")

expect_equal(matches$Nmatch, c(1, 0))
expect_equal(matches$bestmatch$refID, 1)
expect_equal(matches$bestmatch$compareID, 1)
expect_equal(matches$bestmatch$sep, 1, tolerance = 1e-5)
})

test_that("single-coordinate matching chooses the nearest in-radius source", {
matches <- coordmatchsing(
RAref = 0, Decref = 0,
coordcompare = rbind(c(1, 0), c(0, 0)),
rad = 2, radunit = "deg"
)

expect_equal(matches$ID, c(2, 1))
expect_equal(unname(matches$bestmatch["compareID"]), 2)
expect_equal(unname(matches$bestmatch["sep"]), 0, tolerance = 1e-10)
})

test_that("linked coordinate groups combine connected objects", {
groups <- group_links(rbind(c(10, 20), c(20, 30), c(40, 50)))

expect_equal(groups, list(c(10, 20, 30), c(40, 50)))
})
14 changes: 14 additions & 0 deletions tests/testthat/test-cosmology.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
test_that("cosmological distances have expected identities and ordering", {
distances <- cosdist(z = c(0, 0.5, 1), H0 = 70, OmegaM = 0.3)

expect_equal(distances$z, c(0, 0.5, 1))
expect_equal(distances$CoDist[1], 0)
expect_true(all(diff(distances$CoDist) > 0))
expect_equal(distances$LumDist, (1 + distances$z) * distances$CoDist)
expect_equal(distances$AngDist, distances$CoDist / (1 + distances$z))
})

test_that("cosmological distance functions validate redshifts", {
expect_error(cosdist(z = -1), "z must be > -1")
expect_error(cosdist(z = Inf), "z must be finite")
})
18 changes: 18 additions & 0 deletions tests/testthat/test-sky-area.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
test_that("sky area handles full-sky and unit conversions", {
full_sky <- skyarea(long = c(0, 360), lat = c(-90, 90), outunit = "sr")

expect_equal(unname(full_sky["area"]), 4 * pi, tolerance = 1e-10)
expect_equal(unname(full_sky["areafrac"]), 1)

degrees <- skyarea(long = c(0, 10), lat = c(0, 10), outunit = "deg2")
steradians <- skyarea(long = c(0, 10), lat = c(0, 10), outunit = "sr")
expect_equal(unname(steradians["area"]),
unname(degrees["area"]) * (pi / 180)^2,
tolerance = 1e-10)
})

test_that("sky area rejects unsupported units and non-physical regions", {
expect_error(skyarea(inunit = "hour"), "inunit must be")
expect_error(skyarea(outunit = "degree"), "outunit must be")
expect_error(skyarea(long = c(10, 0)), "non-physical")
})
13 changes: 13 additions & 0 deletions tests/testthat/test-spherical-coordinates.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
test_that("spherical and Cartesian coordinates round-trip", {
spherical <- cbind(long = c(0, 90, 180), lat = c(0, 30, -45),
radius = c(1, 2, 3))

cartesian <- sph2car(spherical, deg = TRUE)
expect_equal(car2sph(cartesian, deg = TRUE), spherical, tolerance = 1e-10)
})

test_that("equatorial and galactic coordinates round-trip", {
equatorial <- cbind(RA = c(0, 123.4, 359), Dec = c(-30, 0, 70))

expect_equal(gal2eq(eq2gal(equatorial)), equatorial, tolerance = 1e-10)
})
Loading