mirror of
https://github.com/neovim/neovim
synced 2025-07-15 00:31:45 +00:00
feat(build): make build.zig run unittests
This commit is contained in:
1
.github/workflows/test.yml
vendored
1
.github/workflows/test.yml
vendored
@ -213,6 +213,7 @@ jobs:
|
||||
- run: sudo apt-get install -y inotify-tools
|
||||
- run: zig build test_nlua0
|
||||
- run: zig build nvim_bin && ./zig-out/bin/nvim --version
|
||||
- run: zig build unittest
|
||||
- run: zig build functionaltest
|
||||
|
||||
windows:
|
||||
|
39
build.zig
39
build.zig
@ -149,6 +149,8 @@ pub fn build(b: *std.Build) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const support_unittests = use_luajit;
|
||||
|
||||
const gen_config = b.addWriteFiles();
|
||||
|
||||
const version_lua = gen_config.add("nvim_version.lua", lua_version_info(b));
|
||||
@ -232,7 +234,7 @@ pub fn build(b: *std.Build) !void {
|
||||
|
||||
// TODO(zig): using getEmittedIncludeTree() is ugly af. we want run_preprocessor()
|
||||
// to use the std.build.Module include_path thing
|
||||
const include_path = &.{
|
||||
const include_path = [_]LazyPath{
|
||||
b.path("src/"),
|
||||
gen_config.getDirectory(),
|
||||
lua.getEmittedIncludeTree(),
|
||||
@ -243,10 +245,10 @@ pub fn build(b: *std.Build) !void {
|
||||
treesitter.artifact("tree-sitter").getEmittedIncludeTree(),
|
||||
};
|
||||
|
||||
const gen_headers, const funcs_data = try gen.nvim_gen_sources(b, nlua0, &nvim_sources, &nvim_headers, &api_headers, include_path, target, versiondef_git, version_lua);
|
||||
const gen_headers, const funcs_data = try gen.nvim_gen_sources(b, nlua0, &nvim_sources, &nvim_headers, &api_headers, &include_path, target, versiondef_git, version_lua);
|
||||
|
||||
const test_config_step = b.addWriteFiles();
|
||||
_ = test_config_step.add("test/cmakeconfig/paths.lua", try test_config(b, gen_headers.getDirectory()));
|
||||
_ = test_config_step.add("test/cmakeconfig/paths.lua", try test_config(b));
|
||||
|
||||
const test_gen_step = b.step("gen_headers", "debug: output generated headers");
|
||||
const config_install = b.addInstallDirectory(.{ .source_dir = gen_config.getDirectory(), .install_dir = .prefix, .install_subdir = "config/" });
|
||||
@ -258,6 +260,7 @@ pub fn build(b: *std.Build) !void {
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
nvim_exe.rdynamic = true; // -E
|
||||
|
||||
nvim_exe.linkLibrary(lua);
|
||||
nvim_exe.linkLibrary(libuv);
|
||||
@ -273,16 +276,31 @@ pub fn build(b: *std.Build) !void {
|
||||
nvim_exe.addIncludePath(gen_headers.getDirectory());
|
||||
build_lua.add_lua_modules(nvim_exe.root_module, lpeg, use_luajit, false);
|
||||
|
||||
const src_paths = try b.allocator.alloc([]u8, nvim_sources.items.len);
|
||||
var unit_test_sources = try std.ArrayList([]u8).initCapacity(b.allocator, 10);
|
||||
if (support_unittests) {
|
||||
var unit_test_fixtures = try src_dir.openDir("test/unit/fixtures/", .{ .iterate = true });
|
||||
defer unit_test_fixtures.close();
|
||||
var it = unit_test_fixtures.iterateAssumeFirstIteration();
|
||||
while (try it.next()) |entry| {
|
||||
if (entry.name.len < 3) continue;
|
||||
if (std.mem.eql(u8, ".c", entry.name[entry.name.len - 2 ..])) {
|
||||
try unit_test_sources.append(b.fmt("test/unit/fixtures/{s}", .{entry.name}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const src_paths = try b.allocator.alloc([]u8, nvim_sources.items.len + unit_test_sources.items.len);
|
||||
for (nvim_sources.items, 0..) |s, i| {
|
||||
src_paths[i] = b.fmt("src/nvim/{s}", .{s.name});
|
||||
}
|
||||
@memcpy(src_paths[nvim_sources.items.len..], unit_test_sources.items);
|
||||
|
||||
const flags = [_][]const u8{
|
||||
"-std=gnu99",
|
||||
"-DINCLUDE_GENERATED_DECLARATIONS",
|
||||
"-DZIG_BUILD",
|
||||
"-D_GNU_SOURCE",
|
||||
if (support_unittests) "-DUNIT_TESTING" else "",
|
||||
if (use_luajit) "" else "-DNVIM_VENDOR_BIT",
|
||||
};
|
||||
nvim_exe.addCSourceFiles(.{ .files = src_paths, .flags = &flags });
|
||||
@ -339,7 +357,9 @@ pub fn build(b: *std.Build) !void {
|
||||
const parser_query = b.dependency("treesitter_query", .{ .target = target, .optimize = optimize });
|
||||
test_deps.dependOn(add_ts_parser(b, "query", parser_query.path("."), false, target, optimize));
|
||||
|
||||
try tests.test_steps(b, nvim_exe, test_deps, lua_dev_deps.path("."), test_config_step.getDirectory());
|
||||
const unit_headers: ?[]const LazyPath = if (support_unittests) &(include_path ++ .{gen_headers.getDirectory()}) else null;
|
||||
|
||||
try tests.test_steps(b, nvim_exe, test_deps, lua_dev_deps.path("."), test_config_step.getDirectory(), unit_headers);
|
||||
}
|
||||
|
||||
pub fn test_fixture(
|
||||
@ -401,7 +421,7 @@ pub fn lua_version_info(b: *std.Build) []u8 {
|
||||
, .{ v.major, v.minor, v.patch, v.prerelease.len > 0, v.api_level, v.api_level_compat, v.api_prerelease });
|
||||
}
|
||||
|
||||
pub fn test_config(b: *std.Build, gen_dir: LazyPath) ![]u8 {
|
||||
pub fn test_config(b: *std.Build) ![]u8 {
|
||||
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||
const src_path = try b.build_root.handle.realpath(".", &buf);
|
||||
|
||||
@ -409,7 +429,6 @@ pub fn test_config(b: *std.Build, gen_dir: LazyPath) ![]u8 {
|
||||
return b.fmt(
|
||||
\\local M = {{}}
|
||||
\\
|
||||
\\M.include_paths = {{}}
|
||||
\\M.apple_sysroot = ""
|
||||
\\M.translations_enabled = "$ENABLE_TRANSLATIONS" == "ON"
|
||||
\\M.is_asan = "$ENABLE_ASAN_UBSAN" == "ON"
|
||||
@ -419,9 +438,9 @@ pub fn test_config(b: *std.Build, gen_dir: LazyPath) ![]u8 {
|
||||
\\M.test_source_path = "{[src_path]s}"
|
||||
\\M.test_lua_prg = ""
|
||||
\\M.test_luajit_prg = ""
|
||||
\\table.insert(M.include_paths, "{[gen_dir]}/include")
|
||||
\\table.insert(M.include_paths, "{[gen_dir]}/src/nvim/auto")
|
||||
\\ -- include path passed on the cmdline, see test/lua_runner.lua
|
||||
\\M.include_paths = _G.c_include_path or {{}}
|
||||
\\
|
||||
\\return M
|
||||
, .{ .bin_dir = b.install_path, .src_path = src_path, .gen_dir = gen_dir });
|
||||
, .{ .bin_dir = b.install_path, .src_path = src_path });
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
local platform = vim.uv.os_uname()
|
||||
local deps_install_dir = table.remove(_G.arg, 1)
|
||||
_G.c_include_path = {}
|
||||
while vim.startswith(_G.arg[1], '-I') do
|
||||
table.insert(_G.c_include_path, string.sub(table.remove(_G.arg, 1), 3))
|
||||
end
|
||||
local subcommand = table.remove(_G.arg, 1)
|
||||
local suffix = (platform and platform.sysname:lower():find 'windows') and '.dll' or '.so'
|
||||
package.path = (deps_install_dir .. '/?.lua;')
|
||||
|
@ -1,14 +1,19 @@
|
||||
const std = @import("std");
|
||||
const LazyPath = std.Build.LazyPath;
|
||||
|
||||
pub fn test_steps(b: *std.Build, nvim_bin: *std.Build.Step.Compile, depend_on: *std.Build.Step, lua_deps: LazyPath, config_dir: LazyPath) !void {
|
||||
pub fn testStep(b: *std.Build, kind: []const u8, nvim_bin: *std.Build.Step.Compile, lua_deps: LazyPath, config_dir: LazyPath, include_path: ?[]const LazyPath) !*std.Build.Step.Run {
|
||||
const test_step = b.addRunArtifact(nvim_bin);
|
||||
test_step.addArg("-ll");
|
||||
test_step.addFileArg(b.path("./test/lua_runner.lua"));
|
||||
test_step.addDirectoryArg(lua_deps);
|
||||
if (include_path) |paths| {
|
||||
for (paths) |path| {
|
||||
test_step.addPrefixedDirectoryArg("-I", path);
|
||||
}
|
||||
}
|
||||
test_step.addArgs(&.{ "busted", "-v", "-o", "test.busted.outputHandlers.nvim", "--lazy" });
|
||||
// TODO(bfredl): a bit funky with paths, should work even if we run "zig build" in a nested dir
|
||||
test_step.addArg("./test/functional/preload.lua"); // TEST_TYPE!!
|
||||
test_step.addArg(b.fmt("./test/{s}/preload.lua", .{kind}));
|
||||
test_step.addArg("--lpath=./src/?.lua");
|
||||
test_step.addArg("--lpath=./runtime/lua/?.lua");
|
||||
test_step.addArg("--lpath=./?.lua");
|
||||
@ -17,11 +22,9 @@ pub fn test_steps(b: *std.Build, nvim_bin: *std.Build.Step.Compile, depend_on: *
|
||||
if (b.args) |args| {
|
||||
test_step.addArgs(args); // accept TEST_FILE as a positional argument
|
||||
} else {
|
||||
test_step.addArg("./test/functional/");
|
||||
test_step.addArg(b.fmt("./test/{s}/", .{kind}));
|
||||
}
|
||||
|
||||
test_step.step.dependOn(depend_on);
|
||||
|
||||
const env = test_step.getEnvMap();
|
||||
try env.put("VIMRUNTIME", "runtime");
|
||||
try env.put("NVIM_RPLUGIN_MANIFEST", "Xtest_xdg/Xtest_rplugin_manifest");
|
||||
@ -33,12 +36,27 @@ pub fn test_steps(b: *std.Build, nvim_bin: *std.Build.Step.Compile, depend_on: *
|
||||
|
||||
env.remove("NVIM");
|
||||
env.remove("XDG_DATA_DIRS");
|
||||
return test_step;
|
||||
}
|
||||
|
||||
pub fn test_steps(b: *std.Build, nvim_bin: *std.Build.Step.Compile, depend_on: *std.Build.Step, lua_deps: LazyPath, config_dir: LazyPath, unit_paths: ?[]const LazyPath) !void {
|
||||
const empty_dir = b.addWriteFiles();
|
||||
_ = empty_dir.add(".touch", "");
|
||||
const tmpdir_create = b.addInstallDirectory(.{ .source_dir = empty_dir.getDirectory(), .install_dir = .prefix, .install_subdir = "Xtest_tmpdir/" });
|
||||
test_step.step.dependOn(&tmpdir_create.step);
|
||||
|
||||
const functionaltest_step = b.step("functionaltest", "run functionaltests");
|
||||
functionaltest_step.dependOn(&test_step.step);
|
||||
const functional_tests = try testStep(b, "functional", nvim_bin, lua_deps, config_dir, null);
|
||||
functional_tests.step.dependOn(depend_on);
|
||||
functional_tests.step.dependOn(&tmpdir_create.step);
|
||||
|
||||
const functionaltest_step = b.step("functionaltest", "run functional tests");
|
||||
functionaltest_step.dependOn(&functional_tests.step);
|
||||
|
||||
if (unit_paths) |paths| {
|
||||
const unit_tests = try testStep(b, "unit", nvim_bin, lua_deps, config_dir, paths);
|
||||
unit_tests.step.dependOn(depend_on);
|
||||
unit_tests.step.dependOn(&tmpdir_create.step);
|
||||
|
||||
const unittest_step = b.step("unittest", "run unit tests");
|
||||
unittest_step.dependOn(&unit_tests.step);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user