Skip to content

Commit ea57f87

Browse files
committed
java install mocked tests
1 parent c4f16ed commit ea57f87

3 files changed

Lines changed: 208 additions & 5 deletions

File tree

R/java_install.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#' Install Java from a distribution file
2-
#'
2+
#'
33
#' @description
44
#' Unpack Java distribution file into cache directory and link the installation into a project directory, optionally setting the `JAVA_HOME` and `PATH` environment variables to the Java version that was just installed.
55
#'
@@ -121,6 +121,7 @@ java_install <- function(
121121
unlink(project_version_path, recursive = TRUE)
122122
}
123123
file.symlink(installed_path, project_version_path)
124+
link_success <- TRUE # <--- THIS IS THE ONLY CHANGE
124125
},
125126
warning = function(w) {
126127
if (!quiet) cli::cli_inform("Warning: {w}")
Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,33 @@
11
# This file is run automatically by testthat before tests are run.
22
# It's a good place for mocks that are used across multiple test files.
33

4-
# Mock the slow network call to java_valid_versions() for all tests
5-
# that don't need to test this function's specific behavior.
6-
# The mock will be active for the entire test run because of this file's
7-
# special 'setup-*' name.
4+
# Mock the slow network call to java_valid_versions()
85
local_mocked_bindings(
96
java_valid_versions = function(...) c("8", "11", "17", "21")
107
)
8+
9+
# Mock common dependencies for java_install() tests
10+
local_mocked_bindings(
11+
# Assume user consent is always given in tests
12+
rje_consent_check = function() TRUE,
13+
# Assume java_unpack always succeeds and returns a predictable path.
14+
# We are not testing java_unpack here.
15+
# CORRECTED: This mock is now self-contained and does not depend on global options.
16+
java_unpack = function(java_distrib_path, ...) {
17+
filename <- basename(java_distrib_path)
18+
parts <- strsplit(gsub("\\.tar\\.gz|\\.zip", "", filename), "-")[[1]]
19+
version <- parts[parts %in% c("8", "11", "17", "21")][1]
20+
arch <- parts[parts %in% c("x64", "aarch64")][1]
21+
platform <- parts[parts %in% c("linux", "windows", "macos")][1]
22+
23+
# Use a generic, hardcoded root path instead of calling getOption().
24+
# This makes the mock independent of the state being tested.
25+
file.path(
26+
"/mock/cache/path",
27+
"installed",
28+
platform,
29+
arch,
30+
version
31+
)
32+
}
33+
)
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# Mocked unit tests for java_install()
2+
# NOTE: Common mocks (java_valid_versions, rje_consent_check, java_unpack)
3+
# are defined globally in the setup-mock-globals.R file.
4+
5+
test_that("java_install succeeds with symlink on Unix-like systems", {
6+
# This test is for non-Windows behavior
7+
skip_on_os("windows")
8+
9+
local_proj_path <- withr::local_tempdir(pattern = "project")
10+
local_cache_path <- withr::local_tempdir(pattern = "cache")
11+
withr::local_options(rJavaEnv.cache_path = local_cache_path)
12+
13+
fake_distrib_path <- file.path(
14+
local_cache_path,
15+
"distrib",
16+
"amazon-corretto-21-x64-linux-jdk.tar.gz"
17+
)
18+
# The global mock will generate the unpacked path based on the distrib path
19+
fake_unpacked_path <- java_unpack(fake_distrib_path)
20+
expected_symlink_path <- file.path(
21+
local_proj_path,
22+
"rjavaenv",
23+
"linux",
24+
"x64",
25+
"21"
26+
)
27+
28+
env_set_calls <- 0
29+
local_mocked_bindings(
30+
java_env_set = function(...) {
31+
env_set_calls <<- env_set_calls + 1
32+
}
33+
)
34+
35+
symlink_calls <- 0
36+
symlink_args <- list()
37+
local_mocked_bindings(
38+
file.symlink = function(from, to) {
39+
symlink_calls <<- symlink_calls + 1
40+
symlink_args <<- list(from = from, to = to)
41+
},
42+
.package = "base"
43+
)
44+
45+
return_val <- java_install(
46+
java_distrib_path = fake_distrib_path,
47+
project_path = local_proj_path,
48+
quiet = TRUE
49+
)
50+
51+
expect_equal(env_set_calls, 1)
52+
expect_equal(symlink_calls, 1)
53+
expect_equal(symlink_args$from, fake_unpacked_path)
54+
expect_equal(symlink_args$to, expected_symlink_path)
55+
expect_equal(return_val, fake_unpacked_path)
56+
})
57+
58+
59+
test_that("java_install falls back to file.copy when symlink fails on Unix", {
60+
skip_on_os("windows")
61+
62+
local_proj_path <- withr::local_tempdir()
63+
local_cache_path <- withr::local_tempdir()
64+
withr::local_options(rJavaEnv.cache_path = local_cache_path)
65+
66+
fake_distrib_path <- file.path(
67+
local_cache_path,
68+
"distrib",
69+
"amazon-corretto-21-x64-linux-jdk.tar.gz"
70+
)
71+
72+
local_mocked_bindings(java_env_set = function(...) TRUE)
73+
74+
local_mocked_bindings(
75+
file.symlink = function(from, to) stop("Permission denied"),
76+
.package = "base"
77+
)
78+
79+
copy_calls <- 0
80+
local_mocked_bindings(
81+
file.copy = function(from, to, ...) {
82+
if (grepl(basename(local_proj_path), to, fixed = TRUE)) {
83+
copy_calls <<- copy_calls + 1
84+
}
85+
TRUE
86+
},
87+
.package = "base"
88+
)
89+
90+
java_install(
91+
java_distrib_path = fake_distrib_path,
92+
project_path = local_proj_path,
93+
quiet = TRUE
94+
)
95+
96+
expect_equal(copy_calls, 1)
97+
})
98+
99+
100+
test_that("java_install respects autoset_java_env = FALSE", {
101+
local_proj_path <- withr::local_tempdir()
102+
local_cache_path <- withr::local_tempdir()
103+
withr::local_options(rJavaEnv.cache_path = local_cache_path)
104+
105+
fake_distrib_path <- file.path(
106+
local_cache_path,
107+
"distrib",
108+
"amazon-corretto-21-x64-linux-jdk.tar.gz"
109+
)
110+
111+
# CORRECTED: Add an explicit mock for java_unpack for this test
112+
# to prevent the real function from being called and issuing a warning.
113+
local_mocked_bindings(
114+
java_unpack = function(...) {
115+
# Return a simple, predictable path string
116+
"/mock/cache/path/installed/linux/x64/21"
117+
}
118+
)
119+
120+
# Mock file.symlink to succeed
121+
local_mocked_bindings(
122+
file.symlink = function(...) TRUE,
123+
.package = "base"
124+
)
125+
126+
# Mock java_env_set to fail the test if it's ever called
127+
local_mocked_bindings(
128+
java_env_set = function(...) {
129+
stop("java_env_set should not have been called!")
130+
}
131+
)
132+
133+
# This test will now pass silently because java_unpack is properly mocked.
134+
expect_silent(
135+
java_install(
136+
java_distrib_path = fake_distrib_path,
137+
project_path = local_proj_path,
138+
autoset_java_env = FALSE,
139+
quiet = TRUE
140+
)
141+
)
142+
})
143+
144+
145+
test_that("java_install succeeds with mklink junction on Windows", {
146+
skip_on_os("mac")
147+
skip_on_os("linux")
148+
skip_on_os("solaris")
149+
150+
local_proj_path <- withr::local_tempdir()
151+
local_cache_path <- withr::local_tempdir()
152+
withr::local_options(rJavaEnv.cache_path = local_cache_path)
153+
154+
fake_distrib_path <- file.path(
155+
local_cache_path,
156+
"distrib",
157+
"amazon-corretto-21-x64-windows-jdk.zip"
158+
)
159+
160+
local_mocked_bindings(java_env_set = function(...) TRUE)
161+
162+
system2_args <- list()
163+
local_mocked_bindings(
164+
system2 = function(command, args, ...) {
165+
system2_args <<- list(command = command, args = args)
166+
"Junction created for ... " # Simulate success message
167+
},
168+
.package = "base"
169+
)
170+
171+
java_install(
172+
java_distrib_path = fake_distrib_path,
173+
project_path = local_proj_path,
174+
quiet = TRUE
175+
)
176+
177+
expect_equal(system2_args$command, "cmd.exe")
178+
expect_true(grepl("mklink /J", system2_args$args[2]))
179+
})

0 commit comments

Comments
 (0)