Skip to content

Commit

Permalink
move Assert and check to the stdlib (#1914)
Browse files Browse the repository at this point in the history
Move the Assert and check function from the local test library to the
stdlib, under the name of `std.test.Assert` and `std.test.assert_all`.

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@gmail.com>
  • Loading branch information
ajbt200128 and yannham authored May 24, 2024
1 parent c8e8401 commit 928cf14
Show file tree
Hide file tree
Showing 51 changed files with 159 additions and 157 deletions.
15 changes: 7 additions & 8 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,13 @@ directory. All `.ncl` files in this directory are automatically converted into
Rust integration tests, which run the file and assert that no errors were
raised during evaluation.

Each of these `.ncl` files is structured as an array of `Bool` expressions, which
is ultimately passed to a `check` function defined in
`core/tests/integration/pass/lib/assert.ncl`.
This function applies an `Assert` contract to each value in the array, which
checks that the value it is applied to evaluates to `true`. The benefit of using
a contract for this is that if a test fails we can simply run the file directly
using Nickel, which gives better error messages than the ones we get by default
from `cargo test`.
Each of these `.ncl` files is structured as an array of `Bool` expressions,
which is ultimately passed to `std.contract.check` function defined in the
standard library. This function applies an `Assert` (`std.test.Assert`)
contract to each value in the array, which checks that the value it is applied
to evaluates to `true`. The benefit of using a contract for this is that if a
test fails we can simply run the file directly using Nickel, which gives better
error messages than the ones we get by default from `cargo test`.

Tests which are expected to fail may be written in Rust in `core/tests/integration`.
However, simple failure test cases can make use of the test annotation support
Expand Down
38 changes: 38 additions & 0 deletions core/stdlib/std.ncl
Original file line number Diff line number Diff line change
Expand Up @@ -3085,6 +3085,44 @@
= fun s => %enum_from_str% s,
},

test = {
Assert
| doc m%"
A contract that checks if its argument is the boolean true.

# Examples

```nickel
1 == 2 | std.test.Assert
=> error: contract broken by a value

1 == 1 | std.test.Assert
=> true
```
"%
= fun label value => if value then true else %blame% label,

assert_all
| Array Assert -> Bool
| doc m%"
Asserts that all the elements of an array are equal to true. Applies the
`std.test.Assert` contract on each element of the given array.

Evalutes to `true` if all the elements of the array are equal to true,
or fails with a contract error otherwise.

# Example

```nickel
[ (1 == 2), (1 == 1), (1 == 3) ] |> std.test.assert_all
=> error: contract broken by a value
```
"%
# We mostly rely on the contracts to do the work here. We just need to
# make sure each element of the array is properly forced.
= std.array.all (fun x => x),
},

is_number
: Dyn -> Bool
| doc m%"
Expand Down
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/adts/enum_primops.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
%enum_unwrap_variant% ('Left (1+1)) == 2,
Expand All @@ -8,4 +8,4 @@ let {check, ..} = import "../lib/assert.ncl" in
%enum_get_tag% 'Right == 'Right,
%enum_get_tag% ('Right "stuff") == 'Right,
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/contracts/contracts.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, Assert, ..} = import "../lib/assert.ncl" in
let Assert = std.test.Assert in

[
let AlwaysTrue = fun l t =>
Expand Down Expand Up @@ -179,4 +179,4 @@ let {check, Assert, ..} = import "../lib/assert.ncl" in
in
tag == 'some_tag,
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/contracts/let_order.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let { check, Assert, .. } = import "../lib/assert.ncl" in

let ConstantTrue = fun _label value => std.seq value true in
[
let foo | ConstantTrue | Bool = "not a bool" in
Expand All @@ -12,4 +12,4 @@ let ConstantTrue = fun _label value => std.seq value true in
= "still not a bool"
}.foo
]
|> check
|> std.test.assert_all
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
# check that a record type literal is indeed converted to the corresponding
Expand All @@ -21,4 +21,4 @@ let {check, ..} = import "../lib/assert.ncl" in
& {foo | force = false, bar | force = true})
== {foo = false, bar = true},
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/core/arrays.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
# accesses
Expand Down Expand Up @@ -49,4 +49,4 @@ let {check, ..} = import "../lib/assert.ncl" in

std.array.map_with_index (+) [1, 2, 3] == [1, 3, 5],
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/core/basics.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
# basic arithmetic
Expand Down Expand Up @@ -35,4 +35,4 @@ let {check, ..} = import "../lib/assert.ncl" in
# This test checks that the terms of a match are closured
let x = 3 in ((3 + 2) |> match { 'foo => 1, _ => x}) == 3,
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/core/builtins.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
# is_record
Expand Down Expand Up @@ -28,4 +28,4 @@ let {check, ..} = import "../lib/assert.ncl" in
|> std.deserialize 'Json
== [3,4],
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/core/curried_dot.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


let record = {foo = 1, bar = { baz = 2 }} in
let field = "bar" in
Expand All @@ -9,4 +9,4 @@ let part = "ba" in
(.) record field == { baz = 2 },
let res = (.) record field == {baz = 2} in res,
(.) record "%{part}r" == { baz = 2 },
] |> check
] |> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/core/eq.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
# basic
Expand Down Expand Up @@ -84,4 +84,4 @@ let {check, ..} = import "../lib/assert.ncl" in
'Left 2 != 'Right 2,
'Up [1,2,3] == 'Up [0+1,1+1,2+1],
]
|> check
|> std.test.assert_all
2 changes: 1 addition & 1 deletion core/tests/integration/inputs/core/fibo.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {Assert, ..} = import "../lib/assert.ncl" in
let Assert = std.test.Assert in

let Y | ((Number -> Number) -> Number -> Number) -> Number -> Number = fun f => (fun x => f (x x)) (fun x => f (x x)) in
let dec : Number -> Number = fun x => x + (-1) in
Expand Down
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/core/functions.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
(fun x => x) 3 == 3,
Expand All @@ -16,4 +16,4 @@ let {check, ..} = import "../lib/assert.ncl" in
g true
== 4,
]
|> check
|> std.test.assert_all
2 changes: 1 addition & 1 deletion core/tests/integration/inputs/core/import.ncl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# test.type = 'pass'
let { Assert, .. } = import "../lib/assert.ncl" in
let Assert = std.test.Assert in
((import "../lib/imported.ncl") 3 == 3 | Assert)
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/core/numbers.ncl
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
5 + 5 == 10,
5 * 5 == 25,
1e6 == 1000000,
1e+3 / 2e-3 == 0.5e6,
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/core/records.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let { check, .. } = import "../lib/assert.ncl" in


[
# accesses
Expand Down Expand Up @@ -171,4 +171,4 @@ let { check, .. } = import "../lib/assert.ncl" in
&& r.force == "no"
)
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/core/recursive_let.ncl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
let rec f = fun n => if n == 0 then n else f (n - 1) in f 10 == 0,
let rec fib = fun n => if n == 0 || n == 1 then 1 else fib (n - 1) + fib (n - 2) in fib 5 == 8,
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/imports/yaml_import.ncl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# test.type = 'pass'

let {check, ..} = import "../lib/assert.ncl" in

[
(import "imported/empty.yaml") == null,

Expand All @@ -9,4 +9,4 @@ let {check, ..} = import "../lib/assert.ncl" in
{ type = "event", id = 2 }
],
]
|> check
|> std.test.assert_all
31 changes: 0 additions & 31 deletions core/tests/integration/inputs/lib/assert.ncl

This file was deleted.

4 changes: 2 additions & 2 deletions core/tests/integration/inputs/merging/adts.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let { check, .. } = import "../lib/assert.ncl" in


[
'Foo true & 'Foo true == 'Foo true,
Expand All @@ -13,4 +13,4 @@ let { check, .. } = import "../lib/assert.ncl" in
& { two.b = 1, one = 'Qux {c = 0} }
== { one = 'Qux { a = 1, b = 1, c = 0 }, two = { a = 1, b = 1 } },
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/merging/array-merge.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
# array pointwise merging
Expand All @@ -25,4 +25,4 @@ let {check, ..} = import "../lib/assert.ncl" in
& ([0 + 0, 1 + 0, 2 + 0] | Array AddOne)
== [1, 2, 3],
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/merging/lazy-propagation.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, Assert, ..} = import "../lib/assert.ncl" in


# tests related to RFC005. Check in particular that the motivating examples of
# RFC005 are indeed fixed by lazy propagation.
Expand Down Expand Up @@ -44,4 +44,4 @@ let {check, Assert, ..} = import "../lib/assert.ncl" in
& {bar = "bar"})
== {foo = 5, bar = "bar"},
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/merging/metavalues.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, Assert, ..} = import "../lib/assert.ncl" in
let Assert = std.test.Assert in

[
{val | default | Number = 10}.val == 10,
Expand Down Expand Up @@ -132,4 +132,4 @@ let {check, Assert, ..} = import "../lib/assert.ncl" in
(%fields% value == ["foo", "opt"] | Assert)
),
]
|> check
|> std.test.assert_all
6 changes: 3 additions & 3 deletions core/tests/integration/inputs/merging/multiple_overrides.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
# regression test for issue #908 (https://github.com/tweag/nickel/issues/908)
Expand Down Expand Up @@ -121,6 +121,6 @@ let {check, ..} = import "../lib/assert.ncl" in
fst_data = "override",
snd_data = "override",
}
] |> check,
] |> std.test.assert_all,
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/merging/overriding.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {check, ..} = import "../lib/assert.ncl" in


[
{foo | default = 1} & {foo = 2} == {foo = 2},
Expand Down Expand Up @@ -72,4 +72,4 @@ let {check, ..} = import "../lib/assert.ncl" in
({foo | default = 1, bar = foo} & {foo = 2}).bar == 2,
({foo | default = 1, bar = foo, baz = bar} & {foo = 2}).baz == 2,
]
|> check
|> std.test.assert_all
4 changes: 2 additions & 2 deletions core/tests/integration/inputs/merging/priorities.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# test.type = 'pass'
let {Assert, check, ..} = import "../lib/assert.ncl" in
let Assert = std.test.Assert in

[
let block1 = {
Expand Down Expand Up @@ -83,4 +83,4 @@ let {Assert, check, ..} = import "../lib/assert.ncl" in
# } in
# {val | rec force = x } & {val = {foo = 0, bar = 10}}
# == {val = {bar = 10, foo = 1 + 2 + 10}} | Assert,
] |> check
] |> std.test.assert_all
Loading

0 comments on commit 928cf14

Please sign in to comment.