aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugger/test/record_SUITE.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2010-08-12 16:20:20 +0200
committerBjörn Gustavsson <[email protected]>2010-09-03 10:33:31 +0200
commitc3b086d38bd152af39381bfae96c1e9ce7e7be9b (patch)
treea804d1fcb3270ba8057243076cfaeca3b6f01ae0 /lib/debugger/test/record_SUITE.erl
parent9f72e25a2837bc6073482d7b79b80bdeb56984d5 (diff)
downloadotp-c3b086d38bd152af39381bfae96c1e9ce7e7be9b.tar.gz
otp-c3b086d38bd152af39381bfae96c1e9ce7e7be9b.tar.bz2
otp-c3b086d38bd152af39381bfae96c1e9ce7e7be9b.zip
Add test suite for debugger
Diffstat (limited to 'lib/debugger/test/record_SUITE.erl')
-rw-r--r--lib/debugger/test/record_SUITE.erl252
1 files changed, 252 insertions, 0 deletions
diff --git a/lib/debugger/test/record_SUITE.erl b/lib/debugger/test/record_SUITE.erl
new file mode 100644
index 0000000000..06fd01555e
--- /dev/null
+++ b/lib/debugger/test/record_SUITE.erl
@@ -0,0 +1,252 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%% Purpose : Test records.
+
+-module(record_SUITE).
+
+-include("test_server.hrl").
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+ errors/1,record_test/1,eval_once/1]).
+
+all(suite) ->
+ [{conf,init_all,cases(),finish_all}].
+
+cases() ->
+ [errors,record_test,eval_once].
+
+init_per_testcase(_Case, Config) ->
+ test_lib:interpret(?MODULE),
+ Dog = test_server:timetrap(?t:minutes(1)),
+ [{watchdog,Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+init_all(Config) when is_list(Config) ->
+ ?line test_lib:interpret(?MODULE),
+ ?line true = lists:member(?MODULE, int:interpreted()),
+ ok.
+
+finish_all(Config) when is_list(Config) ->
+ ok.
+
+-record(foo, {a,b,c,d}).
+-record(bar, {a,b,c,d}).
+-record(barf, {a,b,c,d,e}).
+
+errors(Config) when is_list(Config) ->
+ Foo = #foo{a=1,b=2,c=3,d=4},
+ ?line #foo{a=19,b=42,c=3,d=4} = update_foo(Foo, 19, 42),
+
+ ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19)),
+ ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19, 35)),
+ ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19, 35, 17)),
+ ?line {'EXIT',{{badrecord,bar},_}} = (catch update_foo_bar(Foo, 19, 35, 17, 42)),
+
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19)),
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, 35)),
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, 35, 17)),
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19, 35, 17, 42)),
+ ?line {'EXIT',{{badrecord,barf},_}} = (catch update_foo_barf(Foo, 19,
+ 35, 17, 42, -2)),
+
+ ok.
+
+update_foo(#foo{}=R, A, B) ->
+ R#foo{a=A,b=B}.
+
+update_foo_bar(#foo{}=R, A) ->
+ R#bar{a=A}.
+
+update_foo_bar(#foo{}=R, A, _B) ->
+ R#bar{a=A,b=A}.
+
+update_foo_bar(#foo{}=R, A, _B, C) ->
+ R#bar{a=A,b=A,c=C}.
+
+update_foo_bar(#foo{}=R, A, _B, C, D) ->
+ R#bar{a=A,b=A,c=C,d=D}.
+
+update_foo_barf(#foo{}=R, A) ->
+ R#barf{a=A}.
+
+update_foo_barf(#foo{}=R, A, _B) ->
+ R#barf{a=A,b=A}.
+
+update_foo_barf(#foo{}=R, A, _B, C) ->
+ R#barf{a=A,b=A,c=C}.
+
+update_foo_barf(#foo{}=R, A, _B, C, D) ->
+ R#barf{a=A,b=A,c=C,d=D}.
+
+update_foo_barf(#foo{}=R, A, _B, C, D, E) ->
+ R#barf{a=A,b=A,c=C,d=D,e=E}.
+
+
+-define(TrueGuard(Expr), if Expr -> ok; true -> ?t:fail() end).
+-define(FalseGuard(Expr), if Expr -> ?t:fail(); true -> ok end).
+
+record_test(Config) when is_list(Config) ->
+ ?line true = is_record(#foo{}, foo),
+ ?line false = is_record(#foo{}, barf),
+ ?line false = is_record({foo}, foo),
+
+ ?line true = erlang:is_record(#foo{}, foo),
+ ?line false = erlang:is_record(#foo{}, barf),
+ ?line false = erlang:is_record({foo}, foo),
+
+ ?line false = is_record([], foo),
+ ?line false = is_record(Config, foo),
+
+ ?line ?TrueGuard(is_record(#foo{}, foo)),
+ ?line ?FalseGuard(is_record(#foo{}, barf)),
+ ?line ?FalseGuard(is_record({foo}, foo)),
+
+ ?line ?TrueGuard(erlang:is_record(#foo{}, foo)),
+ ?line ?FalseGuard(erlang:is_record(#foo{}, barf)),
+ ?line ?FalseGuard(erlang:is_record({foo}, foo)),
+
+ ?line ?FalseGuard(is_record([], foo)),
+ ?line ?FalseGuard(is_record(Config, foo)),
+
+ %% 'not is_record/2' to test guard optimization.
+
+ ?line ?FalseGuard(not is_record(#foo{}, foo)),
+ ?line ?TrueGuard(not is_record(#foo{}, barf)),
+ ?line ?TrueGuard(not is_record({foo}, foo)),
+
+ ?line ?FalseGuard(not erlang:is_record(#foo{}, foo)),
+ ?line ?TrueGuard(not erlang:is_record(#foo{}, barf)),
+ ?line ?TrueGuard(not erlang:is_record({foo}, foo)),
+
+ Foo = id(#foo{}),
+ ?line ?FalseGuard(not erlang:is_record(Foo, foo)),
+ ?line ?TrueGuard(not erlang:is_record(Foo, barf)),
+
+ ?line ?TrueGuard(not is_record(Config, foo)),
+
+ ?line ?TrueGuard(not is_record(a, foo)),
+ ?line ?TrueGuard(not is_record([], foo)),
+
+ %% Pass non-literal first argument.
+
+ ?line true = is_record(id(#foo{}), foo),
+ ?line false = is_record(id(#foo{}), barf),
+ ?line false = is_record(id({foo}), foo),
+
+ ?line true = erlang:is_record(id(#foo{}), foo),
+ ?line false = erlang:is_record(id(#foo{}), barf),
+ ?line false = erlang:is_record(id({foo}), foo),
+
+ NoRec1 = id(blurf),
+ NoRec2 = id([]),
+
+ ?line ?TrueGuard(not is_record(NoRec1, foo)),
+ ?line ?TrueGuard(not is_record(NoRec2, foo)),
+
+ %% Force the use of guard bifs by using the 'xor' operation.
+
+ False = id(false),
+ ?line ?TrueGuard(is_record(#foo{}, foo) xor False),
+ ?line ?FalseGuard(is_record(#foo{}, barf) xor False),
+ ?line ?FalseGuard(is_record({foo}, foo) xor False ),
+
+ ?line ?TrueGuard(is_record(Foo, foo) xor False),
+ ?line ?FalseGuard(is_record(Foo, barf) xor False),
+
+
+ %% Implicit guards by using a list comprehension.
+
+ List = id([1,#foo{a=2},3,#bar{d=4},5,#foo{a=6},7]),
+
+ ?line [#foo{a=2},#foo{a=6}] = [X || X <- List, is_record(X, foo)],
+ ?line [#bar{d=4}] = [X || X <- List, is_record(X, bar)],
+ ?line [1,#foo{a=2},3,5,#foo{a=6},7] =
+ [X || X <- List, not is_record(X, bar)],
+ ?line [1,3,5,7] =
+ [X || X <- List, ((not is_record(X, bar)) and (not is_record(X, foo)))],
+ ?line [#foo{a=2},#bar{d=4},#foo{a=6}] =
+ [X || X <- List, ((is_record(X, bar)) or (is_record(X, foo)))],
+ ?line [1,3,#bar{d=4}] =
+ [X || X <- List, ((is_record(X, bar)) or (X < 5))],
+
+ ?line MyList = [#foo{a=3},x,[],{a,b}],
+ ?line [#foo{a=3}] = [X || X <- MyList, is_record(X, foo)],
+ ?line [x,[],{a,b}] = [X || X <- MyList, not is_record(X, foo)],
+ ?line [#foo{a=3}] = [X || X <- MyList, begin is_record(X, foo) end],
+ ?line [x,[],{a,b}] = [X || X <- MyList, begin not is_record(X, foo) end],
+ ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList, is_record(X, foo) or
+ not is_binary(X)],
+ ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList, not is_record(X, foo) or
+ not is_binary(X)],
+ ?line [#foo{a=3}] = [X || X <- MyList, is_record(X, foo) or is_reference(X)],
+ ?line [x,[],{a,b}] = [X || X <- MyList, not is_record(X, foo) or
+ is_reference(X)],
+ ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList,
+ begin is_record(X, foo) or
+ not is_binary(X) end],
+ ?line [#foo{a=3},x,[],{a,b}] = [X || X <- MyList,
+ begin not is_record(X, foo) or
+ not is_binary(X) end],
+ ?line [#foo{a=3}] = [X || X <- MyList,
+ begin is_record(X, foo) or is_reference(X) end],
+ ?line [x,[],{a,b}] = [X || X <- MyList,
+ begin not is_record(X, foo) or
+ is_reference(X) end],
+ ok.
+
+eval_once(Config) when is_list(Config) ->
+ ?line once(fun(GetRec) ->
+ true = erlang:is_record(GetRec(), foo)
+ end, #foo{}),
+ ?line once(fun(GetRec) ->
+ (GetRec())#foo{a=1}
+ end, #foo{}),
+ ?line once(fun(GetRec) ->
+ (GetRec())#foo{a=1,b=2}
+ end, #foo{}),
+ ?line once(fun(GetRec) ->
+ (GetRec())#foo{a=1,b=2,c=3}
+ end, #foo{}),
+ ?line once(fun(GetRec) ->
+ (GetRec())#foo{a=1,b=2,c=3,d=4}
+ end, #foo{}),
+ ok.
+
+once(Test, Record) ->
+ put(?MODULE, 0),
+ GetRec = fun() ->
+ put(?MODULE, 1+get(?MODULE)),
+ Record
+ end,
+ Result = Test(GetRec),
+ case get(?MODULE) of
+ 1 -> ok;
+ N ->
+ io:format("Evaluated ~w times\n", [N]),
+ ?t:fail()
+ end,
+ Result.
+
+id(I) -> I.