1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2007-2018. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21-module(array_SUITE).
22
23-include_lib("common_test/include/ct.hrl").
24
25%% Test server specific exports
26-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
27	 init_per_group/2,end_per_group/2]).
28-export([init_per_testcase/2, end_per_testcase/2]).
29
30-export([
31  	 new_test/1,
32	 fix_test/1,
33	 relax_test/1,
34	 resize_test/1,
35  	 set_get_test/1,
36  	 to_list_test/1,
37  	 sparse_to_list_test/1,
38  	 from_list_test/1,
39  	 to_orddict_test/1,
40  	 sparse_to_orddict_test/1,
41  	 from_orddict_test/1,
42  	 map_test/1,
43  	 sparse_map_test/1,
44  	 foldl_test/1,
45  	 sparse_foldl_test/1,
46  	 foldr_test/1,
47  	 sparse_foldr_test/1
48	]).
49
50
51-export([t/0,t/1,extract_tests/0]).
52
53-import(array,
54	[new/0, new/1, new/2, is_array/1, set/3, get/2, %size/1,
55	 sparse_size/1, default/1, reset/2, to_list/1, sparse_to_list/1,
56	 from_list/1, from_list/2, to_orddict/1, sparse_to_orddict/1,
57	 from_orddict/1, from_orddict/2, map/2, sparse_map/2, foldl/3,
58	 foldr/3, sparse_foldl/3, sparse_foldr/3, fix/1, relax/1, is_fix/1,
59	 resize/1, resize/2]).
60
61%%
62%% all/1
63%%
64suite() ->
65    [{ct_hooks,[ts_install_cth]},
66     {timetrap,{minutes,1}}].
67
68all() ->
69    [new_test, fix_test, relax_test, resize_test,
70     set_get_test, to_list_test, sparse_to_list_test,
71     from_list_test, to_orddict_test, sparse_to_orddict_test,
72     from_orddict_test, map_test, sparse_map_test,
73     foldl_test, sparse_foldl_test, foldr_test,
74     sparse_foldr_test].
75
76groups() ->
77    [].
78
79init_per_suite(Config) ->
80    Config.
81
82end_per_suite(_Config) ->
83    ok.
84
85init_per_group(_GroupName, Config) ->
86    Config.
87
88end_per_group(_GroupName, Config) ->
89    Config.
90
91
92init_per_testcase(_Case, Config) ->
93    Config.
94
95end_per_testcase(_Case, _Config) ->
96    ok.
97
98-define(LEAFSIZE,10).
99-define(NODESIZE,?LEAFSIZE).
100
101-record(array,  {size,		%% number of defined entries
102		 max,		%% maximum number of entries in current tree
103		 default,	%% the default value (usually 'undefined')
104		 elements	%% the tuple tree
105		}).
106
107-define(_assert(What),
108	begin true = What end
109       ).
110-define(_assertNot(What),
111	begin false = What end
112       ).
113
114-define(_assertMatch(Res,What),
115	begin
116	    case What of Res -> ok end
117	end
118       ).
119-define(_assertError(Reas,What),
120	begin fun() ->
121			    try What of
122				A_Success -> exit({test_error, A_Success})
123			    catch error:Reas -> ok end
124		    end()
125	end
126       ).
127
128-define(LET(Var,Expr, Test), begin fun() -> Var = Expr, Test end() end).
129
130-define(_test(Expr), begin Expr end).
131
132%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133%% Some helpers to be able to run the tests without testserver
134%%%%%%%%%%%%%%%%%%%%%%%%%
135t() -> t([all]).
136
137t(What) when not is_list(What) ->
138    t([What]);
139t(What) ->
140    lists:foreach(fun(T) ->
141			  io:format("Test ~p ~n",[T]),
142			  try
143			      ?MODULE:T([])
144			  catch _E:_R:_S ->
145				  Line = get(test_server_loc),
146				  io:format("Failed ~p:~p ~p ~p~n   ~p~n",
147					    [T,Line,_E,_R,_S])
148			  end
149		  end, What).
150
151%%%%% extract tests
152
153extract_tests() ->
154    {ok, In} = file:open("../src/array.erl", [read]),
155    {ok, Out} = file:open("array_temp.erl", [write]),
156    try
157	Tests = extract_tests(In,Out,[]),
158	Call = fun(Test) ->
159		       io:format(Out, "~s(Config) when is_list(Config) -> ~s_(), ok.~n",
160				 [Test, Test])
161	       end,
162	[Call(Test) || Test <- Tests],
163	io:format("Tests ~p~n", [Tests])
164    catch _:Err:Stacktrace ->
165	    io:format("Error: ~p ~p~n", [Err, Stacktrace])
166    end,
167    file:close(In),
168    file:close(Out).
169
170extract_tests(In,Out,Tests) ->
171    case io:get_line(In,"") of
172	eof -> lists:reverse(Tests);
173	"-ifdef(EUNIT)" ++ _ ->
174	    Test = write_test(In,Out),
175	    extract_tests(In,Out, [Test|Tests]);
176	_E ->
177	    extract_tests(In,Out,Tests)
178    end.
179
180write_test(In,Out) ->
181    Line = io:get_line(In,""),
182    io:put_chars(Out, Line),
183    [$_|Test] = lists:dropwhile(fun($_) -> false;(_) -> true end,lists:reverse(Line)),
184    write_test_1(In,Out),
185    lists:reverse(Test).
186
187write_test_1(In,Out) ->
188    case io:get_line(In,"") of
189	"-endif" ++ _ ->
190	    io:nl(Out),
191	    ok;
192	Line ->
193	    io:put_chars(Out, Line),
194	    write_test_1(In,Out)
195    end.
196
197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
198%% Actual tests
199
200new_test_() ->
201    N0 = ?LEAFSIZE,
202    N01 = N0+1,
203    N1 = ?NODESIZE*N0,
204    N11 = N1+1,
205    N2 = ?NODESIZE*N1,
206    [?_test(new()),
207
208     ?_test(new([])),
209     ?_test(new(10)),
210     ?_test(new({size,10})),
211     ?_test(new(fixed)),
212     ?_test(new({fixed,true})),
213     ?_test(new({fixed,false})),
214     ?_test(new({default,undefined})),
215     ?_test(new([{size,100},{fixed,false},{default,undefined}])),
216     ?_test(new([100,fixed,{default,0}])),
217
218     ?_assert(new() =:= new([])),
219     ?_assert(new() =:= new([{size,0},{default,undefined},{fixed,false}])),
220     ?_assert(new() =:= new(0, {fixed,false})),
221     ?_assert(new(fixed) =:= new(0)),
222     ?_assert(new(fixed) =:= new(0, [])),
223     ?_assert(new(10) =:= new([{size,0},{size,5},{size,10}])),
224     ?_assert(new(10) =:= new(0, {size,10})),
225     ?_assert(new(10, []) =:= new(10, [{default,undefined},{fixed,true}])),
226
227     ?_assertError(badarg, new(-1)),
228     ?_assertError(badarg, new(10.0)),
229     ?_assertError(badarg, new(undefined)),
230     ?_assertError(badarg, new([undefined])),
231     ?_assertError(badarg, new([{default,0} | fixed])),
232
233     ?_assertError(badarg, new(-1, [])),
234     ?_assertError(badarg, new(10.0, [])),
235     ?_assertError(badarg, new(undefined, [])),
236
237     ?_assertMatch(#array{size=0,max=N0,default=undefined,elements=N0},
238		   new()),
239     ?_assertMatch(#array{size=0,max=0,default=undefined,elements=N0},
240		   new(fixed)),
241     ?_assertMatch(#array{size=N0,max=N0,elements=N0},
242		   new(N0, {fixed,false})),
243     ?_assertMatch(#array{size=N01,max=N1,elements=N1},
244		   new(N01, {fixed,false})),
245     ?_assertMatch(#array{size=N1,max=N1,elements=N1},
246		   new(N1, {fixed,false})),
247     ?_assertMatch(#array{size=N11,max=N2,elements=N2},
248		   new(N11, {fixed,false})),
249     ?_assertMatch(#array{size=N2, max=N2, default=42,elements=N2},
250		   new(N2, [{fixed,false},{default,42}])),
251
252     ?_assert(0 =:= array:size(new())),
253     ?_assert(17 =:= array:size(new(17))),
254     ?_assert(100 =:= array:size(array:set(99,0,new()))),
255     ?_assertError(badarg, array:size({bad_data,gives_error})),
256
257     ?_assert(undefined =:= default(new())),
258     ?_assert(4711 =:= default(new({default,4711}))),
259     ?_assert(0 =:= default(new(10, {default,0}))),
260     ?_assertError(badarg, default({bad_data,gives_error})),
261
262     ?_assert(is_array(new())),
263     ?_assert(false =:= is_array({foobar, 23, 23})),
264     ?_assert(false =:= is_array(#array{size=bad})),
265     ?_assert(false =:= is_array(#array{max=bad})),
266     ?_assert(is_array(new(10))),
267     ?_assert(is_array(new(10, {fixed,false})))
268    ].
269
270fix_test_() ->
271    [?_assert(is_array(fix(new()))),
272     ?_assert(fix(new()) =:= new(fixed)),
273
274     ?_assertNot(is_fix(new())),
275     ?_assertNot(is_fix(new([]))),
276     ?_assertNot(is_fix(new({fixed,false}))),
277     ?_assertNot(is_fix(new(10, {fixed,false}))),
278     ?_assert(is_fix(new({fixed,true}))),
279     ?_assert(is_fix(new(fixed))),
280     ?_assert(is_fix(new(10))),
281     ?_assert(is_fix(new(10, []))),
282     ?_assert(is_fix(new(10, {fixed,true}))),
283     ?_assert(is_fix(fix(new()))),
284     ?_assert(is_fix(fix(new({fixed,false})))),
285
286     ?_test(set(0, 17, new())),
287     ?_assertError(badarg, set(0, 17, new(fixed))),
288     ?_assertError(badarg, set(1, 42, fix(set(0, 17, new())))),
289
290     ?_test(set(9, 17, new(10))),
291     ?_assertError(badarg, set(10, 17, new(10))),
292     ?_assertError(badarg, set(10, 17, fix(new(10, {fixed,false}))))
293    ].
294
295relax_test_() ->
296    [?_assert(is_array(relax(new(fixed)))),
297     ?_assertNot(is_fix(relax(fix(new())))),
298     ?_assertNot(is_fix(relax(new(fixed)))),
299
300     ?_assert(new() =:= relax(new(fixed))),
301     ?_assert(new() =:= relax(new(0))),
302     ?_assert(new(17, {fixed,false}) =:= relax(new(17))),
303     ?_assert(new(100, {fixed,false})
304	      =:= relax(fix(new(100, {fixed,false}))))
305    ].
306
307resize_test_() ->
308    [?_assert(resize(0, new()) =:= new()),
309     ?_assert(resize(99, new(99)) =:= new(99)),
310     ?_assert(resize(99, relax(new(99))) =:= relax(new(99))),
311     ?_assert(is_fix(resize(100, new(10)))),
312     ?_assertNot(is_fix(resize(100, relax(new(10))))),
313
314     ?_assert(array:size(resize(100, new())) =:= 100),
315     ?_assert(array:size(resize(0, new(100))) =:= 0),
316     ?_assert(array:size(resize(99, new(10))) =:= 99),
317     ?_assert(array:size(resize(99, new(1000))) =:= 99),
318
319     ?_assertError(badarg, set(99, 17, new(10))),
320     ?_test(set(99, 17, resize(100, new(10)))),
321     ?_assertError(badarg, set(100, 17, resize(100, new(10)))),
322
323     ?_assert(array:size(resize(new())) =:= 0),
324     ?_assert(array:size(resize(new(8))) =:= 0),
325     ?_assert(array:size(resize(array:set(7, 0, new()))) =:= 8),
326     ?_assert(array:size(resize(array:set(7, 0, new(10)))) =:= 8),
327     ?_assert(array:size(resize(array:set(99, 0, new(10,{fixed,false}))))
328	      =:= 100),
329     ?_assert(array:size(resize(array:set(7, undefined, new()))) =:= 0),
330     ?_assert(array:size(resize(array:from_list([1,2,3,undefined])))
331	      =:= 3),
332     ?_assert(array:size(
333		resize(array:from_orddict([{3,0},{17,0},{99,undefined}])))
334	      =:= 18),
335     ?_assertError(badarg, resize(foo, bad_argument))
336    ].
337
338set_get_test_() ->
339    N0 = ?LEAFSIZE,
340    N1 = ?NODESIZE*N0,
341    [?_assert(array:get(0, new()) =:= undefined),
342     ?_assert(array:get(1, new()) =:= undefined),
343     ?_assert(array:get(99999, new()) =:= undefined),
344
345     ?_assert(array:get(0, new(1)) =:= undefined),
346     ?_assert(array:get(0, new(1,{default,0})) =:= 0),
347     ?_assert(array:get(9, new(10)) =:= undefined),
348
349     ?_assertError(badarg, array:get(0, new(fixed))),
350     ?_assertError(badarg, array:get(1, new(1))),
351     ?_assertError(badarg, array:get(-1, new(1))),
352     ?_assertError(badarg, array:get(10, new(10))),
353     ?_assertError(badarg, array:set(-1, foo, new(10))),
354     ?_assertError(badarg, array:set(10, foo, no_array)),
355
356     ?_assert(array:size(set(0, 17, new())) =:= 1),
357     ?_assert(array:size(set(N1-1, 17, new())) =:= N1),
358     ?_assert(array:size(set(0, 42, set(0, 17, new()))) =:= 1),
359     ?_assert(array:size(set(9, 42, set(0, 17, new()))) =:= 10),
360
361     ?_assert(array:get(0, set(0, 17, new())) =:= 17),
362     ?_assert(array:get(0, set(1, 17, new())) =:= undefined),
363     ?_assert(array:get(1, set(1, 17, new())) =:= 17),
364
365     ?_assert(array:get(0, fix(set(0, 17, new()))) =:= 17),
366     ?_assertError(badarg, array:get(1, fix(set(0, 17, new())))),
367
368     ?_assert(array:get(N1-2, set(N1-1, 17, new())) =:= undefined),
369     ?_assert(array:get(N1-1, set(N1-1, 17, new())) =:= 17),
370     ?_assertError(badarg, array:get(N1, fix(set(N1-1, 17, new())))),
371
372     ?_assert(array:get(0, set(0, 42, set(0, 17, new()))) =:= 42),
373
374     ?_assertError(badarg, array:get(0, reset(11, new([{size,10}])))),
375     ?_assertError(badarg, array:get(0, reset(-1, new([{size,10}])))),
376     ?_assert(array:get(0, reset(0,  new())) =:= undefined),
377     ?_assert(array:get(0, reset(0,  set(0,  17, new()))) =:= undefined),
378     ?_assert(array:get(0, reset(9,  set(9,  17, new()))) =:= undefined),
379     ?_assert(array:get(0, reset(11, set(11, 17, new()))) =:= undefined),
380     ?_assert(array:get(0, reset(11, set(12, 17, new()))) =:= undefined),
381     ?_assert(array:get(0, reset(1,  set(12, 17, new()))) =:= undefined),
382     ?_assert(array:get(0, reset(11, new())) =:= undefined),
383     ?_assert(array:get(0, reset(0,  set(0,  17, new({default,42})))) =:= 42),
384     ?_assert(array:get(0, reset(0,  new({default,42}))) =:= 42)
385    ].
386
387to_list_test_() ->
388    N0 = ?LEAFSIZE,
389    [?_assert([] =:= to_list(new())),
390     ?_assert([undefined] =:= to_list(new(1))),
391     ?_assert([undefined,undefined] =:= to_list(new(2))),
392     ?_assert(lists:duplicate(N0,0) =:= to_list(new(N0,{default,0}))),
393     ?_assert(lists:duplicate(N0+1,1) =:= to_list(new(N0+1,{default,1}))),
394     ?_assert(lists:duplicate(N0+2,2) =:= to_list(new(N0+2,{default,2}))),
395     ?_assert(lists:duplicate(666,6) =:= to_list(new(666,{default,6}))),
396     ?_assert([1,2,3] =:= to_list(set(2,3,set(1,2,set(0,1,new()))))),
397     ?_assert([3,2,1] =:= to_list(set(0,3,set(1,2,set(2,1,new()))))),
398     ?_assert([1|lists:duplicate(N0-2,0)++[1]] =:=
399	      to_list(set(N0-1,1,set(0,1,new({default,0}))))),
400     ?_assert([1|lists:duplicate(N0-1,0)++[1]] =:=
401	      to_list(set(N0,1,set(0,1,new({default,0}))))),
402     ?_assert([1|lists:duplicate(N0,0)++[1]] =:=
403	      to_list(set(N0+1,1,set(0,1,new({default,0}))))),
404     ?_assert([1|lists:duplicate(N0*3,0)++[1]] =:=
405	      to_list(set((N0*3)+1,1,set(0,1,new({default,0}))))),
406     ?_assertError(badarg, to_list(no_array))
407    ].
408
409sparse_to_list_test_() ->
410    N0 = ?LEAFSIZE,
411    [?_assert([] =:= sparse_to_list(new())),
412     ?_assert([] =:= sparse_to_list(new(1))),
413     ?_assert([] =:= sparse_to_list(new(1,{default,0}))),
414     ?_assert([] =:= sparse_to_list(new(2))),
415     ?_assert([] =:= sparse_to_list(new(2,{default,0}))),
416     ?_assert([] =:= sparse_to_list(new(N0,{default,0}))),
417     ?_assert([] =:= sparse_to_list(new(N0+1,{default,1}))),
418     ?_assert([] =:= sparse_to_list(new(N0+2,{default,2}))),
419     ?_assert([] =:= sparse_to_list(new(666,{default,6}))),
420     ?_assert([1,2,3] =:= sparse_to_list(set(2,3,set(1,2,set(0,1,new()))))),
421     ?_assert([3,2,1] =:= sparse_to_list(set(0,3,set(1,2,set(2,1,new()))))),
422     ?_assert([0,1] =:= sparse_to_list(set(N0-1,1,set(0,0,new())))),
423     ?_assert([0,1] =:= sparse_to_list(set(N0,1,set(0,0,new())))),
424     ?_assert([0,1] =:= sparse_to_list(set(N0+1,1,set(0,0,new())))),
425     ?_assert([0,1,2] =:= sparse_to_list(set(N0*10+1,2,set(N0*2+1,1,set(0,0,new()))))),
426     ?_assertError(badarg, sparse_to_list(no_array))
427    ].
428
429from_list_test_() ->
430    N0 = ?LEAFSIZE,
431    N1 = ?NODESIZE*N0,
432    N2 = ?NODESIZE*N1,
433    N3 = ?NODESIZE*N2,
434    N4 = ?NODESIZE*N3,
435    [?_assert(array:size(from_list([])) =:= 0),
436     ?_assert(array:is_fix(from_list([])) =:= false),
437     ?_assert(array:size(from_list([undefined])) =:= 1),
438     ?_assert(array:is_fix(from_list([undefined])) =:= false),
439     ?_assert(array:size(from_list(lists:seq(1,N1))) =:= N1),
440     ?_assert(to_list(from_list(lists:seq(1,N0))) =:= lists:seq(1,N0)),
441     ?_assert(to_list(from_list(lists:seq(1,N0+1))) =:= lists:seq(1,N0+1)),
442     ?_assert(to_list(from_list(lists:seq(1,N0+2))) =:= lists:seq(1,N0+2)),
443     ?_assert(to_list(from_list(lists:seq(1,N2))) =:= lists:seq(1,N2)),
444     ?_assert(to_list(from_list(lists:seq(1,N2+1))) =:= lists:seq(1,N2+1)),
445     ?_assert(to_list(from_list(lists:seq(0,N3))) =:= lists:seq(0,N3)),
446     ?_assert(to_list(from_list(lists:seq(0,N4))) =:= lists:seq(0,N4)),
447     ?_assertError(badarg, from_list([a,b,a,c|d])),
448     ?_assertError(badarg, from_list(no_array))
449    ].
450
451to_orddict_test_() ->
452    N0 = ?LEAFSIZE,
453    [?_assert([] =:= to_orddict(new())),
454     ?_assert([{0,undefined}] =:= to_orddict(new(1))),
455     ?_assert([{0,undefined},{1,undefined}] =:= to_orddict(new(2))),
456     ?_assert([{N,0}||N<-lists:seq(0,N0-1)]
457	      =:= to_orddict(new(N0,{default,0}))),
458     ?_assert([{N,1}||N<-lists:seq(0,N0)]
459	      =:= to_orddict(new(N0+1,{default,1}))),
460     ?_assert([{N,2}||N<-lists:seq(0,N0+1)]
461	      =:= to_orddict(new(N0+2,{default,2}))),
462     ?_assert([{N,6}||N<-lists:seq(0,665)]
463	      =:= to_orddict(new(666,{default,6}))),
464     ?_assert([{0,1},{1,2},{2,3}] =:=
465	      to_orddict(set(2,3,set(1,2,set(0,1,new()))))),
466     ?_assert([{0,3},{1,2},{2,1}] =:=
467	      to_orddict(set(0,3,set(1,2,set(2,1,new()))))),
468     ?_assert([{0,1}|[{N,0}||N<-lists:seq(1,N0-2)]++[{N0-1,1}]]
469	      =:= to_orddict(set(N0-1,1,set(0,1,new({default,0}))))),
470     ?_assert([{0,1}|[{N,0}||N<-lists:seq(1,N0-1)]++[{N0,1}]]
471	      =:= to_orddict(set(N0,1,set(0,1,new({default,0}))))),
472     ?_assert([{0,1}|[{N,0}||N<-lists:seq(1,N0)]++[{N0+1,1}]]
473	      =:= to_orddict(set(N0+1,1,set(0,1,new({default,0}))))),
474     ?_assert([{0,0} | [{N,undefined}||N<-lists:seq(1,N0*2)]] ++
475	      [{N0*2+1,1} | [{N,undefined}||N<-lists:seq(N0*2+2,N0*10)]] ++
476	      [{N0*10+1,2}] =:=
477	      to_orddict(set(N0*10+1,2,set(N0*2+1,1,set(0,0,new()))))),
478     ?_assertError(badarg, to_orddict(no_array))
479    ].
480
481sparse_to_orddict_test_() ->
482    N0 = ?LEAFSIZE,
483    [?_assert([] =:= sparse_to_orddict(new())),
484     ?_assert([] =:= sparse_to_orddict(new(1))),
485     ?_assert([] =:= sparse_to_orddict(new(1,{default,0}))),
486     ?_assert([] =:= sparse_to_orddict(new(2))),
487     ?_assert([] =:= sparse_to_orddict(new(2,{default,0}))),
488     ?_assert([] =:= sparse_to_orddict(new(N0,{default,0}))),
489     ?_assert([] =:= sparse_to_orddict(new(N0+1,{default,1}))),
490     ?_assert([] =:= sparse_to_orddict(new(N0+2,{default,2}))),
491     ?_assert([] =:= sparse_to_orddict(new(666,{default,6}))),
492     ?_assert([{0,1},{1,2},{2,3}] =:=
493	      sparse_to_orddict(set(2,3,set(1,2,set(0,1,new()))))),
494     ?_assert([{0,3},{1,2},{2,1}] =:=
495	      sparse_to_orddict(set(0,3,set(1,2,set(2,1,new()))))),
496     ?_assert([{0,1},{N0-1,1}] =:=
497	      sparse_to_orddict(set(N0-1,1,set(0,1,new({default,0}))))),
498     ?_assert([{0,1},{N0,1}] =:=
499	      sparse_to_orddict(set(N0,1,set(0,1,new({default,0}))))),
500     ?_assert([{0,1},{N0+1,1}] =:=
501	      sparse_to_orddict(set(N0+1,1,set(0,1,new({default,0}))))),
502     ?_assert([{0,0},{N0*2+1,1},{N0*10+1,2}] =:=
503	      sparse_to_orddict(set(N0*10+1,2,set(N0*2+1,1,set(0,0,new()))))),
504     ?_assertError(badarg, sparse_to_orddict(no_array))
505    ].
506
507from_orddict_test_() ->
508    N0 = ?LEAFSIZE,
509    N1 = ?NODESIZE*N0,
510    N2 = ?NODESIZE*N1,
511    N3 = ?NODESIZE*N2,
512    N4 = ?NODESIZE*N3,
513    [?_assert(array:size(from_orddict([])) =:= 0),
514     ?_assert(array:is_fix(from_orddict([])) =:= false),
515     ?_assert(array:size(from_orddict([{0,undefined}])) =:= 1),
516     ?_assert(array:is_fix(from_orddict([{0,undefined}])) =:= false),
517     ?_assert(array:size(from_orddict([{N0-1,undefined}])) =:= N0),
518     ?_assert(array:size(from_orddict([{N,0}||N<-lists:seq(0,N1-1)]))
519	      =:= N1),
520     ?_assertError({badarg,_}, from_orddict([foo])),
521     ?_assertError({badarg,_}, from_orddict([{200,foo},{1,bar}])),
522     ?_assertError({badarg,_}, from_orddict([{N,0}||N<-lists:seq(0,N0-1)] ++ not_a_list)),
523     ?_assertError(badarg, from_orddict(no_array)),
524
525
526     ?_assert(?LET(L, [{N,0}||N<-lists:seq(0,N0-1)],
527		   L =:= to_orddict(from_orddict(L)))),
528     ?_assert(?LET(L, [{N,0}||N<-lists:seq(0,N0)],
529		   L =:= to_orddict(from_orddict(L)))),
530     ?_assert(?LET(L, [{N,0}||N<-lists:seq(0,N2-1)],
531		   L =:= to_orddict(from_orddict(L)))),
532     ?_assert(?LET(L, [{N,0}||N<-lists:seq(0,N2)],
533		   L =:= to_orddict(from_orddict(L)))),
534     ?_assert(?LET(L, [{N,0}||N<-lists:seq(0,N3-1)],
535		   L =:= to_orddict(from_orddict(L)))),
536     ?_assert(?LET(L, [{N,0}||N<-lists:seq(0,N4-1)],
537		   L =:= to_orddict(from_orddict(L)))),
538
539     %% Hole in the begining
540     ?_assert(?LET(L, [{0,0}],
541		   L =:= sparse_to_orddict(from_orddict(L)))),
542     ?_assert(?LET(L, [{N0,0}],
543		   L =:= sparse_to_orddict(from_orddict(L)))),
544     ?_assert(?LET(L, [{N1,0}],
545		   L =:= sparse_to_orddict(from_orddict(L)))),
546     ?_assert(?LET(L, [{N3,0}],
547		   L =:= sparse_to_orddict(from_orddict(L)))),
548     ?_assert(?LET(L, [{N4,0}],
549		   L =:= sparse_to_orddict(from_orddict(L)))),
550     ?_assert(?LET(L, [{N0-1,0}],
551		   L =:= sparse_to_orddict(from_orddict(L)))),
552     ?_assert(?LET(L, [{N1-1,0}],
553		   L =:= sparse_to_orddict(from_orddict(L)))),
554     ?_assert(?LET(L, [{N3-1,0}],
555		   L =:= sparse_to_orddict(from_orddict(L)))),
556     ?_assert(?LET(L, [{N4-1,0}],
557		   L =:= sparse_to_orddict(from_orddict(L)))),
558
559     %% Hole in middle
560
561     ?_assert(?LET(L, [{0,0},{N0,0}],
562		   L =:= sparse_to_orddict(from_orddict(L)))),
563     ?_assert(?LET(L, [{0,0},{N1,0}],
564		   L =:= sparse_to_orddict(from_orddict(L)))),
565     ?_assert(?LET(L, [{0,0},{N3,0}],
566		   L =:= sparse_to_orddict(from_orddict(L)))),
567     ?_assert(?LET(L, [{0,0},{N4,0}],
568		   L =:= sparse_to_orddict(from_orddict(L)))),
569     ?_assert(?LET(L, [{0,0},{N0-1,0}],
570		   L =:= sparse_to_orddict(from_orddict(L)))),
571     ?_assert(?LET(L, [{0,0},{N1-1,0}],
572		   L =:= sparse_to_orddict(from_orddict(L)))),
573     ?_assert(?LET(L, [{0,0},{N3-1,0}],
574		   L =:= sparse_to_orddict(from_orddict(L)))),
575     ?_assert(?LET(L, [{0,0},{N4-1,0}],
576		   L =:= sparse_to_orddict(from_orddict(L))))
577
578    ].
579
580map_test_() ->
581    N0 = ?LEAFSIZE,
582    Id = fun (_,X) -> X end,
583    Plus = fun(N) -> fun (_,X) -> X+N end end,
584    Default = fun(_K,undefined) ->  no_value;
585		 (K,V) -> K+V
586	      end,
587    [?_assertError(badarg, map([], new())),
588     ?_assertError(badarg, map([], new(10))),
589     ?_assert(to_list(map(Id, new())) =:= []),
590     ?_assert(to_list(map(Id, new(1))) =:= [undefined]),
591     ?_assert(to_list(map(Id, new(5,{default,0}))) =:= [0,0,0,0,0]),
592     ?_assert(to_list(map(Id, from_list([1,2,3,4]))) =:= [1,2,3,4]),
593     ?_assert(to_list(map(Plus(1), from_list([0,1,2,3]))) =:= [1,2,3,4]),
594     ?_assert(to_list(map(Plus(-1), from_list(lists:seq(1,11))))
595	      =:= lists:seq(0,10)),
596     ?_assert(to_list(map(Plus(11), from_list(lists:seq(0,99999))))
597	      =:= lists:seq(11,100010)),
598     ?_assert([{0,0},{N0*2+1,N0*2+1+1},{N0*100+1,N0*100+1+2}] =:=
599	      sparse_to_orddict((map(Default,
600				     set(N0*100+1,2,
601					 set(N0*2+1,1,
602					     set(0,0,new())))))#array{default = no_value}))
603    ].
604
605sparse_map_test_() ->
606    N0 = ?LEAFSIZE,
607    Id = fun (_,X) -> X end,
608    Plus = fun(N) -> fun (_,X) -> X+N end end,
609    KeyPlus = fun (K,X) -> K+X end,
610    [?_assertError(badarg, sparse_map([], new())),
611     ?_assertError(badarg, sparse_map([], new(10))),
612     ?_assert(to_list(sparse_map(Id, new())) =:= []),
613     ?_assert(to_list(sparse_map(Id, new(1))) =:= [undefined]),
614     ?_assert(to_list(sparse_map(Id, new(5,{default,0}))) =:= [0,0,0,0,0]),
615     ?_assert(to_list(sparse_map(Id, from_list([1,2,3,4]))) =:= [1,2,3,4]),
616     ?_assert(to_list(sparse_map(Plus(1), from_list([0,1,2,3])))
617	      =:= [1,2,3,4]),
618     ?_assert(to_list(sparse_map(Plus(-1), from_list(lists:seq(1,11))))
619	      =:= lists:seq(0,10)),
620     ?_assert(to_list(sparse_map(Plus(11), from_list(lists:seq(0,99999))))
621	      =:= lists:seq(11,100010)),
622     ?_assert(to_list(sparse_map(Plus(1), set(1,1,new({default,0}))))
623	      =:= [0,2]),
624     ?_assert(to_list(sparse_map(Plus(1),
625				 set(3,4,set(0,1,new({default,0})))))
626	      =:= [2,0,0,5]),
627     ?_assert(to_list(sparse_map(Plus(1),
628				 set(9,9,set(1,1,new({default,0})))))
629	      =:= [0,2,0,0,0,0,0,0,0,10]),
630     ?_assert([{0,0},{N0*2+1,N0*2+1+1},{N0*100+1,N0*100+1+2}] =:=
631	      sparse_to_orddict(sparse_map(KeyPlus,
632					   set(N0*100+1,2,
633					       set(N0*2+1,1,
634						   set(0,0,new()))))))
635
636    ].
637
638foldl_test_() ->
639    N0 = ?LEAFSIZE,
640    Count = fun (_,_,N) -> N+1 end,
641    Sum = fun (_,X,N) -> N+X end,
642    Reverse = fun (_,X,L) -> [X|L] end,
643    Vals = fun(_K,undefined,{C,L}) -> {C+1,L};
644	      (K,X,{C,L}) -> {C,[K+X|L]}
645	   end,
646    [?_assertError(badarg, foldl([], 0, new())),
647     ?_assertError(badarg, foldl([], 0, new(10))),
648     ?_assert(foldl(Count, 0, new()) =:= 0),
649     ?_assert(foldl(Count, 0, new(1)) =:= 1),
650     ?_assert(foldl(Count, 0, new(10)) =:= 10),
651     ?_assert(foldl(Count, 0, from_list([1,2,3,4])) =:= 4),
652     ?_assert(foldl(Count, 10, from_list([0,1,2,3,4,5,6,7,8,9])) =:= 20),
653     ?_assert(foldl(Count, 1000, from_list(lists:seq(0,999))) =:= 2000),
654     ?_assert(foldl(Sum, 0, from_list(lists:seq(0,10))) =:= 55),
655     ?_assert(foldl(Reverse, [], from_list(lists:seq(0,1000)))
656	      =:= lists:reverse(lists:seq(0,1000))),
657     ?_assert({999,[N0*100+1+2,N0*2+1+1,0]} =:=
658	      foldl(Vals, {0,[]},
659		    set(N0*100+1,2,
660			set(N0*2+1,1,
661			    set(0,0,new())))))
662
663    ].
664
665sparse_foldl_test_() ->
666    N0 = ?LEAFSIZE,
667    Count = fun (_,_,N) -> N+1 end,
668    Sum = fun (_,X,N) -> N+X end,
669    Reverse = fun (_,X,L) -> [X|L] end,
670    Vals = fun(_K,undefined,{C,L}) -> {C+1,L};
671	      (K,X,{C,L}) -> {C,[K+X|L]}
672	   end,
673    [?_assertError(badarg, sparse_foldl([], 0, new())),
674     ?_assertError(badarg, sparse_foldl([], 0, new(10))),
675     ?_assert(sparse_foldl(Count, 0, new()) =:= 0),
676     ?_assert(sparse_foldl(Count, 0, new(1)) =:= 0),
677     ?_assert(sparse_foldl(Count, 0, new(10,{default,1})) =:= 0),
678     ?_assert(sparse_foldl(Count, 0, from_list([0,1,2,3,4],0)) =:= 4),
679     ?_assert(sparse_foldl(Count, 0, from_list([0,1,2,3,4,5,6,7,8,9,0],0))
680	      =:= 9),
681     ?_assert(sparse_foldl(Count, 0, from_list(lists:seq(0,999),0))
682	      =:= 999),
683     ?_assert(sparse_foldl(Sum, 0, from_list(lists:seq(0,10), 5)) =:= 50),
684     ?_assert(sparse_foldl(Reverse, [], from_list(lists:seq(0,1000), 0))
685	      =:= lists:reverse(lists:seq(1,1000))),
686     ?_assert({0,[N0*100+1+2,N0*2+1+1,0]} =:=
687	      sparse_foldl(Vals, {0,[]},
688			   set(N0*100+1,2,
689			       set(N0*2+1,1,
690				   set(0,0,new())))))
691    ].
692
693foldr_test_() ->
694    N0 = ?LEAFSIZE,
695    Count = fun (_,_,N) -> N+1 end,
696    Sum = fun (_,X,N) -> N+X end,
697    List = fun (_,X,L) -> [X|L] end,
698    Vals = fun(_K,undefined,{C,L}) -> {C+1,L};
699	      (K,X,{C,L}) -> {C,[K+X|L]}
700	   end,
701    [?_assertError(badarg, foldr([], 0, new())),
702     ?_assertError(badarg, foldr([], 0, new(10))),
703     ?_assert(foldr(Count, 0, new()) =:= 0),
704     ?_assert(foldr(Count, 0, new(1)) =:= 1),
705     ?_assert(foldr(Count, 0, new(10)) =:= 10),
706     ?_assert(foldr(Count, 0, from_list([1,2,3,4])) =:= 4),
707     ?_assert(foldr(Count, 10, from_list([0,1,2,3,4,5,6,7,8,9])) =:= 20),
708     ?_assert(foldr(Count, 1000, from_list(lists:seq(0,999))) =:= 2000),
709     ?_assert(foldr(Sum, 0, from_list(lists:seq(0,10))) =:= 55),
710     ?_assert(foldr(List, [], from_list(lists:seq(0,1000)))
711 	      =:= lists:seq(0,1000)),
712     ?_assert({999,[0,N0*2+1+1,N0*100+1+2]} =:=
713	      foldr(Vals, {0,[]},
714		    set(N0*100+1,2,
715			set(N0*2+1,1,
716			    set(0,0,new())))))
717
718    ].
719
720sparse_foldr_test_() ->
721    N0 = ?LEAFSIZE,
722    Count = fun (_,_,N) -> N+1 end,
723    Sum = fun (_,X,N) -> N+X end,
724    List = fun (_,X,L) -> [X|L] end,
725    Vals = fun(_K,undefined,{C,L}) -> {C+1,L};
726	      (K,X,{C,L}) -> {C,[K+X|L]}
727	   end,
728    [?_assertError(badarg, sparse_foldr([], 0, new())),
729     ?_assertError(badarg, sparse_foldr([], 0, new(10))),
730     ?_assert(sparse_foldr(Count, 0, new()) =:= 0),
731     ?_assert(sparse_foldr(Count, 0, new(1)) =:= 0),
732     ?_assert(sparse_foldr(Count, 0, new(10,{default,1})) =:= 0),
733     ?_assert(sparse_foldr(Count, 0, from_list([0,1,2,3,4],0)) =:= 4),
734     ?_assert(sparse_foldr(Count, 0, from_list([0,1,2,3,4,5,6,7,8,9,0],0))
735	      =:= 9),
736     ?_assert(sparse_foldr(Count, 0, from_list(lists:seq(0,999),0))
737	      =:= 999),
738     ?_assert(sparse_foldr(Sum, 0, from_list(lists:seq(0,10),5)) =:= 50),
739     ?_assert(sparse_foldr(List, [], from_list(lists:seq(0,1000),0))
740 	      =:= lists:seq(1,1000)),
741
742     ?_assert(sparse_size(new()) =:= 0),
743     ?_assert(sparse_size(new(8)) =:= 0),
744     ?_assert(sparse_size(array:set(7, 0, new())) =:= 8),
745     ?_assert(sparse_size(array:set(7, 0, new(10))) =:= 8),
746     ?_assert(sparse_size(array:set(99, 0, new(10,{fixed,false})))
747	      =:= 100),
748     ?_assert(sparse_size(array:set(7, undefined, new())) =:= 0),
749     ?_assert(sparse_size(array:from_list([1,2,3,undefined])) =:= 3),
750     ?_assert(sparse_size(array:from_orddict([{3,0},{17,0},{99,undefined}]))
751			  =:= 18),
752     ?_assert({0,[0,N0*2+1+1,N0*100+1+2]} =:=
753	      sparse_foldr(Vals, {0,[]},
754			   set(N0*100+1,2,
755			       set(N0*2+1,1,
756				   set(0,0,new())))))
757    ].
758
759new_test(Config) when is_list(Config) -> new_test_(), ok.
760fix_test(Config) when is_list(Config) -> fix_test_(), ok.
761relax_test(Config) when is_list(Config) -> relax_test_(), ok.
762resize_test(Config) when is_list(Config) -> resize_test_(), ok.
763set_get_test(Config) when is_list(Config) -> set_get_test_(), ok.
764to_list_test(Config) when is_list(Config) -> to_list_test_(), ok.
765sparse_to_list_test(Config) when is_list(Config) -> sparse_to_list_test_(), ok.
766from_list_test(Config) when is_list(Config) -> from_list_test_(), ok.
767to_orddict_test(Config) when is_list(Config) -> to_orddict_test_(), ok.
768sparse_to_orddict_test(Config) when is_list(Config) -> sparse_to_orddict_test_(), ok.
769from_orddict_test(Config) when is_list(Config) -> from_orddict_test_(), ok.
770map_test(Config) when is_list(Config) -> map_test_(), ok.
771sparse_map_test(Config) when is_list(Config) -> sparse_map_test_(), ok.
772foldl_test(Config) when is_list(Config) -> foldl_test_(), ok.
773sparse_foldl_test(Config) when is_list(Config) -> sparse_foldl_test_(), ok.
774foldr_test(Config) when is_list(Config) -> foldr_test_(), ok.
775sparse_foldr_test(Config) when is_list(Config) -> sparse_foldr_test_(), ok.
776