327 lines
10 KiB
Rust
327 lines
10 KiB
Rust
#![allow(non_snake_case)]
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use fix::Evaluator;
|
|
use fix_common::Value;
|
|
use fix_error::{Source, SourceType};
|
|
|
|
fn get_lang_dir() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/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 mut ctx = Evaluator::new();
|
|
let content = std::fs::read_to_string(&nix_path).unwrap();
|
|
let source = Source {
|
|
ty: SourceType::File(nix_path.into()),
|
|
src: content.into(),
|
|
};
|
|
ctx.eval_deep(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_log::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_log::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
|
|
);
|
|
}
|
|
};
|
|
}
|
|
|
|
mod okay {
|
|
use super::*;
|
|
|
|
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!(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!(fromTOML);
|
|
eval_okay_test!(
|
|
#[ignore = "timestamps are not supported"]
|
|
fromTOML_timestamps
|
|
);
|
|
eval_okay_test!(functionargs);
|
|
eval_okay_test!(hashfile);
|
|
eval_okay_test!(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!(groupBy);
|
|
eval_okay_test!(r#if);
|
|
eval_okay_test!(ind_string);
|
|
eval_okay_test!(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!(toxml);
|
|
eval_okay_test!(toxml2);
|
|
eval_okay_test!(tryeval);
|
|
eval_okay_test!(types);
|
|
eval_okay_test!(versions);
|
|
eval_okay_test!(with);
|
|
eval_okay_test!(zipAttrsWith);
|
|
}
|
|
|
|
mod fail {
|
|
use super::*;
|
|
|
|
eval_fail_test!(abort);
|
|
eval_fail_test!(addDrvOutputDependencies_empty_context);
|
|
eval_fail_test!(addDrvOutputDependencies_multi_elem_context);
|
|
eval_fail_test!(addDrvOutputDependencies_wrong_element_kind);
|
|
eval_fail_test!(addErrorRuntime_example);
|
|
eval_fail_test!(assert);
|
|
eval_fail_test!(assert_equal_attrs_names);
|
|
eval_fail_test!(assert_equal_attrs_names_2);
|
|
eval_fail_test!(assert_equal_derivations);
|
|
eval_fail_test!(assert_equal_derivations_extra);
|
|
eval_fail_test!(assert_equal_floats);
|
|
eval_fail_test!(assert_equal_function_direct);
|
|
eval_fail_test!(assert_equal_int_float);
|
|
eval_fail_test!(assert_equal_ints);
|
|
eval_fail_test!(assert_equal_list_length);
|
|
eval_fail_test!(assert_equal_paths);
|
|
eval_fail_test!(assert_equal_type);
|
|
eval_fail_test!(assert_equal_type_nested);
|
|
eval_fail_test!(assert_nested_bool);
|
|
eval_fail_test!(attr_name_type);
|
|
eval_fail_test!(attrset_merge_drops_later_rec);
|
|
eval_fail_test!(bad_string_interpolation_1);
|
|
eval_fail_test!(bad_string_interpolation_2);
|
|
eval_fail_test!(bad_string_interpolation_3);
|
|
eval_fail_test!(bad_string_interpolation_4);
|
|
eval_fail_test!(blackhole);
|
|
eval_fail_test!(call_primop);
|
|
eval_fail_test!(deepseq);
|
|
eval_fail_test!(derivation_name);
|
|
eval_fail_test!(dup_dynamic_attrs);
|
|
eval_fail_test!(duplicate_traces);
|
|
eval_fail_test!(eol_1);
|
|
eval_fail_test!(eol_2);
|
|
eval_fail_test!(eol_3);
|
|
eval_fail_test!(fetchTree_negative);
|
|
eval_fail_test!(fetchurl_baseName);
|
|
eval_fail_test!(fetchurl_baseName_attrs);
|
|
eval_fail_test!(fetchurl_baseName_attrs_name);
|
|
eval_fail_test!(flake_ref_to_string_negative_integer);
|
|
eval_fail_test!(foldlStrict_strict_op_application);
|
|
eval_fail_test!(fromJSON_keyWithNullByte);
|
|
eval_fail_test!(fromJSON_overflowing);
|
|
eval_fail_test!(fromJSON_valueWithNullByte);
|
|
eval_fail_test!(fromTOML_keyWithNullByte);
|
|
eval_fail_test!(fromTOML_timestamps);
|
|
eval_fail_test!(fromTOML_valueWithNullByte);
|
|
eval_fail_test!(hashfile_missing);
|
|
eval_fail_test!(infinite_recursion_lambda);
|
|
eval_fail_test!(list);
|
|
eval_fail_test!(missing_arg);
|
|
eval_fail_test!(mutual_recursion);
|
|
eval_fail_test!(nested_list_items);
|
|
eval_fail_test!(nonexist_path);
|
|
eval_fail_test!(not_throws);
|
|
eval_fail_test!(overflowing_add);
|
|
eval_fail_test!(overflowing_div);
|
|
eval_fail_test!(overflowing_mul);
|
|
eval_fail_test!(overflowing_sub);
|
|
eval_fail_test!(path_slash);
|
|
eval_fail_test!(pipe_operators);
|
|
eval_fail_test!(recursion);
|
|
eval_fail_test!(remove);
|
|
eval_fail_test!(scope_5);
|
|
eval_fail_test!(seq);
|
|
eval_fail_test!(set);
|
|
eval_fail_test!(set_override);
|
|
eval_fail_test!(string_nul_1);
|
|
eval_fail_test!(string_nul_2);
|
|
eval_fail_test!(substring);
|
|
eval_fail_test!(toJSON);
|
|
eval_fail_test!(toJSON_non_utf_8);
|
|
eval_fail_test!(to_path);
|
|
eval_fail_test!(undeclared_arg);
|
|
eval_fail_test!(using_set_as_attr_name);
|
|
}
|