Long ago @Brett took on the lame-but-important task of breaking the tests into individual files (from a giant, monolithic %core-tests.r file).
And as part of that task, I asked the favor of converting it from the traditional "tests-as-BLOCK!s":
; Original Rebol Test Format
["abba" = reverse "abba"]
[
foo: func [x] [
x + 1000
]
true ; tests have to return *exactly* LOGIC! true
]
[1020 = foo x]
[304 = foo -696]
...to use GROUP!s...
; Ren-C Adjusted Test Format
("abba" = reverse "abba")
(
foo: func [x] [
x + 1000
]
true
)
(1020 = foo x)
(304 = foo -696)
...it Wasn't Just Change for the Sake of Change...
I had a plan.
The idea was that I wanted to save the more "barrier-like" blocks to represent isolated groups. So then in the "someday" that we could run these tests into isolated contexts, we'd be able to group only those tests that needed to interact together.
While we were waiting for isolation technology to improve, the blocks were still used. They were just documentation.
But today that is no longer--by the magic of science they are isolated!
("abba" = reverse "abba") ; does not need foo, stands alone
[
(foo: func [x] [
x + 1000
]
true)
(1020 = foo x) ; uses foo, wants to be in same isolated context
(304 = foo -696) ; also sees foo
]
But It's Better Than I Thought!
We can actually isolate every test if we feel like it! We can run the thousands of tests and add nothing to the user context in the process!
Is it slower, you ask? No--IT'S MUCH FASTER! The GC can clean things up it's not using.
It Has Been A Good Test For Sea Of Words Modules! Making thousands of mini-modules was a good exercise and found a couple of bugs. Nothing too big, but certainly good to have that extra stress test.
(We still might try a mode where we don't isolate, just to throw a wrench in the GC and cause the user context to puff up. It's a semi-random sort of stress test.)
If BLOCK! Means "Isolate Test", Most Want The Insulation
["abba" = reverse "abba"] ; we can isolate this!
[
(foo: func [x] [ ; we can *not* isolate this...
x + 1000 ; ...and make that also mean "don't check result!"
]) ; ...so no need for the "true" here
[y: 1020, y = foo x] ; uses foo, doesn't need to expose Y
[304 = foo -696] ; uses foo, doesn't need to see Y
]
We don't quite yet have the underlying mechanisms to get that extra level of inheritance needed to isolate the "cluster" of tests, and then get that nested isolation for the blocks in the cluster. But it's likely not too far away!
Could We do Better With the Notation?
I tried some experimentation with separating out the idea of putting freeform code in the "cluster" of tests, and saying the freeform code is what's not isolated:
[
foo: func [x] [
x + 1000
]
[1020 = foo x]
[304 = foo -696]
]
You could imagine it running not just setup code for definitions, but also shutdown:
[
port: open %test-data.txt
[port? port]
[binary? read port]
close port
]
But trying my hand at it, I think being this freeform isn't a good idea for this particular dialect. There's potential for confusion since you're sensing so much based on when a block is on a newline or not. Seems easy to make mistakes.
Main thing to focus on here is the advancements in the isolation. I'll keep thinking on the dialect!