feat: use CppNix's test suite

This commit is contained in:
2026-01-30 11:18:25 +08:00
parent 1f835e7b06
commit aee46b0b49
414 changed files with 5109 additions and 8 deletions

View File

@@ -117,15 +117,9 @@ impl Debug for AttrSet {
impl Display for AttrSet {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
use Value::*;
write!(f, "{{")?;
for (k, v) in self.data.iter() {
write!(f, " {k} = ")?;
match v {
List(_) => write!(f, "[ ... ];")?,
AttrSet(_) => write!(f, "{{ ... }};")?,
v => write!(f, "{v};")?,
}
write!(f, " {k} = {v};")?;
}
write!(f, " }}")
}
@@ -199,7 +193,20 @@ impl Display for Value {
&Float(x) => write!(f, "{x}"),
&Bool(x) => write!(f, "{x}"),
Null => write!(f, "null"),
String(x) => write!(f, r#""{x}""#),
String(x) => {
write!(f, "\"")?;
for c in x.chars() {
match c {
'\\' => write!(f, "\\\\")?,
'"' => write!(f, "\\\"")?,
'\n' => write!(f, "\\n")?,
'\r' => write!(f, "\\r")?,
'\t' => write!(f, "\\t")?,
c => write!(f, "{c}")?,
}
}
write!(f, "\"")
}
Path(x) => write!(f, "{x}"),
AttrSet(x) => write!(f, "{x}"),
List(x) => write!(f, "{x}"),

273
nix-js/tests/lang.rs Normal file
View File

@@ -0,0 +1,273 @@
#![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, 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::new_eval(expr).map_err(|e| e.to_string())?;
ctx.eval_code(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.to_string()
}
macro_rules! eval_okay_test {
($(#[$attr:meta])* $name:ident) => {
$(#[$attr])*
#[test]
fn $name() {
let test_name = concat!("eval-okay-", stringify!($name))
.replace("_", "-")
.replace("r#", "");
let result = eval_file(&test_name);
match result {
Ok(value) => {
let actual = format_value(&value);
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);
eval_okay_test!(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!(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!(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);
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!(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);

View File

@@ -0,0 +1 @@
"a"

View File

@@ -0,0 +1 @@
"X"

View File

@@ -0,0 +1 @@
"b"

View File

@@ -0,0 +1 @@
"X"

View File

@@ -0,0 +1 @@
"X"

View File

@@ -0,0 +1 @@
"c"

View File

@@ -0,0 +1 @@
"X"

View File

@@ -0,0 +1 @@
"X"

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'abort' builtin
at /pwd/lang/eval-fail-abort.nix:1:14:
1| if true then abort "this should fail" else 1
| ^
2|
error: evaluation aborted with the following error message: 'this should fail'

View File

@@ -0,0 +1 @@
if true then abort "this should fail" else 1

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'addDrvOutputDependencies' builtin
at /pwd/lang/eval-fail-addDrvOutputDependencies-empty-context.nix:1:1:
1| builtins.addDrvOutputDependencies ""
| ^
2|
error: context of string '' must have exactly one element, but has 0

View File

@@ -0,0 +1 @@
builtins.addDrvOutputDependencies ""

View File

@@ -0,0 +1,9 @@
error:
… while calling the 'addDrvOutputDependencies' builtin
at /pwd/lang/eval-fail-addDrvOutputDependencies-multi-elem-context.nix:25:1:
24| in
25| builtins.addDrvOutputDependencies combo-path
| ^
26|
error: context of string '/nix/store/pg9yqs4yd85yhdm3f4i5dyaqp5jahrsz-fail.drv/nix/store/2dxd5frb715z451vbf7s8birlf3argbk-fail-2.drv' must have exactly one element, but has 2

View File

@@ -0,0 +1,25 @@
let
drv0 = derivation {
name = "fail";
builder = "/bin/false";
system = "x86_64-linux";
outputs = [
"out"
"foo"
];
};
drv1 = derivation {
name = "fail-2";
builder = "/bin/false";
system = "x86_64-linux";
outputs = [
"out"
"foo"
];
};
combo-path = "${drv0.drvPath}${drv1.drvPath}";
in
builtins.addDrvOutputDependencies combo-path

View File

@@ -0,0 +1,9 @@
error:
… while calling the 'addDrvOutputDependencies' builtin
at /pwd/lang/eval-fail-addDrvOutputDependencies-wrong-element-kind.nix:13:1:
12| in
13| builtins.addDrvOutputDependencies drv.outPath
| ^
14|
error: `addDrvOutputDependencies` can only act on derivations, not on a derivation output such as 'out'

View File

@@ -0,0 +1,13 @@
let
drv = derivation {
name = "fail";
builder = "/bin/false";
system = "x86_64-linux";
outputs = [
"out"
"foo"
];
};
in
builtins.addDrvOutputDependencies drv.outPath

View File

@@ -0,0 +1,24 @@
error:
… while counting down; n = 10
… while counting down; n = 9
… while counting down; n = 8
… while counting down; n = 7
… while counting down; n = 6
… while counting down; n = 5
… while counting down; n = 4
… while counting down; n = 3
… while counting down; n = 2
… while counting down; n = 1
(stack trace truncated; use '--show-trace' to show the full, detailed trace)
error: kaboom

View File

@@ -0,0 +1,9 @@
let
countDown =
n:
if n == 0 then
throw "kaboom"
else
builtins.addErrorContext "while counting down; n = ${toString n}" ("x" + countDown (n - 1));
in
countDown 10

View File

@@ -0,0 +1,8 @@
error:
… while evaluating the condition of the assertion '({ a = true; } == { a = true; b = true; })'
at /pwd/lang/eval-fail-assert-equal-attrs-names-2.nix:1:1:
1| assert
| ^
2| {
error: attribute names of attribute set '{ a = true; }' differs from attribute set '{ a = true; b = true; }'

View File

@@ -0,0 +1,8 @@
assert
{
a = true;
} == {
a = true;
b = true;
};
throw "unreachable"

View File

@@ -0,0 +1,8 @@
error:
… while evaluating the condition of the assertion '({ a = true; b = true; } == { a = true; })'
at /pwd/lang/eval-fail-assert-equal-attrs-names.nix:1:1:
1| assert
| ^
2| {
error: attribute names of attribute set '{ a = true; b = true; }' differs from attribute set '{ a = true; }'

View File

@@ -0,0 +1,8 @@
assert
{
a = true;
b = true;
} == {
a = true;
};
throw "unreachable"

View File

@@ -0,0 +1,26 @@
error:
… while evaluating the condition of the assertion '({ foo = { outPath = "/nix/store/0"; type = "derivation"; }; } == { foo = { devious = true; outPath = "/nix/store/1"; type = "derivation"; }; })'
at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:1:1:
1| assert
| ^
2| {
… while comparing attribute 'foo'
… where left hand side is
at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:3:5:
2| {
3| foo = {
| ^
4| type = "derivation";
… where right hand side is
at /pwd/lang/eval-fail-assert-equal-derivations-extra.nix:8:5:
7| } == {
8| foo = {
| ^
9| type = "derivation";
… while comparing a derivation by its 'outPath' attribute
error: string '"/nix/store/0"' is not equal to string '"/nix/store/1"'

View File

@@ -0,0 +1,14 @@
assert
{
foo = {
type = "derivation";
outPath = "/nix/store/0";
};
} == {
foo = {
type = "derivation";
outPath = "/nix/store/1";
devious = true;
};
};
throw "unreachable"

View File

@@ -0,0 +1,26 @@
error:
… while evaluating the condition of the assertion '({ foo = { ignored = (abort "not ignored"); outPath = "/nix/store/0"; type = "derivation"; }; } == { foo = { ignored = (abort "not ignored"); outPath = "/nix/store/1"; type = "derivation"; }; })'
at /pwd/lang/eval-fail-assert-equal-derivations.nix:1:1:
1| assert
| ^
2| {
… while comparing attribute 'foo'
… where left hand side is
at /pwd/lang/eval-fail-assert-equal-derivations.nix:3:5:
2| {
3| foo = {
| ^
4| type = "derivation";
… where right hand side is
at /pwd/lang/eval-fail-assert-equal-derivations.nix:9:5:
8| } == {
9| foo = {
| ^
10| type = "derivation";
… while comparing a derivation by its 'outPath' attribute
error: string '"/nix/store/0"' is not equal to string '"/nix/store/1"'

View File

@@ -0,0 +1,15 @@
assert
{
foo = {
type = "derivation";
outPath = "/nix/store/0";
ignored = abort "not ignored";
};
} == {
foo = {
type = "derivation";
outPath = "/nix/store/1";
ignored = abort "not ignored";
};
};
throw "unreachable"

View File

@@ -0,0 +1,22 @@
error:
… while evaluating the condition of the assertion '({ b = 1; } == { b = 1.01; })'
at /pwd/lang/eval-fail-assert-equal-floats.nix:1:1:
1| assert { b = 1.0; } == { b = 1.01; };
| ^
2| abort "unreachable"
… while comparing attribute 'b'
… where left hand side is
at /pwd/lang/eval-fail-assert-equal-floats.nix:1:10:
1| assert { b = 1.0; } == { b = 1.01; };
| ^
2| abort "unreachable"
… where right hand side is
at /pwd/lang/eval-fail-assert-equal-floats.nix:1:26:
1| assert { b = 1.0; } == { b = 1.01; };
| ^
2| abort "unreachable"
error: a float with value '1' is not equal to a float with value '1.01'

View File

@@ -0,0 +1,2 @@
assert { b = 1.0; } == { b = 1.01; };
abort "unreachable"

View File

@@ -0,0 +1,9 @@
error:
… while evaluating the condition of the assertion '((x: x) == (x: x))'
at /pwd/lang/eval-fail-assert-equal-function-direct.nix:3:1:
2| # This only compares a direct comparison and makes no claims about functions in nested structures.
3| assert (x: x) == (x: x);
| ^
4| abort "unreachable"
error: distinct functions and immediate comparisons of identical functions compare as unequal

View File

@@ -0,0 +1,4 @@
# Note: functions in nested structures, e.g. attributes, may be optimized away by pointer identity optimization.
# This only compares a direct comparison and makes no claims about functions in nested structures.
assert (x: x) == (x: x);
abort "unreachable"

View File

@@ -0,0 +1,8 @@
error:
… while evaluating the condition of the assertion '(1 == 1.1)'
at /pwd/lang/eval-fail-assert-equal-int-float.nix:1:1:
1| assert 1 == 1.1;
| ^
2| throw "unreachable"
error: an integer with value '1' is not equal to a float with value '1.1'

View File

@@ -0,0 +1,2 @@
assert 1 == 1.1;
throw "unreachable"

View File

@@ -0,0 +1,22 @@
error:
… while evaluating the condition of the assertion '({ b = 1; } == { b = 2; })'
at /pwd/lang/eval-fail-assert-equal-ints.nix:1:1:
1| assert { b = 1; } == { b = 2; };
| ^
2| abort "unreachable"
… while comparing attribute 'b'
… where left hand side is
at /pwd/lang/eval-fail-assert-equal-ints.nix:1:10:
1| assert { b = 1; } == { b = 2; };
| ^
2| abort "unreachable"
… where right hand side is
at /pwd/lang/eval-fail-assert-equal-ints.nix:1:24:
1| assert { b = 1; } == { b = 2; };
| ^
2| abort "unreachable"
error: an integer with value '1' is not equal to an integer with value '2'

View File

@@ -0,0 +1,2 @@
assert { b = 1; } == { b = 2; };
abort "unreachable"

View File

@@ -0,0 +1,8 @@
error:
… while evaluating the condition of the assertion '([ (1) (0) ] == [ (10) ])'
at /pwd/lang/eval-fail-assert-equal-list-length.nix:1:1:
1| assert
| ^
2| [
error: list of size '2' is not equal to list of size '1', left hand side is '[ 1 0 ]', right hand side is '[ 10 ]'

View File

@@ -0,0 +1,6 @@
assert
[
1
0
] == [ 10 ];
throw "unreachable"

View File

@@ -0,0 +1,8 @@
error:
… while evaluating the condition of the assertion '(/pwd/lang/foo == /pwd/lang/bar)'
at /pwd/lang/eval-fail-assert-equal-paths.nix:1:1:
1| assert ./foo == ./bar;
| ^
2| throw "unreachable"
error: path '/pwd/lang/foo' is not equal to path '/pwd/lang/bar'

View File

@@ -0,0 +1,2 @@
assert ./foo == ./bar;
throw "unreachable"

View File

@@ -0,0 +1,22 @@
error:
… while evaluating the condition of the assertion '({ ding = false; } == { ding = null; })'
at /pwd/lang/eval-fail-assert-equal-type-nested.nix:1:1:
1| assert { ding = false; } == { ding = null; };
| ^
2| abort "unreachable"
… while comparing attribute 'ding'
… where left hand side is
at /pwd/lang/eval-fail-assert-equal-type-nested.nix:1:10:
1| assert { ding = false; } == { ding = null; };
| ^
2| abort "unreachable"
… where right hand side is
at /pwd/lang/eval-fail-assert-equal-type-nested.nix:1:31:
1| assert { ding = false; } == { ding = null; };
| ^
2| abort "unreachable"
error: a Boolean of value 'false' is not equal to null of value 'null'

View File

@@ -0,0 +1,2 @@
assert { ding = false; } == { ding = null; };
abort "unreachable"

View File

@@ -0,0 +1,8 @@
error:
… while evaluating the condition of the assertion '(false == null)'
at /pwd/lang/eval-fail-assert-equal-type.nix:1:1:
1| assert false == null;
| ^
2| abort "unreachable"
error: a Boolean of value 'false' is not equal to null of value 'null'

View File

@@ -0,0 +1,2 @@
assert false == null;
abort "unreachable"

View File

@@ -0,0 +1,66 @@
error:
… while evaluating the condition of the assertion '({ a = { b = [ ({ c = { d = true; }; }) ]; }; } == { a = { b = [ ({ c = { d = false; }; }) ]; }; })'
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:1:
1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
| ^
2|
… while comparing attribute 'a'
… where left hand side is
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:10:
1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
| ^
2|
… where right hand side is
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:44:
1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
| ^
2|
… while comparing attribute 'b'
… where left hand side is
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:10:
1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
| ^
2|
… where right hand side is
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:44:
1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
| ^
2|
… while comparing list element 0
… while comparing attribute 'c'
… where left hand side is
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:20:
1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
| ^
2|
… where right hand side is
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:54:
1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
| ^
2|
… while comparing attribute 'd'
… where left hand side is
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:20:
1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
| ^
2|
… where right hand side is
at /pwd/lang/eval-fail-assert-nested-bool.nix:1:54:
1| assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
| ^
2|
error: boolean 'true' is not equal to boolean 'false'

View File

@@ -0,0 +1,3 @@
assert { a.b = [ { c.d = true; } ]; } == { a.b = [ { c.d = false; } ]; };
abort "unreachable"

View File

@@ -0,0 +1,30 @@
error:
… while evaluating the attribute 'body'
at /pwd/lang/eval-fail-assert.nix:7:3:
6|
7| body = x "x";
| ^
8| }
… from call site
at /pwd/lang/eval-fail-assert.nix:7:10:
6|
7| body = x "x";
| ^
8| }
… while calling 'x'
at /pwd/lang/eval-fail-assert.nix:3:5:
2| x =
3| arg:
| ^
4| assert arg == "y";
… while evaluating the condition of the assertion '(arg == "y")'
at /pwd/lang/eval-fail-assert.nix:4:5:
3| arg:
4| assert arg == "y";
| ^
5| 123;
error: string '"x"' is not equal to string '"y"'

View File

@@ -0,0 +1,8 @@
let {
x =
arg:
assert arg == "y";
123;
body = x "x";
}

View File

@@ -0,0 +1,21 @@
error:
… while evaluating the attribute 'puppy."${key}"'
at /pwd/lang/eval-fail-attr-name-type.nix:3:5:
2| attrs = {
3| puppy.doggy = { };
| ^
4| };
… while evaluating an attribute name
at /pwd/lang/eval-fail-attr-name-type.nix:7:15:
6| in
7| attrs.puppy.${key}
| ^
8|
error: expected a string but found an integer: 1
at /pwd/lang/eval-fail-attr-name-type.nix:7:15:
6| in
7| attrs.puppy.${key}
| ^
8|

View File

@@ -0,0 +1,7 @@
let
attrs = {
puppy.doggy = { };
};
key = 1;
in
attrs.puppy.${key}

View File

@@ -0,0 +1,6 @@
error: undefined variable 'd'
at /pwd/lang/eval-fail-attrset-merge-drops-later-rec.nix:4:9:
3| a = rec {
4| c = d + 2;
| ^
5| d = 3;

View File

@@ -0,0 +1,8 @@
{
a.b = 1;
a = rec {
c = d + 2;
d = 3;
};
}
.c

View File

@@ -0,0 +1,8 @@
error:
… while evaluating a path segment
at /pwd/lang/eval-fail-bad-string-interpolation-1.nix:1:2:
1| "${x: x}"
| ^
2|
error: cannot coerce a function to a string: «lambda @ /pwd/lang/eval-fail-bad-string-interpolation-1.nix:1:4»

View File

@@ -0,0 +1 @@
"${x: x}"

View File

@@ -0,0 +1 @@
error: path '/pwd/lang/fnord' does not exist

View File

@@ -0,0 +1 @@
"${./fnord}"

View File

@@ -0,0 +1,8 @@
error:
… while evaluating a path segment
at /pwd/lang/eval-fail-bad-string-interpolation-3.nix:1:3:
1| ''${x: x}''
| ^
2|
error: cannot coerce a function to a string: «lambda @ /pwd/lang/eval-fail-bad-string-interpolation-3.nix:1:5»

View File

@@ -0,0 +1 @@
''${x: x}''

View File

@@ -0,0 +1,9 @@
error:
… while evaluating a path segment
at /pwd/lang/eval-fail-bad-string-interpolation-4.nix:19:3:
18| # The error message should not be too long.
19| ''${pkgs}''
| ^
20|
error: cannot coerce a set to a string: { a = { a = { a = { a = "ha"; b = "ha"; c = "ha"; d = "ha"; e = "ha"; f = "ha"; g = "ha"; h = "ha"; j = "ha"; }; «8 attributes elided» }; «8 attributes elided» }; «8 attributes elided» }

View File

@@ -0,0 +1,19 @@
let
# Basically a "billion laughs" attack, but toned down to simulated `pkgs`.
ha = x: y: {
a = x y;
b = x y;
c = x y;
d = x y;
e = x y;
f = x y;
g = x y;
h = x y;
j = x y;
};
has = ha (ha (ha (ha (x: x)))) "ha";
# A large structure that has already been evaluated.
pkgs = builtins.deepSeq has has;
in
# The error message should not be too long.
''${pkgs}''

View File

@@ -0,0 +1,14 @@
error:
… while evaluating the attribute 'body'
at /pwd/lang/eval-fail-blackhole.nix:2:3:
1| let {
2| body = x;
| ^
3| x = y;
error: infinite recursion encountered
at /pwd/lang/eval-fail-blackhole.nix:3:7:
2| body = x;
3| x = y;
| ^
4| y = x;

View File

@@ -0,0 +1,5 @@
let {
body = x;
x = y;
y = x;
}

View File

@@ -0,0 +1,10 @@
error:
… while calling the 'length' builtin
at /pwd/lang/eval-fail-call-primop.nix:1:1:
1| builtins.length 1
| ^
2|
… while evaluating the first argument passed to builtins.length
error: expected a list but found an integer: 1

View File

@@ -0,0 +1 @@
builtins.length 1

View File

@@ -0,0 +1,20 @@
error:
… while calling the 'deepSeq' builtin
at /pwd/lang/eval-fail-deepseq.nix:1:1:
1| builtins.deepSeq { x = abort "foo"; } 456
| ^
2|
… while evaluating the attribute 'x'
at /pwd/lang/eval-fail-deepseq.nix:1:20:
1| builtins.deepSeq { x = abort "foo"; } 456
| ^
2|
… while calling the 'abort' builtin
at /pwd/lang/eval-fail-deepseq.nix:1:24:
1| builtins.deepSeq { x = abort "foo"; } 456
| ^
2|
error: evaluation aborted with the following error message: 'foo'

View File

@@ -0,0 +1 @@
builtins.deepSeq { x = abort "foo"; } 456

View File

@@ -0,0 +1,26 @@
error:
… while evaluating the attribute 'outPath'
at <nix/derivation-internal.nix>:<number>:<number>:
<number>| value = commonAttrs // {
<number>| outPath = builtins.getAttr outputName strict;
| ^
<number>| drvPath = strict.drvPath;
… while calling the 'getAttr' builtin
at <nix/derivation-internal.nix>:<number>:<number>:
<number>| value = commonAttrs // {
<number>| outPath = builtins.getAttr outputName strict;
| ^
<number>| drvPath = strict.drvPath;
… while calling the 'derivationStrict' builtin
at <nix/derivation-internal.nix>:<number>:<number>:
<number>|
<number>| strict = derivationStrict drvAttrs;
| ^
<number>|
… while evaluating derivation '~jiggle~'
whose name attribute is located at /pwd/lang/eval-fail-derivation-name.nix:<number>:<number>
error: invalid derivation name: name '~jiggle~' contains illegal character '~'. Please pass a different 'name'.

View File

@@ -0,0 +1,5 @@
derivation {
name = "~jiggle~";
system = "some-system";
builder = "/dontcare";
}

View File

@@ -0,0 +1,14 @@
error:
… while evaluating the attribute 'set'
at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:2:3:
1| {
2| set = {
| ^
3| "${"" + "b"}" = 1;
error: dynamic attribute 'b' already defined at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:3:5
at /pwd/lang/eval-fail-dup-dynamic-attrs.nix:6:5:
5| set = {
6| "${"b" + ""}" = 2;
| ^
7| };

View File

@@ -0,0 +1,8 @@
{
set = {
"${"" + "b"}" = 1;
};
set = {
"${"b" + ""}" = 2;
};
}

View File

@@ -0,0 +1,51 @@
error:
… from call site
at /pwd/lang/eval-fail-duplicate-traces.nix:6:1:
5| in
6| throwAfter 2
| ^
7|
… while calling 'throwAfter'
at /pwd/lang/eval-fail-duplicate-traces.nix:4:16:
3| let
4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!";
| ^
5| in
… from call site
at /pwd/lang/eval-fail-duplicate-traces.nix:4:33:
3| let
4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!";
| ^
5| in
… while calling 'throwAfter'
at /pwd/lang/eval-fail-duplicate-traces.nix:4:16:
3| let
4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!";
| ^
5| in
… from call site
at /pwd/lang/eval-fail-duplicate-traces.nix:4:33:
3| let
4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!";
| ^
5| in
… while calling 'throwAfter'
at /pwd/lang/eval-fail-duplicate-traces.nix:4:16:
3| let
4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!";
| ^
5| in
… while calling the 'throw' builtin
at /pwd/lang/eval-fail-duplicate-traces.nix:4:57:
3| let
4| throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!";
| ^
5| in
error: Uh oh!

View File

@@ -0,0 +1,6 @@
# Check that we only omit duplicate stack traces when there's a bunch of them.
# Here, there's only a couple duplicate entries, so we output them all.
let
throwAfter = n: if n > 0 then throwAfter (n - 1) else throw "Uh oh!";
in
throwAfter 2

View File

@@ -0,0 +1,6 @@
error: undefined variable 'invalid'
at /pwd/lang/eval-fail-eol-1.nix:2:1:
1| # foo
2| invalid
| ^
3| # bar

View File

@@ -0,0 +1,3 @@
# foo
invalid
# bar

View File

@@ -0,0 +1,6 @@
error: undefined variable 'invalid'
at /pwd/lang/eval-fail-eol-2.nix:2:1:
1| # foo
2| invalid
| ^
3| # bar

View File

@@ -0,0 +1,2 @@
# foo
invalid

View File

@@ -0,0 +1,6 @@
error: undefined variable 'invalid'
at /pwd/lang/eval-fail-eol-3.nix:2:1:
1| # foo
2| invalid
| ^
3| # bar

View File

@@ -0,0 +1,3 @@
# foo
invalid
# bar

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'fetchTree' builtin
at /pwd/lang/eval-fail-fetchTree-negative.nix:1:1:
1| builtins.fetchTree {
| ^
2| type = "file";
error: negative value given for 'fetchTree' argument 'owner': -1

View File

@@ -0,0 +1,5 @@
builtins.fetchTree {
type = "file";
url = "file://eval-fail-fetchTree-negative.nix";
owner = -1;
}

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'fetchurl' builtin
at /pwd/lang/eval-fail-fetchurl-baseName-attrs-name.nix:1:1:
1| builtins.fetchurl {
| ^
2| url = "https://example.com/foo.tar.gz";
error: invalid store path name when fetching URL 'https://example.com/foo.tar.gz': name '~wobble~' contains illegal character '~'. Please change the value for the 'name' attribute passed to 'fetchurl', so that it can create a valid store path.

View File

@@ -0,0 +1,4 @@
builtins.fetchurl {
url = "https://example.com/foo.tar.gz";
name = "~wobble~";
}

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'fetchurl' builtin
at /pwd/lang/eval-fail-fetchurl-baseName-attrs.nix:1:1:
1| builtins.fetchurl { url = "https://example.com/~wiggle~"; }
| ^
2|
error: invalid store path name when fetching URL 'https://example.com/~wiggle~': name '~wiggle~' contains illegal character '~'. Please add a valid 'name' attribute to the argument for 'fetchurl', so that it can create a valid store path.

View File

@@ -0,0 +1 @@
builtins.fetchurl { url = "https://example.com/~wiggle~"; }

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'fetchurl' builtin
at /pwd/lang/eval-fail-fetchurl-baseName.nix:1:1:
1| builtins.fetchurl "https://example.com/~wiggle~"
| ^
2|
error: invalid store path name when fetching URL 'https://example.com/~wiggle~': name '~wiggle~' contains illegal character '~'. Please pass an attribute set with 'url' and 'name' attributes to 'fetchurl', so that it can create a valid store path.

View File

@@ -0,0 +1 @@
builtins.fetchurl "https://example.com/~wiggle~"

View File

@@ -0,0 +1,16 @@
error:
… while calling the 'seq' builtin
at /pwd/lang/eval-fail-flake-ref-to-string-negative-integer.nix:4:1:
3| in
4| builtins.seq n (
| ^
5| builtins.flakeRefToString {
… while calling the 'flakeRefToString' builtin
at /pwd/lang/eval-fail-flake-ref-to-string-negative-integer.nix:5:3:
4| builtins.seq n (
5| builtins.flakeRefToString {
| ^
6| type = "github";
error: negative value given for flake ref attr repo: -1

View File

@@ -0,0 +1,12 @@
let
n = -1;
in
builtins.seq n (
builtins.flakeRefToString {
type = "github";
owner = "NixOS";
repo = n;
ref = "23.05";
dir = "lib";
}
)

View File

@@ -0,0 +1,37 @@
error:
… while calling the 'foldl'' builtin
at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:2:1:
1| # Tests that the result of applying op is forced even if the value is never used
2| builtins.foldl' (_: f: f null) null [
| ^
3| (_: throw "Not the final value, but is still forced!")
… while calling anonymous lambda
at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:2:21:
1| # Tests that the result of applying op is forced even if the value is never used
2| builtins.foldl' (_: f: f null) null [
| ^
3| (_: throw "Not the final value, but is still forced!")
… from call site
at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:2:24:
1| # Tests that the result of applying op is forced even if the value is never used
2| builtins.foldl' (_: f: f null) null [
| ^
3| (_: throw "Not the final value, but is still forced!")
… while calling anonymous lambda
at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:3:4:
2| builtins.foldl' (_: f: f null) null [
3| (_: throw "Not the final value, but is still forced!")
| ^
4| (_: 23)
… while calling the 'throw' builtin
at /pwd/lang/eval-fail-foldlStrict-strict-op-application.nix:3:7:
2| builtins.foldl' (_: f: f null) null [
3| (_: throw "Not the final value, but is still forced!")
| ^
4| (_: 23)
error: Not the final value, but is still forced!

View File

@@ -0,0 +1,5 @@
# Tests that the result of applying op is forced even if the value is never used
builtins.foldl' (_: f: f null) null [
(_: throw "Not the final value, but is still forced!")
(_: 23)
]

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'fromJSON' builtin
at /pwd/lang/eval-fail-fromJSON-keyWithNullByte.nix:1:1:
1| builtins.fromJSON ''{"a\u0000b": 1}''
| ^
2|
error: input string 'a␀b' cannot be represented as Nix string because it contains null bytes

View File

@@ -0,0 +1 @@
builtins.fromJSON ''{"a\u0000b": 1}''

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'fromJSON' builtin
at /pwd/lang/eval-fail-fromJSON-overflowing.nix:1:1:
1| builtins.fromJSON ''{"attr": 18446744073709551615}''
| ^
2|
error: unsigned json number 18446744073709551615 outside of Nix integer range

View File

@@ -0,0 +1 @@
builtins.fromJSON ''{"attr": 18446744073709551615}''

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'fromJSON' builtin
at /pwd/lang/eval-fail-fromJSON-valueWithNullByte.nix:1:1:
1| builtins.fromJSON ''"a\u0000b"''
| ^
2|
error: input string 'a␀b' cannot be represented as Nix string because it contains null bytes

View File

@@ -0,0 +1 @@
builtins.fromJSON ''"a\u0000b"''

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'fromTOML' builtin
at /pwd/lang/eval-fail-fromTOML-keyWithNullByte.nix:1:1:
1| builtins.fromTOML ''"a\u0000b" = 1''
| ^
2|
error: while parsing TOML: error: input string 'a␀b' cannot be represented as Nix string because it contains null bytes

View File

@@ -0,0 +1 @@
builtins.fromTOML ''"a\u0000b" = 1''

View File

@@ -0,0 +1,8 @@
error:
… while calling the 'fromTOML' builtin
at /pwd/lang/eval-fail-fromTOML-timestamps.nix:1:1:
1| builtins.fromTOML ''
| ^
2| key = "value"
error: while parsing TOML: Dates and times are not supported

View File

@@ -0,0 +1,130 @@
builtins.fromTOML ''
key = "value"
bare_key = "value"
bare-key = "value"
1234 = "value"
"127.0.0.1" = "value"
"character encoding" = "value"
"ʎǝʞ" = "value"
'key2' = "value"
'quoted "value"' = "value"
name = "Orange"
physical.color = "orange"
physical.shape = "round"
site."google.com" = true
# This is legal according to the spec, but cpptoml doesn't handle it.
#a.b.c = 1
#a.d = 2
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
int1 = +99
int2 = 42
int3 = 0
int4 = -17
int5 = 1_000
int6 = 5_349_221
int7 = 1_2_3_4_5
hex1 = 0xDEADBEEF
hex2 = 0xdeadbeef
hex3 = 0xdead_beef
oct1 = 0o01234567
oct2 = 0o755
bin1 = 0b11010110
flt1 = +1.0
flt2 = 3.1415
flt3 = -0.01
flt4 = 5e+22
flt5 = 1e6
flt6 = -2E-2
flt7 = 6.626e-34
flt8 = 9_224_617.445_991_228_313
bool1 = true
bool2 = false
odt1 = 1979-05-27T07:32:00Z
odt2 = 1979-05-27T00:32:00-07:00
odt3 = 1979-05-27T00:32:00.999999-07:00
odt4 = 1979-05-27 07:32:00Z
ldt1 = 1979-05-27T07:32:00
ldt2 = 1979-05-27T00:32:00.999999
ld1 = 1979-05-27
lt1 = 07:32:00
lt2 = 00:32:00.999999
arr1 = [ 1, 2, 3 ]
arr2 = [ "red", "yellow", "green" ]
arr3 = [ [ 1, 2 ], [3, 4, 5] ]
arr4 = [ "all", 'strings', """are the same""", ''''type'''']
arr5 = [ [ 1, 2 ], ["a", "b", "c"] ]
arr7 = [
1, 2, 3
]
arr8 = [
1,
2, # this is ok
]
[table-1]
key1 = "some string"
key2 = 123
[table-2]
key1 = "another string"
key2 = 456
[dog."tater.man"]
type.name = "pug"
[a.b.c]
[ d.e.f ]
[ g . h . i ]
[ j . "ʞ" . 'l' ]
[x.y.z.w]
name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 }
animal = { type.name = "pug" }
[[products]]
name = "Hammer"
sku = 738594937
[[products]]
[[products]]
name = "Nail"
sku = 284758393
color = "gray"
[[fruit]]
name = "apple"
[fruit.physical]
color = "red"
shape = "round"
[[fruit.variety]]
name = "red delicious"
[[fruit.variety]]
name = "granny smith"
[[fruit]]
name = "banana"
[[fruit.variety]]
name = "plantain"
''

Some files were not shown because too many files have changed in this diff Show More