[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC] Add assert statement to make unit testing easier for Poke code
From: |
Jose E. Marchesi |
Subject: |
Re: [RFC] Add assert statement to make unit testing easier for Poke code |
Date: |
Wed, 18 Nov 2020 09:37:36 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
Hi Mohammad.
Thanks for your proposal :)
> == Proposal
>
> I suggest to support the following `assert` statements:
>
> assert (condition);
> assert (condition, message);
> assert condition;
> assert condition, message;
>
> The parser will replace this statement with the following function call:
>
> _pkl_assert (condition, message, lineinfo)
>
> The `lineinfo` is a string containing the location of the statement:
>
> "<filename>:<line>:<col>"
>
> And implementation of `_pkl_assert` will something like this in `pkl-rt.pk`:
>
> ```poke
> fun _pkl_assert = (uint<1> condition, string msg, string lineinfo)
> {
> if (cond)
> return;
>
> raise Exception {
> code = EC_assert,
> msg = "Assertion failed at " + lineinfo + (msg'length ? ": " + msg :
> ""),
> exit_status = 1,
> };
> }
> ```
I think this can be achieved without having to introduce a special form
`assert'. Something like this:
fun assert (int condition, string msg,
int line, string file) = void:
{
if (!condition)
raise Exception {
code = EC_generic,
msg = "Assertion failed at " + itos (line) + file + (msg'length ?
": " + msg : ""),
exit_status = 1
};
}
That you invoke like:
assert ("foo"[n] == 102UB, "", __LINE__, __FILE);
We don't have an `itos' (integer to string) function in the standard
library yet though. You may want to write it :)
> == Usage
>
> The main use of `assert` in unit testing of Poke codes.
>
> For example, this is the re-write of some of string tests in
> `testsuite/poke.pkl/`:
>
> ```poke
> type TestFn = () void;
> type Test = struct
> {
> string name;
> TestFn func; /* Currently doesn't work! error: invalid type in struct
> field */
This will be possible soon.
> };
>
> var tests = [
> Test {
> name = "index",
> func = lambda void:
> {
> var n = 0;
>
> assert ("foo"[n] == 102UB);
> assert ("foo"[0] == 102UB);
>
> var s = "bar";
>
> n = 3;
> assert (("foo" + s)[n] == 98UB);
> assert (("foo" + "bar")[3] == 98UB);
> }
> },
> Test {
> name = "escape sequence",
> func = lambda void:
> {
> var s = "\1\12\1234;\12==\n";
>
> assert (s'length == 0o11UL);
> assert (s[0] == 0o1UB);
> assert (s[1] == 0o12UB);
> assert (s[2] == 0o123UB);
> assert (s[3:] == "4;\n==\n");
>
> assert ("\\"[0] == 0x5c);
> }
> },
> ];
>
> for (t in tests)
> {
> try t.func();
> catch (Exception ex)
> {
> printf ("FAIL %s: %s\n", t.name, ex.msg);
> continue;
> }
> print ("PASS " + t.name + "\n");
> }
> ```
>
>
> We also can define a pickle called `unittest` test to add some types and
> functions
> to make writing unit tests easier.
>
> I think this is very useful Poke users. And very easy to implement.
> The only thing `assert` give us is the location of the statement.
> WDYT?
> Any suggestion?
I think a simple native test harness written in Poke is a good idea.
But not precisely for testing things like `"foo"[n] == 102UB', i.e. not
for testing that the language is properly supported by the compiler: if
this can't be assumed, we can't actually trust the test harness itself!
However, testing the logic or pickles (or other Poke code) is a
completely different matter: a Poke test harness is ferfect for that.
For example, I have started adding tests for the pickles distributed
with poke, like in testsuite/poke.id3v1/*.pk, using the dejagnu dg test
harness, like the rest of the project. But if an infrastructure like
you suggest was in place I would certainly be open to use it instead for
these tests.
Salud!