[m-rev.] for review: document failrue conditions for list.split/4
Julien Fischer
jfischer at opturion.com
Thu Jun 2 12:06:38 AEST 2016
For review by anyone.
I would also be intrested in feedback whether the current behaviour
of list.{drop,take} when their first argument is negative is intended.
-----------------
Document failure conditions for list.split/4.
Improve test coverage of list.split_list, list.drop and list.take.
library/list.m:
Document the failure conditions for split_list/4.
Document that det_split_list/4 will also throw an exception for N < 0.
tests/hard_coded/split_list.{m,exp}:
Test for list.split_list/4.
tests/hard_coded/take_and_drop.m:
Ditto for list.take/3 and list.drop/3.
tests/hard_coded/Mmakefile:
Add the new tests.
Julien.
diff --git a/library/list.m b/library/list.m
index ddd5f96..2cb24f4 100644
--- a/library/list.m
+++ b/library/list.m
@@ -209,15 +209,16 @@
% split_list(Len, List, Start, End):
%
% splits `List' into a prefix `Start' of length `Len', and a remainder
- % `End'. See also: take, drop and split_upto.
+ % `End'. Fails if `Len' is not in 0 .. length(List).
+ % See also: take, drop and split_upto.
%
:- pred split_list(int::in, list(T)::in, list(T)::out, list(T)::out)
is semidet.
% det_split_list(Len, List, Start, End):
%
- % A deterministic version of split_list, which aborts instead
- % of failing if Len > length(List).
+ % A deterministic version of split_list, which aborts instead of failing if
+ % `Len' is not in 0 .. length(List).
%
:- pred det_split_list(int::in, list(T)::in, list(T)::out, list(T)::out)
is det.
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index ca2c3c1..6d7bb01 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -272,6 +272,7 @@ ORDINARY_PROGS = \
space \
spawn_native \
special_char \
+ split_list \
stable_sort \
static_no_tag \
stdlib_init \
@@ -311,6 +312,7 @@ ORDINARY_PROGS = \
switch_detect \
system_sort \
tag_switch_dup_label \
+ take_and_drop \
term_io_test \
term_to_univ_test \
test234_sorted_insert \
diff --git a/tests/hard_coded/split_list.exp b/tests/hard_coded/split_list.exp
index e69de29..d201d22 100644
--- a/tests/hard_coded/split_list.exp
+++ b/tests/hard_coded/split_list.exp
@@ -0,0 +1,13 @@
+split_list(-1, []) ==> <<FALSE>>
+split_list(-1, [111]) ==> <<FALSE>>
+split_list(-1, [111, 222]) ==> <<FALSE>>
+split_list(0, []) ==> ([], [])
+split_list(0, [111]) ==> ([], [111])
+split_list(0, [111, 222]) ==> ([], [111, 222])
+split_list(1, []) ==> <<FALSE>>
+split_list(1, [111]) ==> ([111], [])
+split_list(1, [111, 222]) ==> ([111], [222])
+split_list(2, []) ==> <<FALSE>>
+split_list(2, [111]) ==> <<FALSE>>
+split_list(2, [111, 222]) ==> ([111, 222], [])
+split_list(2, [111, 222, 333]) ==> ([111, 222], [333])
diff --git a/tests/hard_coded/split_list.m b/tests/hard_coded/split_list.m
index e69de29..76f064e 100644
--- a/tests/hard_coded/split_list.m
+++ b/tests/hard_coded/split_list.m
@@ -0,0 +1,49 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+%
+% Test list.split_list/4.
+
+:- module split_list.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module assoc_list.
+:- import_module list.
+:- import_module pair.
+:- import_module string.
+
+main(!IO) :-
+ list.foldl(run_test, tests, !IO).
+
+:- pred run_test(pair(int, list(int))::in, io::di, io::uo) is det.
+
+run_test(N - List, !IO) :-
+ io.format("split_list(%d, %s) ==> ", [i(N), s(string(List))], !IO),
+ ( if list.split_list(N, List, Start, End)
+ then io.format("(%s, %s)\n", [s(string(Start)), s(string(End))], !IO)
+ else io.write_string("<<FALSE>>\n", !IO)
+ ).
+
+:- func tests = assoc_list(int, list(int)).
+
+tests = [
+ -1 - [],
+ -1 - [111],
+ -1 - [111, 222],
+ 0 - [],
+ 0 - [111],
+ 0 - [111, 222],
+ 1 - [],
+ 1 - [111],
+ 1 - [111, 222],
+ 2 - [],
+ 2 - [111],
+ 2 - [111, 222],
+ 2 - [111, 222, 333]
+].
diff --git a/tests/hard_coded/take_and_drop.exp b/tests/hard_coded/take_and_drop.exp
index e69de29..8eb2abd 100644
--- a/tests/hard_coded/take_and_drop.exp
+++ b/tests/hard_coded/take_and_drop.exp
@@ -0,0 +1,33 @@
+take(-2, []) ==> []
+take(-2, [111]) ==> []
+take(-2, [111, 222]) ==> []
+take(-1, []) ==> []
+take(-1, [111]) ==> []
+take(-1, [111, 222]) ==> []
+take(0, []) ==> []
+take(0, [111]) ==> []
+take(0, [111, 222]) ==> []
+take(1, []) ==> <<FALSE>>
+take(1, [111]) ==> [111]
+take(1, [111, 222]) ==> [111]
+take(2, []) ==> <<FALSE>>
+take(2, [111]) ==> <<FALSE>>
+take(2, [111, 222]) ==> [111, 222]
+take(2, [111, 222, 333]) ==> [111, 222]
+
+drop(-2, []) ==> []
+drop(-2, [111]) ==> [111]
+drop(-2, [111, 222]) ==> [111, 222]
+drop(-1, []) ==> []
+drop(-1, [111]) ==> [111]
+drop(-1, [111, 222]) ==> [111, 222]
+drop(0, []) ==> []
+drop(0, [111]) ==> [111]
+drop(0, [111, 222]) ==> [111, 222]
+drop(1, []) ==> <<FALSE>>
+drop(1, [111]) ==> []
+drop(1, [111, 222]) ==> [222]
+drop(2, []) ==> <<FALSE>>
+drop(2, [111]) ==> <<FALSE>>
+drop(2, [111, 222]) ==> []
+drop(2, [111, 222, 333]) ==> [333]
diff --git a/tests/hard_coded/take_and_drop.m b/tests/hard_coded/take_and_drop.m
index e69de29..b648ee3 100644
--- a/tests/hard_coded/take_and_drop.m
+++ b/tests/hard_coded/take_and_drop.m
@@ -0,0 +1,56 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+%
+% Test list.take/3 and list.drop/3.
+
+:- module take_and_drop.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module assoc_list.
+:- import_module list.
+:- import_module pair.
+:- import_module string.
+
+main(!IO) :-
+ list.foldl(run_test("take", take), tests, !IO),
+ io.nl(!IO),
+ list.foldl(run_test("drop", drop), tests, !IO).
+
+:- pred run_test(string::in,
+ pred(int, list(T), list(T))::in(pred(in, in, out) is semidet),
+ pair(int, list(T))::in, io::di, io::uo) is det.
+
+run_test(Name, Pred, N - List, !IO) :-
+ io.format("%s(%d, %s) ==> ", [s(Name), i(N), s(string(List))], !IO),
+ ( if Pred(N, List, Result)
+ then io.format("%s\n", [s(string(Result))], !IO)
+ else io.write_string("<<FALSE>>\n", !IO)
+ ).
+
+:- func tests = assoc_list(int, list(int)).
+
+tests = [
+ -2 - [],
+ -2 - [111],
+ -2 - [111, 222],
+ -1 - [],
+ -1 - [111],
+ -1 - [111, 222],
+ 0 - [],
+ 0 - [111],
+ 0 - [111, 222],
+ 1 - [],
+ 1 - [111],
+ 1 - [111, 222],
+ 2 - [],
+ 2 - [111],
+ 2 - [111, 222],
+ 2 - [111, 222, 333]
+].
More information about the reviews
mailing list