Skip to content
Open
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
| `junit_jar` | `string?` | `stdpath("data") .. /nvim/neotest-java/junit-platform-console-standalone-[version].jar` | Path to the JUnit Platform Console standalone JAR. |
| `jvm_args` | `string[]` | `{}` | Additional JVM arguments passed when running tests. |
| `incremental_build` | `boolean` | `true` | Enable incremental compilation before running tests. |
| `disable_update_notifications` | `boolean` | `false` | Disable notifications about available JUnit jar updates. |
| `test_classname_patterns` | `string[]` | `{"^.*Tests?$", "^.*IT$", "^.*Spec$"}` | Regular expressions used to include only classes whose names match these patterns. Classes not matching any pattern will be ignored. |

## :octocat: Contributing
Expand Down
2 changes: 2 additions & 0 deletions lua/neotest-java/context_holder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
return {
--- @type neotest-java.Adapter | nil
adapter = nil,
--- @type boolean
update_notification_shown = false,
}
41 changes: 32 additions & 9 deletions lua/neotest-java/default_config.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
local Path = require("neotest-java.model.path")

local DEFAULT_VERSION = "1.10.1"
local JUNIT_JAR_FILE_NAME = "junit-platform-console-standalone-" .. DEFAULT_VERSION .. ".jar"
local DEFAULT_JUNIT_JAR_PATH = Path(vim.fn.stdpath("data")):append("neotest-java"):append(JUNIT_JAR_FILE_NAME)
local JUNIT_JAR_FILE_NAME = function(version)
return "junit-platform-console-standalone-" .. version .. ".jar"
end
local DEFAULT_JUNIT_JAR_PATH = function(version)
return Path(vim.fn.stdpath("data")):append("neotest-java"):append(JUNIT_JAR_FILE_NAME(version))
end

local SUPPORTED_VERSIONS = {
{
version = "6.0.1",
sha256 = "3009120b7953bfe63add272e65b2bbeca0d41d0dfd8dea605201db15b640e0ff",
},
{
version = "1.10.1",
sha256 = "b42eaa53d13576d17db5fb8b280722a6ae9e36daf95f4262bc6e96d4cb20725f",
},
}
local LATEST_PINNED_VERSION = SUPPORTED_VERSIONS[1]

--- Get supported JUnit versions
--- @return table[]
local function get_supported_versions()
return SUPPORTED_VERSIONS
end

--- @class neotest-java.JunitVersion
--- @field version string
Expand All @@ -15,22 +36,24 @@ local DEFAULT_JUNIT_JAR_PATH = Path(vim.fn.stdpath("data")):append("neotest-java
---@field incremental_build boolean
---@field default_junit_jar_version neotest-java.JunitVersion
---@field test_classname_patterns string[] | nil
---@field disable_update_notifications boolean | nil

---@type neotest-java.ConfigOpts
local default_config = {
default_junit_jar_filepath = DEFAULT_JUNIT_JAR_PATH,
junit_jar = DEFAULT_JUNIT_JAR_PATH,
default_junit_jar_filepath = DEFAULT_JUNIT_JAR_PATH(LATEST_PINNED_VERSION.version),
junit_jar = DEFAULT_JUNIT_JAR_PATH(LATEST_PINNED_VERSION.version),
default_junit_jar_version = LATEST_PINNED_VERSION,
jvm_args = {},
incremental_build = true,
default_junit_jar_version = {
version = DEFAULT_VERSION,
sha256 = "b42eaa53d13576d17db5fb8b280722a6ae9e36daf95f4262bc6e96d4cb20725f",
},
disable_update_notifications = false,
test_classname_patterns = {
"^.*Tests?$",
"^.*IT$",
"^.*Spec$",
},
}

-- Export getter function for supported versions
default_config.get_supported_versions = get_supported_versions

return default_config
141 changes: 122 additions & 19 deletions lua/neotest-java/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,23 @@ local ch = require("neotest-java.context_holder")
local Path = require("neotest-java.model.path")
local nio = require("nio")
local logger = require("neotest-java.logger")
local install = require("neotest-java.install")
local Binaries = require("neotest-java.command.binaries")
local JunitVersionDetector = require("neotest-java.util.junit_version_detector")
local version_detector = JunitVersionDetector({
exists = function(path)
return File.exists(path:to_string())
end,
checksum = function(path)
local f = assert(io.open(path:to_string(), "rb"))
local data = f:read("*a")
f:close()
return vim.fn.sha256(data)
end,
scan = require("neotest-java.util.dir_scan"),
stdpath_data = vim.fn.stdpath,
})
local lib = require("neotest.lib")
local exists = require("neotest.lib.file").exists

local DEFAULT_CONFIG = require("neotest-java.default_config")

Expand All @@ -25,18 +40,6 @@ local build_tools = require("neotest-java.build_tool")
local detect_project_type = require("neotest-java.util.detect_project_type")
local compilers = require("neotest-java.core.spec_builder.compiler")

--- @param filepath neotest-java.Path
local check_junit_jar = function(filepath, default_version)
local _exists, _ = File.exists(filepath:to_string())
assert(
_exists,
([[
Junit Platform Console Standalone jar not found at %s
Please run the following command to download it: NeotestJava setup
Or alternatively, download it from https://repo1.maven.org/maven2/org/junit/platform/junit-platform-console-standalone/%s/junit-platform-console-standalone-%s.jar
]]):format(filepath, default_version, default_version)
)
end

local mkdir = function(dir)
vim.uv.fs_mkdir(dir:to_string(), 493)
Expand All @@ -51,16 +54,22 @@ end
--- @field install fun()
---

---@class neotest-java.CheckJunitJarDeps
---@field file_exists? fun(filepath: string): boolean
---@field version_detector? neotest-java.JunitVersionDetector

--- @class neotest-java.Dependencies
--- @field root_finder { find_root: fun(dir: string): string | nil }
---@field root_finder? { find_root: fun(dir: string): string | nil }
---@field check_junit_jar_deps? neotest-java.CheckJunitJarDeps

--- @param config neotest-java.ConfigOpts
--- @param deps? neotest-java.Dependencies
--- @return neotest-java.Adapter
local function NeotestJavaAdapter(config, deps)
config = config or {}
config = vim.tbl_extend("force", DEFAULT_CONFIG, config or {})
deps = deps or {}
local _root_finder = deps and deps.root_finder or root_finder
local check_junit_jar_deps = deps.check_junit_jar_deps or {}

log.info("neotest-java adapter initialized")

Expand All @@ -69,6 +78,67 @@ local function NeotestJavaAdapter(config, deps)
-- create data directory if it doesn't exist
mkdir(Path(vim.fn.stdpath("data")):append("neotest-java"))

-- Local function to check JUnit jar with dependencies from constructor
--- @param filepath neotest-java.Path
--- @param default_version string
--- @return neotest-java.Path
local check_junit_jar = function(filepath, default_version)
local file_exists_fn = check_junit_jar_deps.file_exists or File.exists
local _exists, _ = file_exists_fn(filepath:to_string())
if not _exists then
-- Try to detect if any supported version exists
local detector = check_junit_jar_deps.version_detector
or JunitVersionDetector({
exists = function(path)
return File.exists(path:to_string())
end,
checksum = function(path)
local f = assert(io.open(path:to_string(), "rb"))
local data = f:read("*a")
f:close()
return vim.fn.sha256(data)
end,
scan = require("neotest-java.util.dir_scan"),
stdpath_data = vim.fn.stdpath,
})
local detected_version, detected_filepath = detector.detect_existing_version()
if detected_version and detected_filepath then
-- Found a supported version, use it
return detected_filepath
end
end
assert(
_exists,
([[
Junit Platform Console Standalone jar not found at %s
Please run the following command to download it: NeotestJava setup
Or alternatively, download it from https://repo1.maven.org/maven2/org/junit/platform/junit-platform-console-standalone/%s/junit-platform-console-standalone-%s.jar
]]):format(filepath, default_version, default_version)
)
return filepath
end

-- Check for JUnit jar updates (only if user hasn't disabled notifications and not already shown)
if not config.disable_update_notifications and not ch.update_notification_shown then
local existing_version, _ = version_detector.detect_existing_version()
if existing_version then
local has_update, latest_version = version_detector.check_for_update(existing_version)
if has_update and latest_version then
-- Mark notification as shown to avoid duplicates
ch.update_notification_shown = true
-- Show notification about available update
lib.notify(
string.format(
"JUnit jar update available: %s → %s. Run :NeotestJava setup to upgrade. (Disable: set disable_update_notifications = true in config)",
existing_version.version,
latest_version.version
),
"info"
)
end
end
end

local cwd = vim.loop.cwd()

--- @type neotest-java.Path|nil
Expand Down Expand Up @@ -118,7 +188,37 @@ local function NeotestJavaAdapter(config, deps)
return setmetatable({

install = function()
install(config)
local Installer = require("neotest-java.install")
local installer = Installer({
exists = exists,
checksum = function(path)
local f = assert(io.open(path:to_string(), "rb"))
local data = f:read("*a")
f:close()
return vim.fn.sha256(data)
end,
download = function(url, output)
local out = vim.system({
"curl",
"--output",
output,
url,
"--create-dirs",
}):wait(10000)
return out
end,
delete_file = vim.fn.delete,
ask_user_consent = function(msg, chs, cb)
vim.ui.select(chs, {
prompt = msg,
}, function(choice)
cb(choice)
end)
end,
notify = lib.notify,
detect_existing_version = version_detector.detect_existing_version,
})
installer.install(config)
end,
config = config,
name = "neotest-java",
Expand All @@ -136,12 +236,15 @@ local function NeotestJavaAdapter(config, deps)
return _root_finder.find_root(dir)
end,
build_spec = function(args)
check_junit_jar(config.junit_jar, config.default_junit_jar_version.version)
return spec_builder_instance.build_spec(args, config)
-- Check if the configured jar exists, if not try to detect any supported version
local actual_jar = check_junit_jar(config.junit_jar, config.default_junit_jar_version.version)
-- Create a config copy with the actual jar to use
local build_config = vim.tbl_extend("force", config, { junit_jar = actual_jar })
return spec_builder_instance.build_spec(args, build_config)
end,
}, {
__call = function(_, opts, user_deps)
local user_opts = vim.tbl_extend("force", config, opts or {})
local user_opts = vim.tbl_extend("force", DEFAULT_CONFIG, opts or {})

if type(user_opts.junit_jar) == "string" then
user_opts.junit_jar = Path(user_opts.junit_jar)
Expand Down
Loading
Loading