Test environment handling of contracts when merging
@@ -761,4 +761,57 @@ Assume(#alwaysTrue -> #alwaysFalse, not ) true
make_composed_contract("10").unwrap_err();
make_composed_contract("35").unwrap_err();
}
+
+ /// Check that the environments of contracts are correctly saved and restored when merging. See
+ /// issue [#117](https://github.com/tweag/nickel/issues/117).
+ #[test]
+ fn merge_contracts_with_env() {
+ let definitions = "
+ let ctr_num = let x = num in {a = Contract(#x)} in
+ let ctr_id = let x = fun l x => x in {a = Contract(#x)} in
+ let val = let x = 1 in {a = x} in
+ let def = let x = 2 in {a = Default(x)} in
+ let def2 = let x = (1 + 1) in {a = Default(x)} in
+ ";
+
+ // Build a term which recursively merges the elements of `elts` in the environment set by
+ // `definitions`, and then access the `a` field
+ let merge_elts = |elts: Vec<&str>| -> Result<Term, Error> {
+ let term = elts.into_iter().fold(String::from("{}"), |term, op| {
+ format!("merge ({}) ({})", op, term)
+ });
+ eval_string(&format!("{} ({}).a", definitions, term))
+ };
+
+ // contract/contract -> contract/value -> value/default
+ assert_eq!(
+ merge_elts(vec!["ctr_num", "ctr_id", "val", "def"]),
+ Ok(Term::Num(1.0))
+ );
+ // default/value <- value/contract
+ assert_eq!(
+ merge_elts(vec!["def", "merge val ctr_num"]),
+ Ok(Term::Num(1.0))
+ );
+ // default/contract-> contract-default/contract-default <- contract/default
+ assert_eq!(
+ merge_elts(vec!["merge def ctr_num", "merge ctr_id def2"]),
+ Ok(Term::Num(2.0))
+ );
+ // default/contract -> contract-default/contract -> contract-default/value
+ assert_eq!(
+ merge_elts(vec!["def", "ctr_num", "ctr_id", "val"]),
+ Ok(Term::Num(1.0))
+ );
+ // default/contract -> contract-default/default
+ assert_eq!(
+ merge_elts(vec!["def", "ctr_num", "def2"]),
+ Ok(Term::Num(2.0))
+ );
+ // value/contract-default <- contract/contract-default
+ assert_eq!(
+ merge_elts(vec!["val", "merge ctr_num def"]),
+ Ok(Term::Num(1.0))
+ );
+ }
}
