Good support for unit tests
I suggest the following:
-
Implement a special function (or effect operator) to obtain the filename / line number / column number of the current function call.
This makes it possible for unit test libraries to provide this information. This makes it easy to determine which unit test failed, and it avoids the need to give names to unit tests, which makes unit tests more convenient.
-
Implement a special function / effect operator / syntax to selectively run code only on certain platforms (e.g. browser, Node, C#, etc.). This is important because some code / unit tests is designed to only be run on certain platforms.
-
The standard library should include a good unit testing library which uses the above two features.
This means that all Koka projects have access to unit testing without needing to install a third-party library.
This is really important: the more convenient it is to write unit tests, the more likely people are to actually write unit tests.
I think it is important that it is possible to write the unit tests in the same file as the code that they are testing.
An API for the unit tests might look something like this:
// In foo.kk
var foo: int = 1
fun tests(): test () {
assert(foo == 1)
}
// In bar.kk
var bar: int = 2
fun tests(): test () {
assert(bar == 2)
}
// In test.kk
import foo
import bar
fun main(): asyncx () {
run-test(interleaved([
foo/tests,
bar/tests
]))
}
So we have a test effect, which has the assert operator. The assert operator checks if its argument is true, and if not it fails. When it fails, it logs the filename, line number, and column, which makes it easy to identify which assert failed.
The run-test function runs a unit test, and interleaved is used to run the unit tests in parallel. This can be shortened to run-tests([...]) which does the same thing.
Each module can export a tests function which runs the unit tests for that module. It doesn't have to be called tests, that's just a convention.
Dead code elimination will remove the tests function from production builds, so it doesn't have any performance cost when not running unit tests.
We'll probably also need various mocks for some things, and fuzz testing (e.g. QuickCheck), but QuickCheck might be difficult to implement due to the lack of typeclasses.
The current dev, soon to be released, will have support for the magic variables kk-file (module name and line),kk-line, and kk-module, as well as a different solution to typeclasses by using some pretty powerful implicit parameters. Check out https://github.com/koka-lang/koka/blob/dev/samples/syntax/implicits.kk for more details on this aspect. That should cover most of the requests I think, other than a builtin testing library, and a way to conditionally include code based on platform.