use super::*;
use crate::snippets::types::{SnippetMetadata, SnippetStatus, SourceOrigin};
const TOOLCHAIN_TEST_TIMEOUT_SECS: u64 = 120;
fn package_fingerprint(name: &[u8]) -> u64 {
let name_crc = crc32_ieee(name);
let mut id: u32 = 0x811c_9dc5;
for byte in name {
id ^= *byte as u32;
id = id.wrapping_mul(0x0100_0193);
}
if id == 0 || id == 0xffff_ffff {
id = 0x1;
}
((name_crc as u64) << 32) | (id as u64)
}
fn build_system_project() -> (tempfile::TempDir, ValidationSession) {
let directory = tempfile::tempdir().expect("project directory");
let root = directory.path();
std::fs::create_dir_all(root.join("src")).unwrap();
std::fs::write(
root.join("build.zig"),
"const std = @import(\"std\");\n\npub fn build(b: *std.Build) void {\n \
const target = b.standardTargetOptions(.{});\n \
const optimize = b.standardOptimizeOption(.{});\n \
_ = b.addModule(\"sample_binding\", .{\n \
.root_source_file = b.path(\"src/root.zig\"),\n \
.target = target,\n \
.optimize = optimize,\n \
});\n}\n",
)
.unwrap();
std::fs::write(root.join("src/root.zig"), "pub fn value() i32 {\n return 42;\n}\n").unwrap();
let fingerprint = package_fingerprint(b"sample_binding");
std::fs::write(
root.join("build.zig.zon"),
format!(
".{{\n .name = .sample_binding,\n .version = \"0.0.0\",\n \
.fingerprint = 0x{fingerprint:016x},\n \
.minimum_zig_version = \"0.16.0\",\n \
.paths = .{{ \"build.zig\", \"build.zig.zon\", \"src\" }},\n}}\n"
),
)
.unwrap();
let session = ValidationSession {
language: Language::Zig,
working_directory: root.to_path_buf(),
manifest: Some(root.join("build.zig")),
fingerprint: "build-system-project".into(),
env: std::collections::BTreeMap::new(),
include_paths: vec![root.join("vendor/include")],
rust_features: Vec::new(),
rust_dependencies: std::collections::BTreeMap::new(),
};
(directory, session)
}
fn build_system_snippet() -> Snippet {
let path = std::path::PathBuf::from("snippet.zig");
Snippet {
id: None,
path: path.clone(),
language: Language::Zig,
title: None,
code: "const sample_binding = @import(\"sample_binding\");\n\npub fn main() void {\n \
_ = sample_binding.value();\n}\n"
.into(),
start_line: 1,
block_index: 0,
annotation: None,
metadata: SnippetMetadata::default(),
source_origin: SourceOrigin {
path,
line: 1,
block_index: 0,
},
}
}
#[test]
fn session_include_paths_are_not_forwarded_to_the_build_system_command() {
if which::which("zig").is_err() {
return;
}
let (_directory, session) = build_system_project();
let snippet = build_system_snippet();
let (status, output) = ZigValidator
.validate_in_session(
&snippet,
ValidationLevel::Compile,
TOOLCHAIN_TEST_TIMEOUT_SECS,
Some(&session),
)
.expect("validation runs");
assert_eq!(
status,
SnippetStatus::Pass,
"a nonempty session.include_paths must not be forwarded as `-I` to `zig build \
--build-file`, which rejects it outright: {output:?}"
);
}