blob: 7b4b03480f10e81cf4ca66dfc0afaac4da3c0dd6 [file] [log] [blame]
Marc Kupietza3a8cd92026-09-08 07:59:04 +02001test_that("cacheAsFileName appends .rds where it is missing", {
2 expect_equal(RKorAPClient:::cacheAsFileName("analysis"), "analysis.rds")
3 expect_equal(RKorAPClient:::cacheAsFileName("analysis.rds"), "analysis.rds")
4 expect_equal(RKorAPClient:::cacheAsFileName("analysis.RDS"), "analysis.RDS")
5})
6
Marc Kupietzc6e77362026-09-08 14:07:49 +02007offlineKco <- function() {
8 methods::new(
9 "KorAPConnection",
10 apiUrl = "https://example.invalid/",
11 KorAPUrl = "https://example.invalid/",
12 authorizationSupported = FALSE,
13 verbose = FALSE
14 )
15}
16
17test_that("blessCacheAs makes an old file usable again", {
18 kco <- offlineKco()
19 file <- tempfile(fileext = ".rds")
20 on.exit(unlink(file), add = TRUE)
21 legacy <- tibble::tibble(node = "Test", collocate = "c", logDice = 7)
22 saveRDS(legacy, file)
23
24 testthat::local_mocked_bindings(
25 collocatesQuery = function(...) stop("server must not be contacted"),
26 .package = "RKorAPClient"
27 )
28
29 expect_message(blessCacheAs(file), "records no parameters")
30 expect_silent(result <- collocationAnalysis(kco, "Test", cacheAs = file))
31 expect_equal(result, legacy)
32})
33
34test_that("blessing records itself without claiming a provenance", {
35 file <- tempfile(fileext = ".rds")
36 on.exit(unlink(file), add = TRUE)
37 saveRDS(tibble::tibble(x = 1), file)
38
39 suppressMessages(blessCacheAs(file))
40 info <- cacheAsInfo(file)
41
42 expect_equal(info$scoresConfirmedFor, RKorAPClient:::cacheAsScoreVersion)
43 expect_s3_class(info$blessedAt, "POSIXct")
44 # what actually wrote the file is unknown and stays unclaimed
45 expect_null(info$packageVersion)
46})
47
48test_that("blessCacheAs refuses a file that is not there", {
49 expect_error(blessCacheAs(file.path(tempdir(), "no-such-cache.rds")), "does not exist")
50})
51
Marc Kupietzafac5142026-09-08 10:37:42 +020052test_that("cacheAsInfo says what produced a file", {
53 skip_if_offline()
54 kco <- KorAPConnection(accessToken = NULL, verbose = FALSE)
55 file <- tempfile(fileext = ".rds")
56 on.exit(unlink(file), add = TRUE)
57
58 frequencyQuery(kco, "Ameisenplage", cacheAs = file)
59 info <- cacheAsInfo(file)
60
61 expect_equal(info$packageVersion, as.character(utils::packageVersion("RKorAPClient")))
62 expect_equal(info$apiUrl, kco@apiUrl)
63 expect_equal(info$indexRevision, kco@indexRevision)
64 expect_equal(info$parameters$query, "Ameisenplage")
65 # given without its extension, the .rds file is found
66 expect_equal(cacheAsInfo(sub("\\.rds$", "", file)), info)
67})
68
69test_that("cacheAsInfo has nothing to report for a file from before 1.4.0", {
70 file <- tempfile(fileext = ".rds")
71 on.exit(unlink(file), add = TRUE)
72 saveRDS(tibble::tibble(x = 1), file)
73
74 expect_null(cacheAsInfo(file))
75})
76
77test_that("cacheAsInfo refuses a file that is not there", {
78 expect_error(
79 cacheAsInfo(file.path(tempdir(), "no-such-cache.rds")),
80 "does not exist"
81 )
82})
83
Marc Kupietza3a8cd92026-09-08 07:59:04 +020084test_that("a cache file is written and read back, without contacting the server", {
85 skip_if_offline()
86 kco <- KorAPConnection(accessToken = NULL, verbose = FALSE)
87 dir <- file.path(tempdir(), "cacheAsTest")
88 dir.create(dir, showWarnings = FALSE)
89 on.exit(unlink(dir, recursive = TRUE), add = TRUE)
90
91 # every query function that takes cacheAs, so that one added later without a
92 # cache file of its own does not go unnoticed
93 queries <- list(
94 "frequencyQuery" = function(f) frequencyQuery(kco, "Ameisenplage", cacheAs = f),
95 "corpusStats" = function(f) corpusStats(kco, vc = "pubDate since 2020", as.df = TRUE, cacheAs = f),
96 "collocationScoreQuery" = function(f) collocationScoreQuery(kco, "Grund", "triftiger", cacheAs = f),
97 "textMetadata" = function(f) textMetadata(kco, "WPD17/L79/98721", cacheAs = f)
98 )
99
100 for (name in names(queries)) {
101 query <- queries[[name]]
102 file <- file.path(dir, name)
103
104 fresh <- query(file)
105 expect_true(file.exists(paste0(file, ".rds")), info = name)
106
107 fromCache <- local({
108 testthat::local_mocked_bindings(
109 apiCall = function(...) stop("server must not be contacted"),
110 .package = "RKorAPClient"
111 )
112 query(file)
113 })
114 expect_equal(fromCache, fresh, info = name)
115
116 # what produced the result lives in the file only, not in the value
117 expect_null(attr(fromCache, RKorAPClient:::cacheAsAttribute), info = name)
118 expect_equal(
119 attr(readRDS(paste0(file, ".rds")), RKorAPClient:::cacheAsAttribute)$scoreVersion,
120 RKorAPClient:::cacheAsScoreVersion,
121 info = name
122 )
123 }
124})
125
126test_that("a cache file written before the scores were corrected is refused", {
127 skip_if_offline()
128 kco <- KorAPConnection(accessToken = NULL, verbose = FALSE)
129 file <- tempfile(fileext = ".rds")
130 on.exit(unlink(file), add = TRUE)
131
132 frequencyQuery(kco, "Ameisenplage", cacheAs = file)
133 aged <- readRDS(file)
134 record <- attr(aged, RKorAPClient:::cacheAsAttribute)
135 # as a file from before the corrections has it: an older score generation, and
136 # an older version to go with it
137 record$scoreVersion <- "1.3.0"
138 record$packageVersion <- "1.3.0"
139 attr(aged, RKorAPClient:::cacheAsAttribute) <- record
140 saveRDS(aged, file)
141
142 expect_warning(frequencyQuery(kco, "Ameisenplage", cacheAs = file), "1\\.3\\.0")
143 # and the refused file is replaced by a current one, so the warning comes once
144 expect_silent(frequencyQuery(kco, "Ameisenplage", cacheAs = file))
145})
146
147test_that("a query that differs is recomputed rather than read back", {
148 skip_if_offline()
149 kco <- KorAPConnection(accessToken = NULL, verbose = FALSE)
150 file <- tempfile(fileext = ".rds")
151 on.exit(unlink(file), add = TRUE)
152
153 frequencyQuery(kco, "Ameisenplage", cacheAs = file)
154 expect_warning(frequencyQuery(kco, "Heuschreckenplage", cacheAs = file), "query")
155})
156
157test_that("verbosity is not part of what a cache file records", {
158 skip_if_offline()
159 kco <- KorAPConnection(accessToken = NULL, verbose = FALSE)
160 file <- tempfile(fileext = ".rds")
161 on.exit(unlink(file), add = TRUE)
162
163 corpusStats(kco, vc = "pubDate since 2020", as.df = TRUE, cacheAs = file)
164 # how loud a query is does not change what it returns, so it must not make
165 # the file be thrown away
166 expect_silent(
167 corpusStats(kco, vc = "pubDate since 2020", as.df = TRUE, verbose = TRUE, cacheAs = file)
168 )
169})