Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
56b1b45
Add serverside checks for class and object existence
timcadman Oct 9, 2025
4a9df9f
add functions in helper file
timcadman Oct 9, 2025
3280cd1
ran check, added dependencies
timcadman Oct 9, 2025
cee9a81
just use glue within messages for consistency
timcadman Oct 9, 2025
29d73aa
renamed snake case to camel case to match naming convention
timcadman Oct 9, 2025
245bbba
require testthat version 3
timcadman Oct 9, 2025
01b0f0f
test: unit tests for helper files
timcadman Oct 9, 2025
4a17212
look in correct environment, ie 2 steps up
timcadman Oct 9, 2025
6771731
write unit tests for unhappy path
timcadman Oct 9, 2025
c5e961e
added template with checklist for PRs
timcadman Oct 9, 2025
cc8d8f8
Added 'pull_request_template'
StuartWheater Oct 21, 2025
aa9fb8f
Updates for context() + copyright
StuartWheater Oct 26, 2025
809f7cb
Change version
StuartWheater Oct 27, 2025
3db8b60
Merge pull request #435 from StuartWheater/v6.3.5-dev-feat/testthat-r…
StuartWheater Oct 28, 2025
1e0b07f
Add "pull request template" to .Rbuildignore
StuartWheater Oct 28, 2025
8afb219
Merge branch 'v7.0-dev-feat/performance' into v6.3.5-dev-feat/testtha…
StuartWheater Oct 28, 2025
bef1b36
Merge pull request #436 from datashield/v6.3.5-dev-feat/testthat-rework
StuartWheater Oct 28, 2025
bb70048
Merge branch 'v7.0-dev-feat/performance' into v7.0-dev-feat/performance
StuartWheater Oct 28, 2025
511b95d
Comment out 'context(...)'
StuartWheater Oct 28, 2025
b6e7cb5
Update for 'testthat' and other changes
StuartWheater Oct 28, 2025
c5ff70c
Updates due to 'testthat' changes
StuartWheater Oct 28, 2025
597b2a3
Merge pull request #437 from StuartWheater/v7.0-dev-feat/performance
StuartWheater Oct 28, 2025
004919f
Experimental dealing with 'pull_request_template' issue
StuartWheater Oct 28, 2025
8216d19
Merge branch 'v7.0-dev-feat/performance' of github.com:datashield/dsB…
StuartWheater Oct 28, 2025
e5188a0
Fix regex for pull_request_template in .Rbuildignore
StuartWheater Oct 28, 2025
d37331a
test: call function within correct environment
timcadman Oct 30, 2025
7660589
fixed pull request template in buildignore
timcadman Oct 30, 2025
4867280
added note explaining test setup
timcadman Oct 30, 2025
53eb5dc
Merge branch 'v7.0-dev' into v7.0-dev-feat/performance
timcadman Dec 9, 2025
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
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
^\.circleci/config\.yml$
^\.github$
^cran-comments\.md$
^pull_request_template$
6 changes: 4 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ Imports:
gamlss,
gamlss.dist,
mice,
childsds
childsds,
glue
Suggests:
spelling,
testthat
testthat (>= 3.0.0)
RoxygenNote: 7.3.3
Encoding: UTF-8
Language: en-GB
Config/testthat/edition: 3
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,5 @@ import(gamlss.dist)
import(mice)
importFrom(gamlss.dist,pST3)
importFrom(gamlss.dist,qST3)
importFrom(glue,glue)
importFrom(glue,glue_collapse)
9 changes: 2 additions & 7 deletions R/colnamesDS.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,10 @@
#' @export
#'
colnamesDS <- function(x){

x.val <- eval(parse(text=x), envir = parent.frame())

# find the dim of the input dataframe or matrix
x.val <- .loadServersideObject(x)
.checkClass(obj = x.val, obj_name = x, permitted_classes = c("data.frame", "matrix"))
out <- colnames(x.val)

# return the dimension
return(out)

}
#AGGREGATE FUNCTION
# colnamesDS
42 changes: 42 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#' Load a Server-Side Object by Name
#'
#' Evaluates a character string referring to an object name and returns the corresponding
#' object from the parent environment. If the object does not exist, an error is raised.
#'
#' @param x A character string naming the object to be retrieved.
#' @return The evaluated R object referred to by `x`.
#' @noRd
.loadServersideObject <- function(x) {
tryCatch(
eval(parse(text = x), envir = parent.frame(2)),
error = function(e) {
stop("The server-side object", " '", x, "' ", "does not exist")
}
)
}

#' Check Class of a Server-Side Object
#'
#' Verifies that a given object is of an allowed class. If not, raises an informative error
#' message listing the permitted classes and the actual class of the object.
#'
#' @param obj The object whose class should be checked.
#' @param obj_name A character string with the name of the object (used in error messages).
#' @param permitted_classes A character vector of allowed class names.
#' @importFrom glue glue glue_collapse
#' @return Invisibly returns `TRUE` if the class check passes; otherwise throws an error.
#' @noRd
.checkClass <- function(obj, obj_name, permitted_classes) {
typ <- class(obj)

if (!any(permitted_classes %in% typ)) {
msg <- glue(
"The server-side object must be of type {glue_collapse(permitted_classes, sep = ' or ')}. ",
"'{obj_name}' is type {typ}."
)

stop(msg, call. = FALSE)
}

invisible(TRUE)
}
15 changes: 15 additions & 0 deletions pull_request_template
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Description
[Write a description of the changes you have made]

## Checklist (all items may not apply)

### Refactor
- [ ] Replace `eval(parse(text = x), envir = parent.frame())` with `.loadServersideObject()`
- [ ] Where appropriate, check object class using `.checkClass()
- [ ] Check whether additional checks are required on the server-side

### Testing
- [ ] Writen server-side unit tests for unhappy flow
- [ ] Run and passed `devtools::test(filter = "smk-|disc|arg")`
- [ ] Run and passed `devtools::check(args = '--no-tests')` (we run tests separately to skip performance checks)
- [ ] Run and passed `devtools::build`
8 changes: 4 additions & 4 deletions tests/testthat/perf_files/default_perf_profile.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"refer_name","rate","lower_tolerance","upper_tolerance"
"meanDS::perf::numeric::0","2998.9844","0.5","2"
"meanDS::perf::numberAndNA::0","3027.3963","0.5","2"
"varDS::perf::numeric::0","3124.4088","0.5","2"
"varDS::perf::numberAndNA::0","3146.532","0.5","2"
"meanDS::perf::numeric::0","11557.1204746495","0.5","2"
"meanDS::perf::numberAndNA::0","11718.8520447749","0.5","2"
"varDS::perf::numeric::0","12758.5511531009","0.5","2"
"varDS::perf::numberAndNA::0","12545.8819532662","0.5","2"
8 changes: 4 additions & 4 deletions tests/testthat/perf_files/hp-laptop_quay.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"refer_name","rate","lower_tolerance","upper_tolerance"
"meanDS::perf::numeric::0","8874.24924669612","0.5","2"
"meanDS::perf::numberAndNA::0","8946.22935183172","0.5","2"
"varDS::perf::numeric::0","10029.1022487173","0.5","2"
"varDS::perf::numberAndNA::0","10014.7789085673","0.5","2"
"meanDS::perf::numeric::0","11557.1204746495","0.5","2"
"meanDS::perf::numberAndNA::0","11718.8520447749","0.5","2"
"varDS::perf::numeric::0","12758.5511531009","0.5","2"
"varDS::perf::numberAndNA::0","12545.8819532662","0.5","2"
5 changes: 3 additions & 2 deletions tests/testthat/setup.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved.
# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
#
# This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0.
Expand All @@ -11,7 +12,7 @@
# Datashield test suite set up
#

context("setup - start")
# context("setup - start")

library(RANN)
library(stringr)
Expand All @@ -22,4 +23,4 @@ source("random/set_random_seed_settings.R")

source("perf_tests/perf_rate.R")

context("setup - done")
# context("setup - done")
5 changes: 3 additions & 2 deletions tests/testthat/teardown.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved.
# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
#
# This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0.
Expand All @@ -8,6 +9,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#-------------------------------------------------------------------------------

context("teardown - start")
# context("teardown - start")

context("teardown - done")
# context("teardown - done")
10 changes: 5 additions & 5 deletions tests/testthat/test-arg-asIntegerDS.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2024 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
# Copyright (c) 2024-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
#
# This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0.
Expand All @@ -12,13 +12,13 @@
# Set up
#

context("asIntegerDS::arg::setup")
# context("asIntegerDS::arg::setup")

#
# Tests
#

context("asIntegerDS::arg::direct input numeric")
# context("asIntegerDS::arg::direct input numeric")
test_that("simple asIntegerDS non-input", {
expect_error(asIntegerDS(1.0), "ERROR: x.name must be specified as a character string", fixed = TRUE)
})
Expand All @@ -27,6 +27,6 @@ test_that("simple asIntegerDS non-input", {
# Done
#

context("asIntegerDS::arg::shutdown")
# context("asIntegerDS::arg::shutdown")

context("asIntegerDS::arg::done")
# context("asIntegerDS::arg::done")
13 changes: 7 additions & 6 deletions tests/testthat/test-arg-asLogicalDS.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved.
# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
#
# This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0.
Expand All @@ -12,25 +13,25 @@
# Set up
#

context("asLogicalDS::arg::setup")
# context("asLogicalDS::arg::setup")

#
# Tests
#

context("asLogicalDS::arg::direct input numeric")
# context("asLogicalDS::arg::direct input numeric")
test_that("simple asLogicalDS non-input", {
expect_error(asLogicalDS(1.0), "ERROR: x.name must be specified as a character string", fixed = TRUE)
})

context("asLogicalDS::arg::input NULL")
# context("asLogicalDS::arg::input NULL")
test_that("simple asLogicalDS NULL", {
input <- NULL

expect_error(asLogicalDS("input"), "ERROR: for ds.asLogical function, x.name must specify an input object of class numeric, integer, character or matrix", fixed = TRUE)
})

context("asLogicalDS::arg::input NA")
# context("asLogicalDS::arg::input NA")
test_that("simple asLogicalDS NA", {
input <- NA

Expand All @@ -41,6 +42,6 @@ test_that("simple asLogicalDS NA", {
# Done
#

context("asLogicalDS::arg::shutdown")
# context("asLogicalDS::arg::shutdown")

context("asLogicalDS::arg::done")
# context("asLogicalDS::arg::done")
9 changes: 5 additions & 4 deletions tests/testthat/test-arg-dataFrameFillDS.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved.
# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
#
# This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0.
Expand All @@ -12,13 +13,13 @@
# Set up
#

context("dataFrameFillDS::arg::setup")
# context("dataFrameFillDS::arg::setup")

#
# Tests
#

context("dataFrameFillDS::arg")
# context("dataFrameFillDS::arg")
test_that("simple dataFrameFillDS, ascending, numeric", {
df <- data.frame(v1 = c(-2.0, -3.0, 4.0, 2.0, 1.0, 0.0, -1.0, 3.0), v2 = c(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0))
allNames.transmit <- "v1,v2,v3,v4,v5,v6,v7"
Expand All @@ -45,10 +46,10 @@ test_that("simple dataFrameFillDS, ascending, numeric", {
# Shutdown
#

context("dataFrameFillDS::arg::shutdown")
# context("dataFrameFillDS::arg::shutdown")

#
# Done
#

context("dataFrameFillDS::arg::done")
# context("dataFrameFillDS::arg::done")
9 changes: 5 additions & 4 deletions tests/testthat/test-arg-dataFrameSortDS.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved.
# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
#
# This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0.
Expand All @@ -12,15 +13,15 @@
# Set up
#

context("dataFrameSortDS::arg::setup")
# context("dataFrameSortDS::arg::setup")

set.standard.disclosure.settings()

#
# Tests
#

context("dataFrameSortDS::arg")
# context("dataFrameSortDS::arg")
test_that("simple dataFrameSortDS, factor error check", {
df <- data.frame(v1 = as.factor(c("a", "b", "c", "d", "b", "e", "f", "f")), v2 = c(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0))
sort.key.name <- "df$v1"
Expand All @@ -34,10 +35,10 @@ test_that("simple dataFrameSortDS, factor error check", {
# Shutdown
#

context("dataFrameSortDS::arg::shutdown")
# context("dataFrameSortDS::arg::shutdown")

#
# Done
#

context("dataFrameSortDS::arg::done")
# context("dataFrameSortDS::arg::done")
15 changes: 8 additions & 7 deletions tests/testthat/test-arg-uniqueDS.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved.
# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
#
# This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0.
Expand All @@ -12,29 +13,29 @@
# Set up
#

context("uniqueDS::arg::setup")
# context("uniqueDS::arg::setup")

#
# Tests
#

context("uniqueDS::arg::simple null argument")
# context("uniqueDS::arg::simple null argument")
test_that("simple uniqueDS for NULL", {
expect_error(uniqueDS(NULL), "Variable's name can't be NULL", fixed = TRUE)
})

context("uniqueDS::arg::null value")
# context("uniqueDS::arg::null value")
test_that("simple uniqueDS for NULL", {
input <- NULL
expect_error(uniqueDS("input"), "Variable can't be NULL", fixed = TRUE)
})

context("uniqueDS::arg::not character value")
# context("uniqueDS::arg::not character value")
test_that("simple uniqueDS for NULL", {
expect_error(uniqueDS(17), "Variable's name isn't a single character vector", fixed = TRUE)
})

context("uniqueDS::arg::missing value")
# context("uniqueDS::arg::missing value")
test_that("simple uniqueDS for NULL", {
expect_error(uniqueDS("input"), "object 'input' not found", fixed = TRUE)
})
Expand All @@ -43,6 +44,6 @@ test_that("simple uniqueDS for NULL", {
# Done
#

context("uniqueDS::arg::shutdown")
# context("uniqueDS::arg::shutdown")

context("uniqueDS::arg::done")
# context("uniqueDS::arg::done")
9 changes: 5 additions & 4 deletions tests/testthat/test-disc-meanDS.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved.
# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
#
# This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0.
Expand All @@ -12,15 +13,15 @@
# Set up
#

context("meanDS::disc::setup")
# context("meanDS::disc::setup")

set.standard.disclosure.settings()

#
# Tests
#

context("meanDS::disc::numeric with below nfilter.tab values")
# context("meanDS::disc::numeric with below nfilter.tab values")
test_that("numeric meanDS, with below nfilter.tab values", {
input <- c(NA, NA, 2.0, NA, 4.0)

Expand All @@ -31,6 +32,6 @@ test_that("numeric meanDS, with below nfilter.tab values", {
# Done
#

context("meanDS::disc::shutdown")
# context("meanDS::disc::shutdown")

context("meanDS::disc::done")
# context("meanDS::disc::done")
Loading