feat: NamedSource

This commit is contained in:
2026-01-20 18:54:19 +08:00
parent e310133421
commit 2cb85529c9
19 changed files with 225 additions and 292 deletions

View File

@@ -1,25 +1,24 @@
mod utils;
use nix_js::context::Context;
use nix_js::error::Source;
use nix_js::value::Value;
use crate::utils::{eval, eval_result};
#[test]
fn import_absolute_path() {
let mut ctx = Context::new().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let lib_path = temp_dir.path().join("nix_test_lib.nix");
std::fs::write(&lib_path, "{ add = a: b: a + b; }").unwrap();
let expr = format!(r#"(import "{}").add 3 5"#, lib_path.display());
assert_eq!(ctx.eval_code(&expr).unwrap(), Value::Int(8));
assert_eq!(eval(&expr), Value::Int(8));
}
#[test]
fn import_nested() {
let mut ctx = Context::new().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let lib_path = temp_dir.path().join("lib.nix");
@@ -33,13 +32,11 @@ fn import_nested() {
std::fs::write(&main_path, main_content).unwrap();
let expr = format!(r#"(import "{}").result"#, main_path.display());
assert_eq!(ctx.eval_code(&expr).unwrap(), Value::Int(30));
assert_eq!(eval(&expr), Value::Int(30));
}
#[test]
fn import_relative_path() {
let mut ctx = Context::new().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let subdir = temp_dir.path().join("subdir");
std::fs::create_dir_all(&subdir).unwrap();
@@ -63,27 +60,24 @@ fn import_relative_path() {
std::fs::write(&main_path, main_content).unwrap();
let expr = format!(r#"let x = import "{}"; in x.result1"#, main_path.display());
assert_eq!(ctx.eval_code(&expr).unwrap(), Value::Int(12));
assert_eq!(eval(&expr), Value::Int(12));
let expr = format!(r#"let x = import "{}"; in x.result2"#, main_path.display());
assert_eq!(ctx.eval_code(&expr).unwrap(), Value::Int(7));
assert_eq!(eval(&expr), Value::Int(7));
}
#[test]
fn import_returns_function() {
let mut ctx = Context::new().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let func_path = temp_dir.path().join("nix_test_func.nix");
std::fs::write(&func_path, "x: x * 2").unwrap();
let expr = format!(r#"(import "{}") 5"#, func_path.display());
assert_eq!(ctx.eval_code(&expr).unwrap(), Value::Int(10));
assert_eq!(eval(&expr), Value::Int(10));
}
#[test]
fn import_with_complex_dependency_graph() {
let mut ctx = Context::new().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let utils_path = temp_dir.path().join("utils.nix");
@@ -98,7 +92,7 @@ fn import_with_complex_dependency_graph() {
std::fs::write(&main_path, main_content).unwrap();
let expr = format!(r#"import "{}""#, main_path.display());
assert_eq!(ctx.eval_code(&expr).unwrap(), Value::Int(15));
assert_eq!(eval(&expr), Value::Int(15));
}
// Tests for builtins.path
@@ -111,7 +105,7 @@ fn path_with_file() {
std::fs::write(&test_file, "Hello, World!").unwrap();
let expr = format!(r#"builtins.path {{ path = {}; }}"#, test_file.display());
let result = ctx.eval_code(&expr).unwrap();
let result = ctx.eval_code(Source::new_eval(expr).unwrap()).unwrap();
// Should return a store path string
if let Value::String(store_path) = result {
@@ -124,7 +118,6 @@ fn path_with_file() {
#[test]
fn path_with_custom_name() {
let mut ctx = Context::new().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let test_file = temp_dir.path().join("original.txt");
std::fs::write(&test_file, "Content").unwrap();
@@ -133,7 +126,7 @@ fn path_with_custom_name() {
r#"builtins.path {{ path = {}; name = "custom-name"; }}"#,
test_file.display()
);
let result = ctx.eval_code(&expr).unwrap();
let result = eval(&expr);
if let Value::String(store_path) = result {
assert!(store_path.contains("custom-name"));
@@ -156,7 +149,7 @@ fn path_with_directory_recursive() {
r#"builtins.path {{ path = {}; recursive = true; }}"#,
test_dir.display()
);
let result = ctx.eval_code(&expr).unwrap();
let result = ctx.eval_code(Source::new_eval(expr).unwrap()).unwrap();
if let Value::String(store_path) = result {
assert!(store_path.starts_with(ctx.get_store_dir()));
@@ -177,7 +170,7 @@ fn path_flat_with_file() {
r#"builtins.path {{ path = {}; recursive = false; }}"#,
test_file.display()
);
let result = ctx.eval_code(&expr).unwrap();
let result = ctx.eval_code(Source::new_eval(expr).unwrap()).unwrap();
if let Value::String(store_path) = result {
assert!(store_path.starts_with(ctx.get_store_dir()));
@@ -188,7 +181,6 @@ fn path_flat_with_file() {
#[test]
fn path_flat_with_directory_fails() {
let mut ctx = Context::new().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let test_dir = temp_dir.path().join("mydir");
std::fs::create_dir_all(&test_dir).unwrap();
@@ -197,7 +189,7 @@ fn path_flat_with_directory_fails() {
r#"builtins.path {{ path = {}; recursive = false; }}"#,
test_dir.display()
);
let result = ctx.eval_code(&expr);
let result = eval_result(&expr);
assert!(result.is_err());
let err_msg = result.unwrap_err().to_string();
@@ -206,10 +198,8 @@ fn path_flat_with_directory_fails() {
#[test]
fn path_nonexistent_fails() {
let mut ctx = Context::new().unwrap();
let expr = r#"builtins.path { path = "/nonexistent/path/that/should/not/exist"; }"#;
let result = ctx.eval_code(expr);
let result = eval_result(expr);
assert!(result.is_err());
let err_msg = result.unwrap_err().to_string();
@@ -218,10 +208,8 @@ fn path_nonexistent_fails() {
#[test]
fn path_missing_path_param() {
let mut ctx = Context::new().unwrap();
let expr = r#"builtins.path { name = "test"; }"#;
let result = ctx.eval_code(expr);
let result = eval_result(expr);
assert!(result.is_err());
let err_msg = result.unwrap_err().to_string();
@@ -230,14 +218,13 @@ fn path_missing_path_param() {
#[test]
fn path_with_sha256() {
let mut ctx = Context::new().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let test_file = temp_dir.path().join("hash_test.txt");
std::fs::write(&test_file, "Test content for hashing").unwrap();
// First, get the hash by calling without sha256
let expr1 = format!(r#"builtins.path {{ path = {}; }}"#, test_file.display());
let result1 = ctx.eval_code(&expr1).unwrap();
let result1 = eval(&expr1);
let store_path1 = match result1 {
Value::String(s) => s,
_ => panic!("Expected string"),
@@ -246,7 +233,7 @@ fn path_with_sha256() {
// Compute the actual hash (for testing, we'll just verify the same path is returned)
// In real usage, the user would know the hash beforehand
let expr2 = format!(r#"builtins.path {{ path = {}; }}"#, test_file.display());
let result2 = ctx.eval_code(&expr2).unwrap();
let result2 = eval(&expr2);
let store_path2 = match result2 {
Value::String(s) => s,
_ => panic!("Expected string"),
@@ -258,7 +245,6 @@ fn path_with_sha256() {
#[test]
fn path_deterministic() {
let mut ctx = Context::new().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let test_file = temp_dir.path().join("deterministic.txt");
std::fs::write(&test_file, "Same content").unwrap();
@@ -268,8 +254,8 @@ fn path_deterministic() {
test_file.display()
);
let result1 = ctx.eval_code(&expr).unwrap();
let result2 = ctx.eval_code(&expr).unwrap();
let result1 = eval(&expr);
let result2 = eval(&expr);
// Same inputs should produce same store path
assert_eq!(result1, result2);