# Plunit and keeping "clauses together"

**URL:** <https://swi-prolog.discourse.group/t/plunit-and-keeping-clauses-together/2406>\
**Category:** Help!\
**Tags:** discussion\
**Created:** [May 25, 2020, 2:23pm UTC](https://swi-prolog.discourse.group/t/plunit-and-keeping-clauses-together/2406 "2020-05-25T14:23:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [May 25, 2020, 2:23pm UTC](https://swi-prolog.discourse.group/t/plunit-and-keeping-clauses-together/2406/1 "2020-05-25T14:23:06Z")

</div>

Some test code:

```prolog
:- begin_tests(member).

   % Standard success

   test(t1, true, [nondet]) :- member(1,[1,2,3]).

   % Succeed twice

   test(t2, all(X == [1,1])) :- X=1, member(X,[1,2,3,1]).

   % Succeed even if the "list" is a non-list, as long as the prefix contains 1

   test(t3, true, [nondet]) :- L=[1,2,3|nope], \+is_list(L), member(1,L).

:- end_tests(member).

rt(member) :- run_tests(member).

```

When we load this:

```prolog
?- [member_test].
Warning: /home/me/member_test.pl:13:
Warning: Clauses of plunit_member:test/3 are not together in the source-file
Warning: Earlier definition at /home/me/member_test.pl:5
Warning: Current predicate: plunit_member:'unit body'/2
Warning: Use :- discontiguous plunit_member:test/3. to suppress this message
true.

```

Is this is expected? It might be best to suppress this warning, right?

Alternatively, I can apparently write this, (second-guessing the documentation), inserting `true` before `all`:

```prolog
test(t2, true, all(X == [1,1])) :- X=1, member(X,[1,2,3,1]).

```

Then everything is `test/3` and the compiler does not warn.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [May 25, 2020, 2:33pm UTC](https://swi-prolog.discourse.group/t/plunit-and-keeping-clauses-together/2406/2 "2020-05-25T14:33:41Z")

</div>

> [@dtonhofer](#):
>
> Is this is expected?

Yes

> [@dtonhofer](#):
>
> It might be best to suppress this warning, right?

You say tomato, I say tomato.

I have never seen someone calling that a taboo, but in test cases I would avoid doing that.

* * *

If you [search](https://github.com/SWI-Prolog/swipl-devel/search?q=begin_tests&unscoped_q=begin_tests) the SWI-Prolog source code at GitHub for `begin_tests` you will see lots of examples and possibly get some other ideas. If you see `discontiguous` used with these test I would like to know for future reference. Also be aware that the source code has some older styles of test cases and those I personally do not use as examples with the newer style using `begin_tests`.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [May 25, 2020, 3:24pm UTC](https://swi-prolog.discourse.group/t/plunit-and-keeping-clauses-together/2406/3 "2020-05-25T15:24:10Z")

</div>

> [@dtonhofer](#):
>
> `test(t1, true, [nondet])`

Tests are declared with a _head_ being either test(Name) or test(Name, Properties), i.e. test/1 or test/2. Anything else is just a predicate. No properties means `true`. A single property can be written without a list. Multiple need a list. So this would be

```
 test(t1, [true,nondet]) :-

```

Now, `nondet` is not the usual mode determinism declaration. In this context it means _“succeeds, possibly with open choice points”_ and thus the `true` is not needed.

So, the intended way to write this is

```
test(t1, nondet) :- member(1,[1,2,3]).

```

> [@dtonhofer](#):
>
> `L=[1,2,3|nope], \+is_list(L)`

Why the `\+ is_list(L)`? You know it is not a list. You are testing member/2 (I assume). If you were testing list you’d write

```
test(nonlist, fail) :- is_list([1,2,3|nope).

```

---

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [May 25, 2020, 6:47pm UTC](https://swi-prolog.discourse.group/t/plunit-and-keeping-clauses-together/2406/4 "2020-05-25T18:47:51Z")

</div>

Thanks jan.

I see I have been deluding myself. test/3 is not called at all vi run\_tests/1, indeed.

Indeed,

```prolog
   test(t3, [nondet]) :- L=[1,2,3|nope], \+is_list(L), member(1,L).

```

Yes, this is a test for member. But I wanted to inform the reader/myself that this is a test for “not a list”.

One could even write:

```prolog
   test(notalist_1, [nondet]) :- (L=[1,2,3|nope], \+is_list(L)) -> member(1,L).
   test(notalist_2, all(X == [1,2,3])) :- (L=[1,2,3|nope], \+is_list(L)) -> member(X,L).

```

---

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [May 25, 2020, 6:50pm UTC](https://swi-prolog.discourse.group/t/plunit-and-keeping-clauses-together/2406/5 "2020-05-25T18:50:51Z")

</div>

Thanks Eric. That’s a lot of code!
