Stream: ideas

Topic: Nested expect statements


view this post on Zulip Aurélien Geron (Oct 07 2024 at 03:45):

While coding Exercism test cases, I often need to create some data structure (i.e., setup something), then run several tests on that structure. In such cases, unless I'm missing something, I have to create a named test function such as tests1 in the following example module:

module [createComplexDataStructure]

createComplexDataStructure = \a, b, c ->
    { a, b, c }

tests1 =
    data = createComplexDataStructure 1 2 3
    expect data.a == 1
    expect data.b == 2
    expect data.c == 3
    Bool.true

expect tests1

I can test this module using roc test MyModule.roc, no problem. But having to give the function a name is a bit of an inconvenience, especially in the context of Exercism (because the test cases are generated from a JSON template which does not provide a name for each test case, just a description, so I have to just number the test functions: tests1, tests2, etc.). It doesn't really feel natural to define tests1, make it return Bool.true, then call expect tests1.

It would be nice if I could just nest expect statements like this:

module [createComplexDataStructure]

createComplexDataStructure = \a, b, c ->
    { a, b, c }

expect
    data = createComplexDataStructure 1 2 3
    expect data.a == 1
    expect data.b == 2
    expect data.c == 3

Note that I didn't end with Bool.true, it feels unnecessary when we end with a nested expect statement.

view this post on Zulip Luke Boswell (Oct 07 2024 at 03:46):

I've done things like this before

expect
    data = createComplexDataStructure 1 2 3
    data.a == 1
    && data.b == 2
    && data.c == 3

view this post on Zulip Aurélien Geron (Oct 07 2024 at 04:02):

That's pretty nice. I did something like that, but it when it fails, it doesn't tell you what failed, whereas the very first example (the one with the tests1 function) does.

view this post on Zulip Richard Feldman (Oct 07 2024 at 11:21):

oh yeah I'd like this to Just Work! :+1:

view this post on Zulip Isaac Van Doren (Nov 23 2024 at 04:12):

Instead of requiring explicit use of the expect keyword to make multiple assertions at the end of an expect, what if we allowed the end of the expect to contain any number of boolean expressions that would all be checked?

Instead of this

expect
     complexRecord = myFunction 123 456
     expect complexRecord.foo == "bar"
     expect complexRecord.baz == 789

you could do this

expect
     complexRecord = myFunction 123 456
     complexRecord.foo == "bar"
     complexRecord.baz == 789

I use a test framework at work (Spock) that supports this and it is very natural and has not caused any problems that I can think of. When you are constantly writing multiple assertions at the end of each test it's nice to not be required to write out assert before each one.


Last updated: Jun 16 2026 at 16:19 UTC