1
1
mirror of https://github.com/tweag/nickel.git synced 2024-09-11 11:47:03 +03:00

Merge pull request #503 from tweag/timcer/fix_test_stackoverflow

Rewrite tests using list of booleans instead of chained &&
This commit is contained in:
Yann Hamdaoui 2021-12-13 12:44:36 +01:00 committed by GitHub
commit 18a18c7d19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 478 additions and 528 deletions

View File

@ -1,26 +1,27 @@
let Assert = fun l x => x || %blame% l in
// left_annot_precedence
(let dummy = null in
let LocalAssert = Assert in
true | #LocalAssert) &&
(if false then
null
else
let dummy = null in
[
// left_annot_precedence
(let dummy = null in
let LocalAssert = Assert in
true | #LocalAssert) &&
true | #LocalAssert),
(let f = fun x =>
let dummy = null in
let LocalAssert = Assert in
x | #LocalAssert in
f true) &&
(if false then
null
else
let dummy = null in
let LocalAssert = Assert in
true | #LocalAssert),
// others_precedence
((fun x => x | #Assert) true) &&
(let AssertOk = fun l t => if t == `Ok then t else %blame% l in
switch {`Ok => true, `Err => false} `Ok | #AssertOk) &&
(let f = fun x =>
let dummy = null in
let LocalAssert = Assert in
x | #LocalAssert in
f true),
true
// others_precedence
((fun x => x | #Assert) true),
(let AssertOk = fun l t => if t == `Ok then t else %blame% l in
switch {`Ok => true, `Err => false} `Ok | #AssertOk),
]
|> lists.foldl (fun x y => x && y) true

View File

@ -1,37 +1,37 @@
let Assert = fun l x => x || %blame% l in
// basic arithmetic
(1+1 == 2 | #Assert) &&
(1-2+3-4 == -2 | #Assert) &&
(2-3-4 == -5 | #Assert) &&
(-1-2 == -3 | #Assert) &&
(2*2 + 2*3 - 2*4 == 2 | #Assert) &&
(1/2 + 1/4 - 1/8 == 0.625 | #Assert) &&
((10 + 1/4) % 3 == 1.25 | #Assert) &&
(10 + 1/4 % 3 == 10.25 | #Assert) &&
(34 + (if true then 2 else 222)
== 36
| #Assert) &&
[
// basic arithmetic
1+1 == 2,
1-2+3-4 == -2,
2-3-4 == -5,
-1-2 == -3,
2*2 + 2*3 - 2*4 == 2,
1/2 + 1/4 - 1/8 == 0.625,
(10 + 1/4) % 3 == 1.25,
10 + 1/4 % 3 == 10.25,
34 + (if true then 2 else 222)
== 36,
// comparisons
(1 < 1 == false | #Assert) &&
(1 <= 1 == true | #Assert) &&
(1 > 1 == false | #Assert) &&
(1 >= 1 == true | #Assert) &&
(1 + 1/2 > 1 + 1/4 == true | #Assert) &&
(1 + 1/2 < 1 + 1/4 == false | #Assert) &&
(1 + 1/2 + 1/8 > 1 + 1/4 + 1/4 == true | #Assert) &&
(1 + 1/2 + 1/8 < 1 + 1/4 + 1/4 == false | #Assert) &&
(-1 - 2 < 3 - 10 == false | #Assert) &&
(-1 - 2 > 3 - 10 == true | #Assert) &&
(-1*2 > 1*2 == false | #Assert) &&
(-1*2 < 1*2 == true | #Assert) &&
(1/4 + 1/4 - 1/4 + 1/4 <= 1/2 == true | #Assert) &&
(1/4 + 1/4 - 1/4 + 1/4 < 1/2 == false | #Assert) &&
(1/4 + 1/4 - 1/4 + 1/4 >= 1/2 == true | #Assert) &&
(1/4 + 1/4 - 1/4 + 1/4 < 1/2 == false | #Assert) &&
// comparisons
1 < 1 == false,
1 <= 1 == true,
1 > 1 == false,
1 >= 1 == true,
1 + 1/2 > 1 + 1/4 == true,
1 + 1/2 < 1 + 1/4 == false,
1 + 1/2 + 1/8 > 1 + 1/4 + 1/4 == true,
1 + 1/2 + 1/8 < 1 + 1/4 + 1/4 == false,
-1 - 2 < 3 - 10 == false,
-1 - 2 > 3 - 10 == true,
-1*2 > 1*2 == false,
-1*2 < 1*2 == true,
1/4 + 1/4 - 1/4 + 1/4 <= 1/2 == true,
1/4 + 1/4 - 1/4 + 1/4 < 1/2 == false,
1/4 + 1/4 - 1/4 + 1/4 >= 1/2 == true,
1/4 + 1/4 - 1/4 + 1/4 < 1/2 == false,
// This test checks that the terms of a switch are closured
(let x = 3 in (switch { `foo => 1, _ => x} (3 + 2)) == 3) &&
true
// This test checks that the terms of a switch are closured
let x = 3 in (switch { `foo => 1, _ => x} (3 + 2)) == 3,
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -1,30 +1,30 @@
let Assert = fun l x => x || %blame% l in
// is_record
(builtins.isRecord {} | #Assert) &&
[
// is_record
builtins.isRecord {},
/// This currently do not check that subexpressions are actually forced,
/// just that the evaluation succeeds
(%seq% 1 true | #Assert) &&
(let x = (1 + 1) in %seq% x x == 2 | #Assert) &&
(let r = {a=(1 + 1),} in
%deepSeq% r (r.a) == 2 | #Assert) &&
(let r = {a=(1 + 1),b=("a" ++ "b"),} in
%deepSeq% r (r.b) == "ab" | #Assert) &&
(let r = {a = {b = 1 + 1}} in
%deepSeq% r (r.a.b) == 2 | #Assert) &&
/// This currently do not check that subexpressions are actually forced,
/// just that the evaluation succeeds
%seq% 1 true,
let x = (1 + 1) in %seq% x x == 2,
let r = {a=(1 + 1),} in
%deepSeq% r (r.a) == 2,
let r = {a=(1 + 1),b=("a" ++ "b"),} in
%deepSeq% r (r.b) == "ab",
let r = {a = {b = 1 + 1}} in
%deepSeq% r (r.a.b) == 2,
(let inj = fun x => {b=(x + 2)} in
let cat = fun x => fun y => x ++ y in
let r = {a=(inj 1),b=(cat "a" "b")} in
%deepSeq% r (r.a.b) == 3 | #Assert) &&
let inj = fun x => {b=(x + 2)} in
let cat = fun x => fun y => x ++ y in
let r = {a=(inj 1),b=(cat "a" "b")} in
%deepSeq% r (r.a.b) == 3,
([1,2,3]
|> lists.map (fun x => x + 1)
|> lists.filter (fun x => x > 2)
|> builtins.serialize `Json
|> builtins.deserialize `Json
== [3,4]
| #Assert) &&
true
[1,2,3]
|> lists.map (fun x => x + 1)
|> lists.filter (fun x => x > 2)
|> builtins.serialize `Json
|> builtins.deserialize `Json
== [3,4],
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -1,11 +1,10 @@
let AssertEq = fun val l x => val == x || %blame% l in
let Y | ((Num -> Num) -> Num -> Num) -> Num -> Num = fun f => (fun x => f (x x)) (fun x => f (x x)) in
let dec : Num -> Num = fun x => x + (-1) in
let or : Bool -> Bool -> Bool = fun x => fun y => if x then x else y in
let fibo : Num -> Num = Y (fun fibo =>
(fun x => if or (x == 0) (dec x == 0) then 1 else (fibo (dec x)) + (fibo (dec (dec x))))) in
let val : Num = 4 in
(fibo val | #(AssertEq 5)) &&
let dec : Num -> Num = fun x => x + (-1) in
let or : Bool -> Bool -> Bool = fun x => fun y => if x then x else y in
let fibo : Num -> Num = Y (fun fibo =>
(fun x => if or (x == 0) (dec x == 0) then 1 else (fibo (dec x)) + (fibo (dec (dec x))))) in
let val : Num = 4 in
true
(fibo val | #(AssertEq 5))

View File

@ -1,123 +1,118 @@
let Assert = fun l x => x || %blame% l in
(let AlwaysTrue = fun l t =>
let boolT | Bool = t in
if boolT then boolT else %blame% l in
let AlwaysFalse = fun l t =>
let boolT | Bool = t in
if boolT then %blame% l else boolT
in let not | #AlwaysTrue -> #AlwaysFalse = fun b => if b then false else true in
not true == false) &&
[
let AlwaysTrue = fun l t =>
let boolT | Bool = t in
if boolT then boolT else %blame% l in
let AlwaysFalse = fun l t =>
let boolT | Bool = t in
if boolT then %blame% l else boolT
in let not | #AlwaysTrue -> #AlwaysFalse = fun b => if b then false else true in
not true == false,
// id_polymorphic_contract
(let id | forall a. a -> a = fun x => x in id true) &&
// id_polymorphic_contract
let id | forall a. a -> a = fun x => x in id true,
// higher_order_contract
(let to_bool | forall a. (a -> Bool) -> a -> Bool =
fun f => fun x => f x in
to_bool (fun x => true) 4) &&
// higher_order_contract
let to_bool | forall a. (a -> Bool) -> a -> Bool =
fun f => fun x => f x in
to_bool (fun x => true) 4,
// apply_twice
(let twice | forall a. (a -> a) -> a -> a =
fun f => fun x => f (f x) in
twice (fun x => x + 1) 3 == 5) &&
// apply_twice
let twice | forall a. (a -> a) -> a -> a =
fun f => fun x => f (f x) in
twice (fun x => x + 1) 3 == 5,
// strings
("hello" | Str) == "hello" &&
("hello" ++ " world" | Str) == "hello world" &&
// strings
("hello" | Str) == "hello",
("hello" ++ " world" | Str) == "hello world",
// enums_simple
(`foo | <foo, bar>) == `foo &&
(`bar | forall r. <foo, bar | r>) == `bar &&
// enums_simple
(`foo | <foo, bar>) == `foo,
(`bar | forall r. <foo, bar | r>) == `bar,
// enums_escaped
(`"foo:baz" | <"foo:baz", "bar:baz">) == `"foo:baz" &&
(`"bar:baz" | forall r. <"foo:baz", "bar:baz" | r>) == `"bar:baz" &&
// enums_escaped
(`"foo:baz" | <"foo:baz", "bar:baz">) == `"foo:baz",
(`"bar:baz" | forall r. <"foo:baz", "bar:baz" | r>) == `"bar:baz",
// enums_complex
(let f : forall r. <foo, bar | r> -> Num =
fun x => switch { `foo => 1, `bar => 2, _ => 3, } x in
f `bar == 2) &&
// enums_complex
let f : forall r. <foo, bar | r> -> Num =
fun x => switch { `foo => 1, `bar => 2, _ => 3, } x in
f `bar == 2,
(let f : forall r. <foo, bar | r> -> Num =
fun x => switch { `foo => 1, `bar => 2, _ => 3, } x in
f `boo == 3) &&
let f : forall r. <foo, bar | r> -> Num =
fun x => switch { `foo => 1, `bar => 2, _ => 3, } x in
f `boo == 3,
(let f : forall r. <foo, "bar:baz" | r> -> Num =
fun x => switch { `foo => 1, `"bar:baz" => 2, _ => 3, } x in
f `"bar:baz" == 2) &&
let f : forall r. <foo, "bar:baz" | r> -> Num =
fun x => switch { `foo => 1, `"bar:baz" => 2, _ => 3, } x in
f `"bar:baz" == 2,
(let f : forall r. <foo, "bar:baz" | r> -> Num =
fun x => switch { `foo => 1, `"bar:baz" => 2, _ => 3, } x in
f `"boo,grr" == 3) &&
let f : forall r. <foo, "bar:baz" | r> -> Num =
fun x => switch { `foo => 1, `"bar:baz" => 2, _ => 3, } x in
f `"boo,grr" == 3,
// records_simple
(({} | {}) == {} | #Assert) &&
(let x | {a: Num, s: Str} = {a = 1, s = "a"} in
%deepSeq% x x == {a = 1, s = "a"}
| #Assert) &&
// records_simple
({} | {}) == {},
let x | {a: Num, s: Str} = {a = 1, s = "a"} in
%deepSeq% x x == {a = 1, s = "a"},
(let x | {a: Num, s: {foo: Bool}} = {a = 1, s = { foo = true}} in
%deepSeq% x x == {a = 1, s = { foo = true}}
| #Assert) &&
let x | {a: Num, s: {foo: Bool}} = {a = 1, s = { foo = true}} in
%deepSeq% x x == {a = 1, s = { foo = true}},
// polymorphism
(let id | forall a. { | a} -> { | a} = fun x => x in
let extend | forall a. { | a} -> {foo: Num | a} = fun x =>
x & {foo = 1} in
let remove | forall a. {foo: Num | a} -> { | a} = fun x =>
x -$ "foo" in
// polymorphism
(let id | forall a. { | a} -> { | a} = fun x => x in
let extend | forall a. { | a} -> {foo: Num | a} = fun x =>
x & {foo = 1} in
let remove | forall a. {foo: Num | a} -> { | a} = fun x =>
x -$ "foo" in
(id {} == {} | #Assert) &&
(id {a = 1, b = false} == {a = 1, b = false} | #Assert) &&
(extend {} == {foo = 1} | #Assert) &&
(extend {bar = false} == {foo = 1, bar = false} | #Assert) &&
(remove {foo = 1} == {} | #Assert) &&
(remove {foo = 1, bar = 1} == {bar = 1} | #Assert) &&
(remove (extend {}) == {} | #Assert) &&
(extend (remove {foo = 2}) == {foo =1} | #Assert) &&
(let f | forall a b. {f: a -> a, arg: a | b} -> a =
fun rec => rec.f (rec.arg) in
f { f = fun x => x ++ " suffix", arg = "foo" }
== "foo suffix"
| #Assert)
) &&
(id {} == {} | #Assert) &&
(id {a = 1, b = false} == {a = 1, b = false} | #Assert) &&
(extend {} == {foo = 1} | #Assert) &&
(extend {bar = false} == {foo = 1, bar = false} | #Assert) &&
(remove {foo = 1} == {} | #Assert) &&
(remove {foo = 1, bar = 1} == {bar = 1} | #Assert) &&
(remove (extend {}) == {} | #Assert) &&
(extend (remove {foo = 2}) == {foo =1} | #Assert) &&
(let f | forall a b. {f: a -> a, arg: a | b} -> a =
fun rec => rec.f (rec.arg) in
f { f = fun x => x ++ " suffix", arg = "foo" }
== "foo suffix"
| #Assert)
),
// records_dynamic_tail
(({a = 1, b = "b"} | {a: Num, b: Str | Dyn}) == {a = 1, b = "b"}
| #Assert) &&
(({a = 1, b = "b", c = false} | {a: Num, b: Str | Dyn})
== {a = 1, b = "b", c = false}
| #Assert) &&
(((fun r => r.b) | {a: Num | Dyn} -> Dyn) {a = 1, b = 2} == 2
| #Assert) &&
// records_dynamic_tail
({a = 1, b = "b"} | {a: Num, b: Str | Dyn}) == {a = 1, b = "b"},
({a = 1, b = "b", c = false} | {a: Num, b: Str | Dyn})
== {a = 1, b = "b", c = false},
((fun r => r.b) | {a: Num | Dyn} -> Dyn) {a = 1, b = 2} == 2,
// records_open_contracts
(({a = 0, b = 0} | #{a | Num, ..}) == {a = 0, b = 0} | #Assert) &&
(let Contract = {a | Num} & {..} in
({a = 0, b = 0} | #Contract) == {a = 0, b = 0} | #Assert) &&
(let Contract = {..} & {b | Num} in
({a = 0, b = 0} | #Contract) == {a = 0, b = 0} | #Assert) &&
(let Contract = {a | Num, ..} & {b | Num, ..} in
({a = 0, b = 0, c = 0} | #Contract) == {a = 0, b = 0, c = 0} | #Assert) &&
// records_open_contracts
({a = 0, b = 0} | #{a | Num, ..}) == {a = 0, b = 0},
let Contract = {a | Num} & {..} in
({a = 0, b = 0} | #Contract) == {a = 0, b = 0},
let Contract = {..} & {b | Num} in
({a = 0, b = 0} | #Contract) == {a = 0, b = 0},
let Contract = {a | Num, ..} & {b | Num, ..} in
({a = 0, b = 0, c = 0} | #Contract) == {a = 0, b = 0, c = 0},
// lists
(([1, "2", false] | List) == [1, "2", false] | #Assert) &&
(([1, 2, 3] | List Num) == [1, 2, 3] | #Assert) &&
((["1", "2", "false"] | List Str) == ["1", "2", "false"] | #Assert) &&
// lists
([1, "2", false] | List) == [1, "2", false],
([1, 2, 3] | List Num) == [1, 2, 3],
(["1", "2", "false"] | List Str) == ["1", "2", "false"],
// full_annotations
// Check that the contract introduced by the type annotation doesn't interact
// with the `default` attribute
(({foo : {bar: Bool} | default = {bar = false}} & {foo.bar = true}).foo.bar
| #Assert) &&
// full_annotations
// Check that the contract introduced by the type annotation doesn't interact
// with the `default` attribute
({foo : {bar: Bool} | default = {bar = false}} & {foo.bar = true}).foo.bar,
// nested_metavalues
// Regression test for #402
(let myContract = { x | Str } in
{
foo | #myContract | default = { x = "From foo" },
bar | #{..} | default = foo
} == { foo.x = "From foo", bar.x = "From foo"} | #Assert) &&
true
// nested_metavalues
// Regression test for #402
let myContract = { x | Str } in
{
foo | #myContract | default = { x = "From foo" },
bar | #{..} | default = foo
} == { foo.x = "From foo", bar.x = "From foo"},
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -1,83 +1,78 @@
let Assert = fun l x => x || %blame% l in
// basic
(0 == 0 + 0 + 0 | #Assert) &&
(true == (if true then true else false) | #Assert) &&
("a" ++ "b" ++ "c" == "#{"a" ++ "b"}" ++ "c" | #Assert) &&
(`Less == `Less | #Assert) &&
(`small == `small | #Assert) &&
[
// basic
0 == 0 + 0 + 0,
true == (if true then true else false),
"a" ++ "b" ++ "c" == "#{"a" ++ "b"}" ++ "c",
`Less == `Less,
`small == `small,
(1 + 1 != 0 | #Assert) &&
(true != (if true then false else true) | #Assert) &&
("a" != "a" ++ " " | #Assert) &&
(1 != true | #Assert) &&
("1" != 1 | #Assert) &&
("true" != true | #Assert) &&
(`Less != `small | #Assert) &&
(`Less != 0 | #Assert) &&
(`Greater != false | #Assert) &&
1 + 1 != 0,
true != (if true then false else true),
"a" != "a" ++ " ",
1 != true,
"1" != 1,
"true" != true,
`Less != `small,
`Less != 0,
`Greater != false,
// lists
([] == [] | #Assert) &&
([(1 + 0), (1 + 1), (1 + 1 + 1)] == [1, 2, 3] | #Assert) &&
([(1 + 0), ("a" ++ "b"), (if true then true else false)]
== [1, "ab", true]
| #Assert) &&
([[[]]] == [[[]]] | #Assert) &&
([[1], [[2]]] == [[2 + (-1)], [[1 + 1]]] | #Assert) &&
([[true, false]] == lists.flatten [[[true, false]]] | #Assert) &&
// lists
[] == [],
[(1 + 0), (1 + 1), (1 + 1 + 1)] == [1, 2, 3],
[(1 + 0), ("a" ++ "b"), (if true then true else false)]
== [1, "ab", true],
[[[]]] == [[[]]],
[[1], [[2]]] == [[2 + (-1)], [[1 + 1]]],
[[true, false]] == lists.flatten [[[true, false]]],
([] != [1] | #Assert) &&
([] != 1 | #Assert) &&
([] != {} | #Assert) &&
([1, "a", true] != [1, "a", false] | #Assert) &&
([[true]] != [[[true]]] | #Assert) &&
[] != [1],
[] != 1,
[] != {},
[1, "a", true] != [1, "a", false],
[[true]] != [[[true]]],
// records
({} == {} | #Assert) &&
({}$["a" = 1]$["b" = true]
== {a = 1, b = true}
| #Assert) &&
({a = 1 + 0, b = 1 + 1, c = 1 + 1 + 1}
== { a = 1, b = 2, c = 3 }
| #Assert) &&
({
foo = 1 + 0,
bar = "a" ++ "b",
baz = if true then true else false
} == {foo = 1, bar = "ab", baz = true}
| #Assert) &&
// records
{} == {},
{}$["a" = 1]$["b" = true]
== {a = 1, b = true},
{a = 1 + 0, b = 1 + 1, c = 1 + 1 + 1}
== { a = 1, b = 2, c = 3 },
{
foo = 1 + 0,
bar = "a" ++ "b",
baz = if true then true else false
} == {foo = 1, bar = "ab", baz = true},
({}$["a" = { a = { a = {} } }]
== { a = { a = { a = {} } } }
| #Assert) &&
({
foo = {bar = 2 + (-1)},
baz = {foo = {bar = 1 + 1}}
}
== {foo = {bar = 1}, baz = {foo = {bar = 2}}}
| #Assert) &&
({} != {a = true} | #Assert) &&
({a = 1} != {a = 2} | #Assert) &&
({ a = "a", b = true } != { a = true, b = "a"} | #Assert) &&
({ a = { a = true } } != {a = { a = { a = true } } } | #Assert) &&
{}$["a" = { a = { a = {} } }]
== { a = { a = { a = {} } } },
{
foo = {bar = 2 + (-1)},
baz = {foo = {bar = 1 + 1}}
}
== {foo = {bar = 1}, baz = {foo = {bar = 2}}},
{} != {a = true},
{a = 1} != {a = 2},
{ a = "a", b = true } != { a = true, b = "a"},
{ a = { a = true } } != {a = { a = { a = true } } },
// Now that the equality operator directly uses the stack to store its continuation (see
// https://github.com/tweag/nickel/pull/247), check that it correctly cleans the stack when
// evaluating a subequality to `false`.
// Generate an non-empty evaluation context to evaluate equalities over a non-empty stack
(let eq_with_ctxt = fun x y =>
let not = fun b =>
if b then true else false in
not (not (not (not ((x) == (y))))) in
(eq_with_ctxt
{a = 1 + 0, b = 1 + 1 + a, c = 0, d = 0}
{ a = 1, b = 3, c = 0, d = 0}
| #Assert) &&
(eq_with_ctxt
[[1,2,3,4], [1,0,3,4], [1,2,3,4], [1,2,3,4]]
[[1,2,3,4], [1,2,3,4], [1,2,3,4], [1,2,3,4]]
== false
| #Assert)) &&
true
// Now that the equality operator directly uses the stack to store its continuation (see
// https://github.com/tweag/nickel/pull/247), check that it correctly cleans the stack when
// evaluating a subequality to `false`.
// Generate an non-empty evaluation context to evaluate equalities over a non-empty stack
let eq_with_ctxt = fun x y =>
let not = fun b =>
if b then true else false in
not (not (not (not ((x) == (y))))) in
(eq_with_ctxt
{a = 1 + 0, b = 1 + 1 + a, c = 0, d = 0}
{ a = 1, b = 3, c = 0, d = 0}
) &&
(eq_with_ctxt
[[1,2,3,4], [1,0,3,4], [1,2,3,4], [1,2,3,4]]
[[1,2,3,4], [1,2,3,4], [1,2,3,4], [1,2,3,4]]
== false
),
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -1,20 +1,18 @@
let Assert = fun l x => x || %blame% l in
((fun x => x) 3 == 3 | #Assert) &&
((fun x y => x) 1 2 == 1 | #Assert) &&
((fun x y => y) 1 2 == 2 | #Assert) &&
((fun f x => f 0) (fun x => x+2) 2 == 2 | #Assert) &&
[
(fun x => x) 3 == 3,
(fun x y => x) 1 2 == 1,
(fun x y => y) 1 2 == 2,
(fun f x => f 0) (fun x => x+2) 2 == 2,
(let f = fun f y => f (f y) in f (fun x => x+1) 3 == 5 | #Assert) &&
(let g = fun x => if x then 0 else false in g ((fun x => true) 23)
== 0
| #Assert) &&
// Y fixpont combinator
(let Y = (fun f => (fun x => f (x x)) (fun x => f (x x))) in
let g = Y (fun g => (fun x => if x then (g false) else 4)) in
g true
== 4
| #Assert) &&
true
let f = fun f y => f (f y) in f (fun x => x+1) 3 == 5,
let g = fun x => if x then 0 else false in g ((fun x => true) 23)
== 0,
// Y fixpont combinator
let Y = (fun f => (fun x => f (x x)) (fun x => f (x x))) in
let g = Y (fun g => (fun x => if x then (g false) else 4)) in
g true
== 4,
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -1,5 +1,3 @@
let Assert = fun l x => x || %blame% l in
(import "imported.ncl" 3 == 3 | #Assert) &&
true
(import "imported.ncl" 3 == 3 | #Assert)

View File

@ -1,38 +1,36 @@
let Assert = fun l x => x || %blame% l in
// accesses
(lists.elemAt 1 [1,2,3] == 2 | #Assert) &&
(lists.elemAt 1 (lists.map (fun x => x + 1) [1,2,3]) == 3 | #Assert) &&
[
// accesses
lists.elemAt 1 [1,2,3] == 2,
lists.elemAt 1 (lists.map (fun x => x + 1) [1,2,3]) == 3,
// length
(lists.length [] == 0 | #Assert) &&
(lists.length [1,2,3] == 3 | #Assert) &&
(lists.length ([] @ [1,2] @ [3,4] @ []) == 4 | #Assert) &&
// length
lists.length [] == 0,
lists.length [1,2,3] == 3,
lists.length ([] @ [1,2] @ [3,4] @ []) == 4,
// Test case added after https://github.com/tweag/nickel/issues/154
(let x = 1 in let l = [x] @ [2] in %head% l == 1 | #Assert) &&
// Test case added after https://github.com/tweag/nickel/issues/154
let x = 1 in let l = [x] @ [2] in %head% l == 1,
(let Y = fun f => (fun x => f (x x)) (fun x => f (x x)) in
let foldr_ =
fun self => fun f => fun acc => fun l =>
if %length% l == 0 then acc
else
let h = %head% l in
let t = %tail% l in
let next_acc = self f acc t in
f next_acc h in
let foldr = Y foldr_ in
let and : Bool -> Bool -> Bool =
fun x => fun y =>
if x then
if y then true else false
else false
in
let all = fun pred => fun l => foldr and true (%map% l pred) in
let isZ = fun x => x == 0 in
all isZ [0, 0, 0, 1]
== false
| #Assert) &&
true
let Y = fun f => (fun x => f (x x)) (fun x => f (x x)) in
let foldr_ =
fun self => fun f => fun acc => fun l =>
if %length% l == 0 then acc
else
let h = %head% l in
let t = %tail% l in
let next_acc = self f acc t in
f next_acc h in
let foldr = Y foldr_ in
let and : Bool -> Bool -> Bool =
fun x => fun y =>
if x then
if y then true else false
else false
in
let all = fun pred => fun l => foldr and true (%map% l pred) in
let isZ = fun x => x == 0 in
all isZ [0, 0, 0, 1] == false,
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -1,61 +1,56 @@
let Assert = fun l x => x || %blame% l in
((10 | default | Num) == 10 | #Assert) &&
[
(10 | default | Num) == 10,
// Check the correct handling of the update of thunks containing enriched values (see issue
// https://github.com/tweag/nickel/issues/123)
(let x = {a = (fun x => (1 | default)) 1} in
builtins.seq (x.a) ((x & {a=2}).a) == 2 | #Assert) &&
// Check the correct handling of the update of thunks containing enriched values (see issue
// https://github.com/tweag/nickel/issues/123)
let x = {a = (fun x => (1 | default)) 1} in
builtins.seq (x.a) ((x & {a=2}).a) == 2,
// merge_default
(({a = 2} & {a | default = 0, b | default = true}) == {a = 2, b = true}
| #Assert) &&
({a | default = {x = 1}} & {a | default = {y = "y"}} == {a = {x = 1, y = "y"}}
| #Assert) &&
// merge_default
({a = 2} & {a | default = 0, b | default = true}) == {a = 2, b = true},
{a | default = {x = 1}} & {a | default = {y = "y"}} == {a = {x = 1, y = "y"}},
// merge_contract
({a = 2, b | Bool} & {a | Num, b | default = true}
== {a = 2, b = true}
| #Assert) &&
// merge_contract
{a = 2, b | Bool} & {a | Num, b | default = true}
== {a = 2, b = true},
// merge_default_contract
({a = 2} & {a | default | Num = 0, b | default = true}
== {a = 2, b = true}
| #Assert) &&
// merge_default_contract
{a = 2} & {a | default | Num = 0, b | default = true}
== {a = 2, b = true},
({a=2} & {a | Num} & {a | default = 3} == {a = 2} | #Assert) &&
({a=2} & {b | Num} & {b | default = 3} == {a = 2, b = 3} | #Assert) &&
(({a | default = 1} & {b | Num} & {a | default = 1}).a
== 1
| #Assert) &&
{a=2} & {a | Num} & {a | default = 3} == {a = 2},
{a=2} & {b | Num} & {b | default = 3} == {a = 2, b = 3},
({a | default = 1} & {b | Num} & {a | default = 1}).a
== 1,
// composed
(let Even = fun l x => if x % 2 == 0 then x else %blame% l in
let DivBy3 = fun l x => if x % 3 == 0 then x else %blame% l in
let composed = {a | #Even} & {a | #DivBy3} in
(composed & {a = 6} == {a = 6} | #Assert) &&
(composed & {a = 12} == {a = 12} | #Assert)) &&
// composed
let Even = fun l x => if x % 2 == 0 then x else %blame% l in
let DivBy3 = fun l x => if x % 3 == 0 then x else %blame% l in
let composed = {a | #Even} & {a | #DivBy3} in
(composed & {a = 6} == {a = 6} | #Assert) &&
(composed & {a = 12} == {a = 12} | #Assert),
// Check that the environments of contracts are correctly saved and restored when merging. See
// issue [#117](https://github.com/tweag/nickel/issues/117)
(let ctr_num = let x = num in {a | #x} in
let ctr_id = let x = fun l x => x in {a | #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
// contract/contract -> contract/value -> value/default
((ctr_num & ctr_id & val & def).a == 1 | #Assert) &&
// default/value <- value/contract
((def & (val & ctr_num)).a == 1 | #Assert) &&
// default/contract-> contract-default/contract-default <- contract/default
(((def & ctr_num) & (ctr_id & def2)).a == 2 | #Assert) &&
// default/contract -> contract-default/contract -> contract-default/value
((def & ctr_num & ctr_id & val).a == 1 | #Assert) &&
// default/contract -> contract-default/default
((def & ctr_num & def2).a == 2 | #Assert) &&
// value/contract-default <- contract/contract-default
((val & (ctr_num & def)).a == 1 | #Assert)) &&
true
// Check that the environments of contracts are correctly saved and restored when merging. See
// issue [#117](https://github.com/tweag/nickel/issues/117)
(let ctr_num = let x = num in {a | #x} in
let ctr_id = let x = fun l x => x in {a | #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
// contract/contract -> contract/value -> value/default
((ctr_num & ctr_id & val & def).a == 1 | #Assert) &&
// default/value <- value/contract
((def & (val & ctr_num)).a == 1 | #Assert) &&
// default/contract-> contract-default/contract-default <- contract/default
(((def & ctr_num) & (ctr_id & def2)).a == 2 | #Assert) &&
// default/contract -> contract-default/contract -> contract-default/value
((def & ctr_num & ctr_id & val).a == 1 | #Assert) &&
// default/contract -> contract-default/default
((def & ctr_num & def2).a == 2 | #Assert) &&
// value/contract-default <- contract/contract-default
((val & (ctr_num & def)).a == 1 | #Assert)),
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -1,51 +1,43 @@
let Assert = fun l x => x || %blame% l in
// piecewise_definitions
({foo.bar.stuff = 1} == {foo = {bar = {stuff = 1}}} | #Assert) &&
({foo.bar.stuff = 1, foo.bar.stuff = 1} == {foo = {bar = {stuff = 1}}}
| #Assert) &&
({a.b.c.d = "foo"} == {a = {b = {c = {d = "foo"}}}} | #Assert) &&
({a.b = "foo", a.c = "bar"} == {a = {b = "foo", c = "bar"}} | #Assert) &&
({a.b.c = "foo", a.b.d = {foo = 1}, a.b.d = {bar = 2}}
== {a = {b = {c = "foo", d = {foo = 1, bar = 2}}}}
| #Assert) &&
[
// piecewise_definitions
{foo.bar.stuff = 1} == {foo = {bar = {stuff = 1}}},
{foo.bar.stuff = 1, foo.bar.stuff = 1} == {foo = {bar = {stuff = 1}}},
{a.b.c.d = "foo"} == {a = {b = {c = {d = "foo"}}}},
{a.b = "foo", a.c = "bar"} == {a = {b = "foo", c = "bar"}},
{a.b.c = "foo", a.b.d = {foo = 1}, a.b.d = {bar = 2}}
== {a = {b = {c = "foo", d = {foo = 1, bar = 2}}}},
({foo.bar.baz = 1, foo.bar.stuff = false}
== {foo = {bar = {baz = 1, stuff = false}}}
| #Assert) &&
{foo.bar.baz = 1, foo.bar.stuff = false}
== {foo = {bar = {baz = 1, stuff = false}}},
({foo = {}, foo.bar = {}, foo.bar.baz = true}
== {foo = {bar = {baz = true}}}
| #Assert) &&
{foo = {}, foo.bar = {}, foo.bar.baz = true}
== {foo = {bar = {baz = true}}},
// quoted_fields
({"foo$-^bar" = "foo"}."foo$-^bar" == "foo" | #Assert) &&
(let x = "fo" ++ "o" in
{"#{x}-bar" = "foo"}."foo-bar" == "foo" | #Assert) &&
// quoted_fields
{"foo$-^bar" = "foo"}."foo$-^bar" == "foo",
let x = "fo" ++ "o" in
{"#{x}-bar" = "foo"}."foo-bar" == "foo",
({"foo-bar"."baz+baz" = false}."foo-bar"."baz+baz" == false | #Assert) &&
({foo-bar.baz-baz = false}.foo-bar.baz-baz == false | #Assert) &&
{"foo-bar"."baz+baz" = false}."foo-bar"."baz+baz" == false,
{foo-bar.baz-baz = false}.foo-bar.baz-baz == false,
// recursive_paths
({foo.bar.baz = 1, bar.baz.foo = foo.bar.baz + 1}
== {foo = {bar = {baz = 1}}, bar = {baz = {foo = 2}}}
| #Assert) &&
({foo."bar"."baz" = 1, "bar"."baz"."foo" = foo.bar."baz" + 1}
== {foo = {bar = {baz = 1}}, bar = {baz = {foo = 2}}}
| #Assert) &&
// recursive_paths
{foo.bar.baz = 1, bar.baz.foo = foo.bar.baz + 1}
== {foo = {bar = {baz = 1}}, bar = {baz = {foo = 2}}},
{foo."bar"."baz" = 1, "bar"."baz"."foo" = foo.bar."baz" + 1}
== {foo = {bar = {baz = 1}}, bar = {baz = {foo = 2}}},
// piecewise_annotations
({foo.bar | default = 1, foo.baz = 2}
== {foo = {bar = 1, baz = 2}}
| #Assert) &&
({foo.bar | default = 1, foo.bar = 2} == {foo = {bar = 2}} | #Assert) &&
({foo.bar.baz | Bool = true}.foo.bar.baz | #Assert) &&
// piecewise_annotations
{foo.bar | default = 1, foo.baz = 2}
== {foo = {bar = 1, baz = 2}},
{foo.bar | default = 1, foo.bar = 2} == {foo = {bar = 2}},
{foo.bar.baz | Bool = true}.foo.bar.baz,
// recursive_dynamic_fields
(let x = "foo" in
{"#{x}" = bar, bar = 1} == {foo = 1, bar = 1} | #Assert) &&
({"#foo"."#bar".baz = other + 1, other = 0}."#foo"."#bar".baz == 1) &&
true
// recursive_dynamic_fields
let x = "foo" in {"#{x}" = bar, bar = 1} == {foo = 1, bar = 1},
({"#foo"."#bar".baz = other + 1, other = 0}."#foo"."#bar".baz == 1),
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -1,97 +1,84 @@
let Assert = fun l x => x || %blame% l in
// accesses
(({foo = 3, bar = true}).bar == true | #Assert) &&
({"#{if true then "foo" else "bar"}" = false, bar = true}.foo
== false
| #Assert) &&
[
// accesses
({foo = 3, bar = true}).bar == true,
{"#{if true then "foo" else "bar"}" = false, bar = true}.foo
== false,
(({foo = 3, bar = true})."bar" == true | #Assert) &&
({"#{if true then "foo" else "bar"}" = false, bar = true}."#{"foo"}"
== false
| #Assert) &&
({foo = 3, bar = true})."bar" == true,
{"#{if true then "foo" else "bar"}" = false, bar = true}."#{"foo"}"
== false,
(({bar = 3}$["foo" = true]).foo == true
| #Assert) &&
({bar = 3}$["foo" = true]).foo == true,
// primitive_ops
(records.hasField "foo" {foo = 1, bar = 2} | #Assert) &&
(records.hasField "fop" {foo = 1, bar = 2} == false | #Assert) &&
(records.hasField "foo" ({foo = 2, bar = 3} -$ "foo")
== false
| #Assert) &&
// primitive_ops
records.hasField "foo" {foo = 1, bar = 2},
records.hasField "fop" {foo = 1, bar = 2} == false,
records.hasField "foo" ({foo = 2, bar = 3} -$ "foo")
== false,
(records.hasField "foo" ({bar = 3}$["foo" = 1]) | #Assert) &&
records.hasField "foo" ({bar = 3}$["foo" = 1]),
// lazyness of map
((records.map (fun x y => y + 1) {foo = 1, bar = "it's lazy"}).foo
== 2
| #Assert) &&
// lazyness of map
(records.map (fun x y => y + 1) {foo = 1, bar = "it's lazy"}).foo
== 2,
(let r = records.map
(fun y x => if %isNum% x then x + 1 else 0)
{foo = 1, bar = "it's lazy"} in
(r.foo) + (r.bar) == 2
| #Assert) &&
let r = records.map
(fun y x => if %isNum% x then x + 1 else 0)
{foo = 1, bar = "it's lazy"} in
(r.foo) + (r.bar) == 2,
// merging
({a = 1} & {b=true} == {a = 1, b = true} | #Assert) &&
({a = 1, b = 2} & {b = 2, c = 3}
== {a = 1, b = 2, c = 3}
| #Assert) &&
// merging
{a = 1} & {b=true} == {a = 1, b = true},
{a = 1, b = 2} & {b = 2, c = 3}
== {a = 1, b = 2, c = 3},
({a = {b = 1}} & {a = {c = true}}
== {a = {b = 1, c = true}}
| #Assert) &&
{a = {b = 1}} & {a = {c = true}}
== {a = {b = 1, c = true}},
// merge_complex
(let rec1 = {
a = false,
b = if true then (1 + 1) else (2 + 0),
c= ((fun x => x) (fun y => y)) 2,
} in
let rec2 = {
b = ((fun x => x) (fun y => y)) 2,
c = if true then (1 + 1) else (2 + 0),
d = true,
} in
let result = {
a = false,
b = 2,
c = 2,
d = true,
} in
rec1 & rec2 == result
| #Assert) &&
// merge_complex
let rec1 = {
a = false,
b = if true then (1 + 1) else (2 + 0),
c= ((fun x => x) (fun y => y)) 2,
} in
let rec2 = {
b = ((fun x => x) (fun y => y)) 2,
c = if true then (1 + 1) else (2 + 0),
d = true,
} in
let result = {
a = false,
b = 2,
c = 2,
d = true,
} in
rec1 & rec2 == result,
// merge_with_env
((fun y => ((fun x => {a=y}) 1) & ({b=false})) 2
== {a = 2, b = false}
| #Assert) &&
// merge_with_env
(fun y => ((fun x => {a=y}) 1) & ({b=false})) 2
== {a = 2, b = false},
// merge_with_env_nested
({b={c=10}} & ((fun x => {a=x, b={c=x}}) 10)
== {a=10, b = {c = 10}}
| #Assert) &&
// merge_with_env_nested
{b={c=10}} & ((fun x => {a=x, b={c=x}}) 10)
== {a=10, b = {c = 10}},
// recursive_records
({a = 1, b = a + 1, c = b + a} == {a = 1, b = 2, c = 3} | #Assert) &&
({f = fun x y =>
if x == 0 then y else f (x + (-1)) (y + 1)
}.f 5 5
== 10
| #Assert) &&
// recursive_records
{a = 1, b = a + 1, c = b + a} == {a = 1, b = 2, c = 3},
{f = fun x y =>
if x == 0 then y else f (x + (-1)) (y + 1)
}.f 5 5
== 10,
(let with_res = fun res =>
{
f = fun x =>
if x == 0 then
res
else g x,
g = fun y => f (y + (-1))
}.f 10 in
with_res "done" == "done"
| #Assert) &&
true
let with_res = fun res =>
{
f = fun x =>
if x == 0 then
res
else g x,
g = fun y => f (y + (-1))
}.f 10 in
with_res "done" == "done",
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -15,19 +15,18 @@ let assertDeserInv = fun x =>
assertAux `Yaml x &&
assertAux `Toml x in
(assertSerInv {val = 1 + 1} | #Assert) &&
(assertSerInv {val = "Some string"} | #Assert) &&
(assertSerInv {val = ["a", 3, []]} | #Assert) &&
(assertSerInv {a.foo.bar = "2", b = false, c = [{d = "e"}, {d = "f"}]}
| #Assert) &&
[
assertSerInv {val = 1 + 1},
assertSerInv {val = "Some string"},
assertSerInv {val = ["a", 3, []]},
assertSerInv {a.foo.bar = "2", b = false, c = [{d = "e"}, {d = "f"}]},
(assertDeserInv {a = 1, b = 4, c = 3} | #Assert) &&
(assertDeserInv {a.b.c = "richtig"} | #Assert) &&
(assertDeserInv {
foo = 1,
bar = ["str", true],
baz = {subfoo = true, subbar = 0}
} | #Assert) &&
true
assertDeserInv {a = 1, b = 4, c = 3},
assertDeserInv {a.b.c = "richtig"},
assertDeserInv {
foo = 1,
bar = ["str", true],
baz = {subfoo = true, subbar = 0}
},
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -1,23 +1,19 @@
let Assert = fun l x => x || %blame% l in
// interpolation
("simple #{"interp" ++ "olation"} here" == "simple interpolation here"
| #Assert) &&
("#{"alone"}" == "alone" | #Assert) &&
("nested #{ "#{(fun x => "#{x}") "expression"}" }"
== "nested expression" | #Assert) &&
("#{"some"}#{" " ++ "se" ++ "qu"}#{"#{"ence"}"}"
== "some sequence" | #Assert) &&
("nested #{ {str = {a = "braces"}.a}.str } !"
== "nested braces !" | #Assert) &&
((let x = "world" in
"Hello, #{x}! Welcome in #{let y = "universe" in "the #{x}-#{y}"}")
== "Hello, world! Welcome in the world-universe" | #Assert) &&
// regression test for issue #361 (https://github.com/tweag/nickel/issues/361)
(m#""#{"foo"}""#m == "\"foo\"" | #Assert) &&
(m#"""#m == "\"" | #Assert) &&
(m#""#"#"#"#m == "\"#\"#\"#" | #Assert) &&
true
[
// interpolation
"simple #{"interp" ++ "olation"} here" == "simple interpolation here",
"#{"alone"}" == "alone",
"nested #{ "#{(fun x => "#{x}") "expression"}" }" == "nested expression",
"#{"some"}#{" " ++ "se" ++ "qu"}#{"#{"ence"}"}" == "some sequence",
"nested #{ {str = {a = "braces"}.a}.str } !" == "nested braces !",
(let x = "world" in
"Hello, #{x}! Welcome in #{let y = "universe" in "the #{x}-#{y}"}")
== "Hello, world! Welcome in the world-universe",
// regression test for issue #361 (https://github.com/tweag/nickel/issues/361)
m#""#{"foo"}""#m == "\"foo\"",
m#"""#m == "\"",
m#""#"#"#"#m == "\"#\"#\"#",
]
|> lists.foldl (fun x y => (x | #Assert) && y) true

View File

@ -172,5 +172,4 @@ let typecheck = [
{"foo" = 1} : {foo : Num},
] in
true

View File

@ -1,6 +1,4 @@
let Assert = fun l x => x || %blame% l in
(let plus : Num -> Num -> Num = fun x => fun y => x + y in
plus (54 : Num) (6 : Num) == 60 | #Assert) &&
true
plus (54 : Num) (6 : Num) == 60 | #Assert)