349 lines
10 KiB
Rust
349 lines
10 KiB
Rust
#![allow(non_snake_case)]
|
|
|
|
mod utils;
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use nix_js::context::Context;
|
|
use nix_js::error::Source;
|
|
use nix_js::value::Value;
|
|
|
|
fn get_lang_dir() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/lang")
|
|
}
|
|
|
|
fn eval_file(name: &str) -> Result<(Value, Source), String> {
|
|
let lang_dir = get_lang_dir();
|
|
let nix_path = lang_dir.join(format!("{name}.nix"));
|
|
|
|
let expr = format!(r#"import "{}""#, nix_path.display());
|
|
|
|
let mut ctx = Context::new().map_err(|e| e.to_string())?;
|
|
let source = Source {
|
|
ty: nix_js::error::SourceType::File(nix_path.into()),
|
|
src: expr.into(),
|
|
};
|
|
ctx.eval_code(source.clone())
|
|
.map(|val| (val, source))
|
|
.map_err(|e| e.to_string())
|
|
}
|
|
|
|
fn read_expected(name: &str) -> String {
|
|
let lang_dir = get_lang_dir();
|
|
let exp_path = lang_dir.join(format!("{name}.exp"));
|
|
std::fs::read_to_string(exp_path)
|
|
.expect("expected file should exist")
|
|
.trim_end()
|
|
.to_string()
|
|
}
|
|
|
|
fn format_value(value: &Value) -> String {
|
|
value.display_compat().to_string()
|
|
}
|
|
|
|
macro_rules! eval_okay_test {
|
|
($(#[$attr:meta])* $name:ident$(, $pre:expr)?) => {
|
|
$(#[$attr])*
|
|
#[test]
|
|
fn $name() {
|
|
$(($pre)();)?
|
|
let test_name = concat!("eval-okay-", stringify!($name))
|
|
.replace("_", "-")
|
|
.replace("r#", "");
|
|
let result = eval_file(&test_name);
|
|
match result {
|
|
Ok((value, source)) => {
|
|
let actual = format_value(&value);
|
|
let actual = actual.replace(
|
|
source
|
|
.get_dir()
|
|
.parent()
|
|
.unwrap()
|
|
.to_string_lossy()
|
|
.as_ref(),
|
|
"/pwd",
|
|
);
|
|
let expected = read_expected(&test_name);
|
|
assert_eq!(actual, expected, "Output mismatch for {}", test_name);
|
|
}
|
|
Err(e) => {
|
|
panic!("Test {} failed to evaluate: {}", test_name, e);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! eval_fail_test {
|
|
($name:ident) => {
|
|
#[test]
|
|
fn $name() {
|
|
let test_name = concat!("eval-fail-", stringify!($name))
|
|
.replace("_", "-")
|
|
.replace("r#", "");
|
|
let result = eval_file(&test_name);
|
|
assert!(
|
|
result.is_err(),
|
|
"Test {} should have failed but succeeded with: {:?}",
|
|
test_name,
|
|
result
|
|
);
|
|
}
|
|
};
|
|
}
|
|
|
|
eval_okay_test!(any_all);
|
|
eval_okay_test!(arithmetic);
|
|
eval_okay_test!(attrnames);
|
|
eval_okay_test!(attrs);
|
|
eval_okay_test!(attrs2);
|
|
eval_okay_test!(attrs3);
|
|
eval_okay_test!(attrs4);
|
|
eval_okay_test!(attrs5);
|
|
eval_okay_test!(
|
|
#[ignore = "__overrides is not supported"]
|
|
attrs6
|
|
);
|
|
eval_okay_test!(
|
|
#[ignore = "requires --arg/--argstr CLI flags"]
|
|
autoargs
|
|
);
|
|
eval_okay_test!(backslash_newline_1);
|
|
eval_okay_test!(backslash_newline_2);
|
|
eval_okay_test!(baseNameOf);
|
|
eval_okay_test!(builtins);
|
|
eval_okay_test!(builtins_add);
|
|
eval_okay_test!(callable_attrs);
|
|
eval_okay_test!(catattrs);
|
|
eval_okay_test!(closure);
|
|
eval_okay_test!(comments);
|
|
eval_okay_test!(concat);
|
|
eval_okay_test!(concatmap);
|
|
eval_okay_test!(concatstringssep);
|
|
eval_okay_test!(context);
|
|
eval_okay_test!(context_introspection);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: convertHash"]
|
|
convertHash
|
|
);
|
|
eval_okay_test!(curpos);
|
|
eval_okay_test!(deepseq);
|
|
eval_okay_test!(delayed_with);
|
|
eval_okay_test!(delayed_with_inherit);
|
|
eval_okay_test!(deprecate_cursed_or);
|
|
eval_okay_test!(derivation_legacy);
|
|
eval_okay_test!(dynamic_attrs);
|
|
eval_okay_test!(dynamic_attrs_2);
|
|
eval_okay_test!(dynamic_attrs_bare);
|
|
eval_okay_test!(elem);
|
|
eval_okay_test!(empty_args);
|
|
eval_okay_test!(eq);
|
|
eval_okay_test!(eq_derivations);
|
|
eval_okay_test!(filter);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: flakeRefToString"]
|
|
flake_ref_to_string
|
|
);
|
|
eval_okay_test!(flatten);
|
|
eval_okay_test!(float);
|
|
eval_okay_test!(floor_ceil);
|
|
eval_okay_test!(foldlStrict);
|
|
eval_okay_test!(foldlStrict_lazy_elements);
|
|
eval_okay_test!(foldlStrict_lazy_initial_accumulator);
|
|
eval_okay_test!(fromjson);
|
|
eval_okay_test!(fromjson_escapes);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: fromTOML"]
|
|
fromTOML
|
|
);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: fromTOML"]
|
|
fromTOML_timestamps
|
|
);
|
|
eval_okay_test!(functionargs);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: hashFile"]
|
|
hashfile
|
|
);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: hashString"]
|
|
hashstring
|
|
);
|
|
eval_okay_test!(getattrpos);
|
|
eval_okay_test!(getattrpos_functionargs);
|
|
eval_okay_test!(getattrpos_undefined);
|
|
eval_okay_test!(getenv, || {
|
|
unsafe { std::env::set_var("TEST_VAR", "foo") };
|
|
});
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: hashString"]
|
|
groupBy
|
|
);
|
|
eval_okay_test!(r#if);
|
|
eval_okay_test!(ind_string);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: scopedImport"]
|
|
import
|
|
);
|
|
eval_okay_test!(inherit_attr_pos);
|
|
eval_okay_test!(
|
|
#[ignore = "__overrides is not supported"]
|
|
inherit_from
|
|
);
|
|
eval_okay_test!(intersectAttrs);
|
|
eval_okay_test!(r#let);
|
|
eval_okay_test!(list);
|
|
eval_okay_test!(listtoattrs);
|
|
eval_okay_test!(logic);
|
|
eval_okay_test!(map);
|
|
eval_okay_test!(mapattrs);
|
|
eval_okay_test!(merge_dynamic_attrs);
|
|
eval_okay_test!(nested_with);
|
|
eval_okay_test!(new_let);
|
|
eval_okay_test!(null_dynamic_attrs);
|
|
eval_okay_test!(
|
|
#[ignore = "__overrides is not supported"]
|
|
overrides
|
|
);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: parseFlakeRef"]
|
|
parse_flake_ref
|
|
);
|
|
eval_okay_test!(partition);
|
|
eval_okay_test!(path);
|
|
eval_okay_test!(pathexists);
|
|
eval_okay_test!(path_string_interpolation, || {
|
|
unsafe {
|
|
std::env::set_var("HOME", "/fake-home");
|
|
}
|
|
});
|
|
eval_okay_test!(patterns);
|
|
eval_okay_test!(print);
|
|
eval_okay_test!(readDir);
|
|
eval_okay_test!(readfile);
|
|
eval_okay_test!(readFileType);
|
|
eval_okay_test!(redefine_builtin);
|
|
eval_okay_test!(regex_match);
|
|
eval_okay_test!(regex_split);
|
|
eval_okay_test!(regression_20220122);
|
|
eval_okay_test!(regression_20220125);
|
|
eval_okay_test!(regrettable_rec_attrset_merge);
|
|
eval_okay_test!(remove);
|
|
eval_okay_test!(repeated_empty_attrs);
|
|
eval_okay_test!(repeated_empty_list);
|
|
eval_okay_test!(replacestrings);
|
|
eval_okay_test!(
|
|
#[ignore = "requires -I CLI flags"]
|
|
search_path
|
|
);
|
|
eval_okay_test!(scope_1);
|
|
eval_okay_test!(scope_2);
|
|
eval_okay_test!(scope_3);
|
|
eval_okay_test!(scope_4);
|
|
eval_okay_test!(scope_6);
|
|
eval_okay_test!(scope_7);
|
|
eval_okay_test!(seq);
|
|
eval_okay_test!(sort);
|
|
eval_okay_test!(splitversion);
|
|
eval_okay_test!(string);
|
|
eval_okay_test!(strings_as_attrs_names);
|
|
eval_okay_test!(substring);
|
|
eval_okay_test!(substring_context);
|
|
eval_okay_test!(symlink_resolution);
|
|
eval_okay_test!(
|
|
#[ignore = "TCO not implemented, also disabled in CppNix"]
|
|
tail_call_1
|
|
);
|
|
eval_okay_test!(tojson);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: toXML"]
|
|
toxml
|
|
);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: toXML"]
|
|
toxml2
|
|
);
|
|
eval_okay_test!(tryeval);
|
|
eval_okay_test!(types);
|
|
eval_okay_test!(versions);
|
|
eval_okay_test!(with);
|
|
eval_okay_test!(
|
|
#[ignore = "not implemented: hashString"]
|
|
zipAttrsWith
|
|
);
|
|
|
|
eval_fail_test!(fail_abort);
|
|
eval_fail_test!(fail_addDrvOutputDependencies_empty_context);
|
|
eval_fail_test!(fail_addDrvOutputDependencies_multi_elem_context);
|
|
eval_fail_test!(fail_addDrvOutputDependencies_wrong_element_kind);
|
|
eval_fail_test!(fail_addErrorContext_example);
|
|
eval_fail_test!(fail_assert);
|
|
eval_fail_test!(fail_assert_equal_attrs_names);
|
|
eval_fail_test!(fail_assert_equal_attrs_names_2);
|
|
eval_fail_test!(fail_assert_equal_derivations);
|
|
eval_fail_test!(fail_assert_equal_derivations_extra);
|
|
eval_fail_test!(fail_assert_equal_floats);
|
|
eval_fail_test!(fail_assert_equal_function_direct);
|
|
eval_fail_test!(fail_assert_equal_int_float);
|
|
eval_fail_test!(fail_assert_equal_ints);
|
|
eval_fail_test!(fail_assert_equal_list_length);
|
|
eval_fail_test!(fail_assert_equal_paths);
|
|
eval_fail_test!(fail_assert_equal_type);
|
|
eval_fail_test!(fail_assert_equal_type_nested);
|
|
eval_fail_test!(fail_assert_nested_bool);
|
|
eval_fail_test!(fail_attr_name_type);
|
|
eval_fail_test!(fail_attrset_merge_drops_later_rec);
|
|
eval_fail_test!(fail_bad_string_interpolation_1);
|
|
eval_fail_test!(fail_bad_string_interpolation_2);
|
|
eval_fail_test!(fail_bad_string_interpolation_3);
|
|
eval_fail_test!(fail_bad_string_interpolation_4);
|
|
eval_fail_test!(fail_blackhole);
|
|
eval_fail_test!(fail_call_primop);
|
|
eval_fail_test!(fail_deepseq);
|
|
eval_fail_test!(fail_derivation_name);
|
|
eval_fail_test!(fail_dup_dynamic_attrs);
|
|
eval_fail_test!(fail_duplicate_traces);
|
|
eval_fail_test!(fail_eol_1);
|
|
eval_fail_test!(fail_eol_2);
|
|
eval_fail_test!(fail_eol_3);
|
|
eval_fail_test!(fail_fetchTree_negative);
|
|
eval_fail_test!(fail_fetchurl_baseName);
|
|
eval_fail_test!(fail_fetchurl_baseName_attrs);
|
|
eval_fail_test!(fail_fetchurl_baseName_attrs_name);
|
|
eval_fail_test!(fail_flake_ref_to_string_negative_integer);
|
|
eval_fail_test!(fail_foldlStrict_strict_op_application);
|
|
eval_fail_test!(fail_fromJSON_keyWithNullByte);
|
|
eval_fail_test!(fail_fromJSON_overflowing);
|
|
eval_fail_test!(fail_fromJSON_valueWithNullByte);
|
|
eval_fail_test!(fail_fromTOML_keyWithNullByte);
|
|
eval_fail_test!(fail_fromTOML_timestamps);
|
|
eval_fail_test!(fail_fromTOML_valueWithNullByte);
|
|
eval_fail_test!(fail_hashfile_missing);
|
|
eval_fail_test!(fail_infinite_recursion_lambda);
|
|
eval_fail_test!(fail_list);
|
|
eval_fail_test!(fail_missing_arg);
|
|
eval_fail_test!(fail_mutual_recursion);
|
|
eval_fail_test!(fail_nested_list_items);
|
|
eval_fail_test!(fail_nonexist_path);
|
|
eval_fail_test!(fail_not_throws);
|
|
eval_fail_test!(fail_overflowing_add);
|
|
eval_fail_test!(fail_overflowing_div);
|
|
eval_fail_test!(fail_overflowing_mul);
|
|
eval_fail_test!(fail_overflowing_sub);
|
|
eval_fail_test!(fail_path_slash);
|
|
eval_fail_test!(fail_pipe_operators);
|
|
eval_fail_test!(fail_recursion);
|
|
eval_fail_test!(fail_remove);
|
|
eval_fail_test!(fail_scope_5);
|
|
eval_fail_test!(fail_seq);
|
|
eval_fail_test!(fail_set);
|
|
eval_fail_test!(fail_set_override);
|
|
eval_fail_test!(fail_string_nul_1);
|
|
eval_fail_test!(fail_string_nul_2);
|
|
eval_fail_test!(fail_substring);
|
|
eval_fail_test!(fail_toJSON);
|
|
eval_fail_test!(fail_toJSON_non_utf_8);
|
|
eval_fail_test!(fail_to_path);
|
|
eval_fail_test!(fail_undeclared_arg);
|
|
eval_fail_test!(fail_using_set_as_attr_name);
|