1test_that("end-to-end NAMESPACE generation works", {
2  expect_output(roxygenise(test_path("testNamespace"), "namespace", clean = TRUE))
3
4  ns <- read_lines(test_path("testNamespace/NAMESPACE"))
5  expect_length(ns, 4)
6})
7
8# @export -----------------------------------------------------------------
9
10test_that("export quote object name appropriate", {
11  out <- roc_proc_text(namespace_roclet(), "#' @export\na <- function(){}")
12  expect_equal(out, 'export(a)')
13
14  out <- roc_proc_text(namespace_roclet(), "#' @export\n`+` <- function(){}")
15  expect_equal(out, 'export("+")')
16
17  out <- roc_proc_text(namespace_roclet(), "#' @export\n`\\`` <- function(){}")
18  expect_equal(out, 'export("`")')
19})
20
21test_that("export parameter overrides default", {
22  out <- roc_proc_text(namespace_roclet(), "#' @export b\na <- function(){}")
23  expect_equal(out, 'export(b)')
24})
25
26test_that("multiple export parameters generate multiple exports", {
27  out <- roc_proc_text(namespace_roclet(), "
28    #' @export a b
29    a <- function(){}")
30  expect_equal(out, c('export(a)', 'export(b)'))
31})
32
33test_that("export trimmed before line test", {
34  out <- roc_proc_text(namespace_roclet(), "
35    #' @export
36    #'
37    a <- function(){}")
38  expect_equal(out, 'export(a)')
39})
40
41
42test_that("export detects S4 class", {
43  out <- roc_proc_text(namespace_roclet(), "#' @export\nsetClass('a')")
44  expect_equal(out, 'exportClasses(a)')
45})
46
47test_that("export detects S4 generic", {
48  out <- roc_proc_text(namespace_roclet(), "
49    #' @export
50    setGeneric('foo', function(x) standardGeneric('foo'))
51  ")
52  expect_equal(out, 'export(foo)')
53})
54
55
56test_that("export detects S3 method", {
57  out <- roc_proc_text(namespace_roclet(), "#' @export\nmean.foo <- function(x) 'foo'")
58  expect_equal(out, 'S3method(mean,foo)')
59})
60
61test_that("export handles non-syntactic names", {
62  out <- roc_proc_text(namespace_roclet(),  "
63    #' @export
64    `mean.foo-bar` <- function(x) 'foo'
65  ")
66  expect_equal(out, "S3method(mean,\"foo-bar\")")
67
68  out <- roc_proc_text(namespace_roclet(),  "
69    `foo-bar` <- function(x) UseMethod('foo-bar')
70    #' @export
71    `foo-bar.integer` <- function(x) 'foo'
72  ")
73  expect_equal(out, "S3method(\"foo-bar\",integer)")
74})
75
76test_that("@exportS3method generatedsS3method()", {
77  out <- roc_proc_text(namespace_roclet(),
78    "#' @exportS3Method
79    mean.foo <- function(x) 'foo'
80  ")
81  expect_equal(out, "S3method(mean,foo)")
82
83  out <- roc_proc_text(namespace_roclet(),
84    "#' @exportS3Method base::mean
85    mean.foo <- function(x) 'foo'
86  ")
87  expect_equal(out, "S3method(base::mean,foo)")
88
89  expect_warning(
90    roc_proc_text(namespace_roclet(),
91      "#' @exportS3Method base::mean
92      NULL
93    "),
94    "an S3 method"
95  )
96
97  out <- roc_proc_text(namespace_roclet(),
98    "#' @exportS3Method base::mean foo
99    NULL
100  ")
101  expect_equal(out, "S3method(base::mean,foo)")
102
103
104})
105
106test_that("exportClass overrides default class name", {
107  out <- roc_proc_text(namespace_roclet(), "#' @exportClass b\nsetClass('a')")
108  expect_equal(out, 'exportClasses(b)')
109})
110
111test_that("export detects method name", {
112  out <- roc_proc_text(namespace_roclet(), "
113    #' @export\n
114    setMethod('max', 'a', function(x, ...) x[1])")
115  expect_equal(out, 'exportMethods(max)')
116})
117
118test_that("export method escapes if needed", {
119  out <- roc_proc_text(namespace_roclet(), "
120    setGeneric('x<-', function(x, value) standardGeneric('x<-'))
121    #' @export\n
122    setMethod('x<-', 'a', function(x, value) value)")
123  expect_equal(out, 'exportMethods("x<-")')
124})
125
126test_that("export uses name if no object present", {
127  out <- roc_proc_text(namespace_roclet(), "
128    #' Title
129    #'
130    #' @export
131    #' @name x
132    NULL
133  ")
134  expect_equal(out, 'export(x)')
135})
136
137test_that("default export uses exportClass for RC objects", {
138  out <- roc_proc_text(namespace_roclet(), "
139    #' Title
140    #'
141    #' @export
142    x <- setRefClass('X')
143  ")
144  expect_equal(out, 'exportClasses(X)')
145})
146
147test_that("exportMethod overrides default method name", {
148  out <- roc_proc_text(namespace_roclet(), "
149    #' @exportMethod c
150    setMethod('max', 'a', function(x, ...) x[1])")
151  expect_equal(out, 'exportMethods(c)')
152})
153
154test_that("other namespace tags produce correct output", {
155  out <- roc_proc_text(namespace_roclet(), "
156    #' @exportPattern test
157    #' @import test
158    #' @importFrom test test1 test2
159    #' @importClassesFrom test test1 test2
160    #' @importMethodsFrom test test1 test2
161    NULL")
162
163  expect_equal(sort(out), sort(c(
164    "exportPattern(test)",
165    "import(test)",
166    "importFrom(test,test1)",
167    "importFrom(test,test2)",
168    "importClassesFrom(test,test1)",
169    "importClassesFrom(test,test2)",
170    "importMethodsFrom(test,test1)",
171    "importMethodsFrom(test,test2)"
172  )))
173})
174
175test_that("poorly formed importFrom throws error", {
176  expect_warning(roc_proc_text(namespace_roclet(), "
177    #' @importFrom test
178    NULL
179  "), "needs at least 2 words")
180})
181
182test_that("multiline importFrom parsed correctly", {
183  out <- roc_proc_text(namespace_roclet(), "
184    #' @importFrom test test1
185    #'   test2
186    NULL
187  ")
188  expect_equal(sort(out), sort(c(
189    "importFrom(test,test1)",
190    "importFrom(test,test2)"
191  )))
192})
193
194test_that("useDynLib imports only selected functions", {
195  out <- roc_proc_text(namespace_roclet(), "
196    #' @useDynLib test
197    #' @useDynLib test a
198    #' @useDynLib test a b
199    NULL")
200
201    expect_equal(sort(out), sort(
202      c("useDynLib(test)", "useDynLib(test,a)", "useDynLib(test,b)")))
203})
204
205test_that("useDynLib doesn't quote if comma present", {
206  out <- roc_proc_text(namespace_roclet(), "
207    #' @useDynLib test, .registration = TRUE
208    NULL")
209
210  expect_equal(sort(out), "useDynLib(test, .registration = TRUE)")
211})
212
213test_that("empty NAMESPACE generates zero-length vector", {
214  base_path <- test_path("empty")
215
216  env <- pkgload::load_all(base_path)$env
217  blocks <- parse_package(base_path, env = env)
218
219  results <- roclet_process(namespace_roclet(), blocks, env = env, base_path)
220  expect_equal(results, character())
221})
222
223
224# Raw ---------------------------------------------------------------------
225
226
227test_that("rawNamespace must be valid code", {
228  expect_warning(
229    roc_proc_text(namespace_roclet(), "
230      #' @rawNamespace if() {
231      #' @name a
232      NULL"),
233    "code failed to parse"
234  )
235})
236
237test_that("rawNamespace inserted unchanged", {
238  out <- roc_proc_text(namespace_roclet(), "
239    #' @rawNamespace xyz
240    #'   abc
241    NULL")
242
243  expect_equal(out, "xyz\n  abc")
244})
245
246
247# @evalNamespace ----------------------------------------------------------
248
249test_that("evalNamespace generates warning when code is invalid", {
250  expect_warning(
251    roc_proc_text(namespace_roclet(), "
252      #' @evalNamespace a +
253      #' @name a
254      #' @title a
255      NULL"),
256    "code failed to parse"  # Message generated by tag_code
257  )
258})
259
260test_that("evalNamespace generates warning when code raises error", {
261  expect_warning(
262    roc_proc_text(namespace_roclet(), "
263      #' @evalNamespace stop('!')
264      #' @name a
265      #' @title a
266      NULL"),
267    "failed with error"  # From block_eval
268  )
269})
270
271test_that("evalNamespace generates warning when code doesn't eval to string", {
272  # Not character
273  expect_warning(
274    roc_proc_text(namespace_roclet(), "
275      z <- 10
276      #' @evalNamespace z * 2
277      #' @name a
278      #' @title a
279      NULL"),
280    "did not evaluate to a string"  # From block_eval
281  )
282
283  # NA_character_ not allowed
284  expect_warning(
285    roc_proc_text(namespace_roclet(), "
286      nms <- NA_character_
287      #' @evalNamespace nms
288      #' @name a
289      #' @title a
290      NULL"),
291    "result contained NA"  # From block_eval
292  )
293})
294
295test_that("evalNamespace code is inserted when its value is a string", {
296  out1 <- roc_proc_text(namespace_roclet(), "
297    nms <- paste(letters[1:3], collapse = ',')
298    #' @evalNamespace sprintf('export(%s)', nms)
299    #' @name a
300    #' @title a
301    NULL")
302  out2 <- roc_proc_text(namespace_roclet(), "
303    nms <- paste(letters[1:3], collapse = ',')
304    #' @evalNamespace sprintf('export(%s)',
305    #'                        nms)
306    #' @name a
307    #' @title a
308    NULL")
309
310  expect_equal(out1, "export(a,b,c)")
311  expect_equal(out2, "export(a,b,c)")
312})
313
314test_that("evalNamspace can yield a vector", {
315  out <- roc_proc_text(namespace_roclet(), "
316    nms <- letters[1:2]
317    #' @evalNamespace paste0('export(', nms, ')')
318    #' @name a
319    #' @title a
320    NULL")
321
322  expect_equal(out, c("export(a)", "export(b)"))
323})
324
325
326# helpers -----------------------------------------------------------------
327
328test_that("auto_quote behaves as needed", {
329  expect_equal(auto_quote("x"), "x")
330  expect_equal(auto_quote("if"), '"if"') # quotes non-syntactic
331  expect_equal(auto_quote("'if'"), "'if'") # unless already quoted
332})
333