diff options
Diffstat (limited to 'lib/stdlib/test/qlc_SUITE.erl')
-rw-r--r-- | lib/stdlib/test/qlc_SUITE.erl | 899 |
1 files changed, 440 insertions, 459 deletions
diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl index a9ea78a58b..2bd940020c 100644 --- a/lib/stdlib/test/qlc_SUITE.erl +++ b/lib/stdlib/test/qlc_SUITE.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2016. 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/. +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at %% -%% 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. +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% %% %CopyrightEnd% %% @@ -24,7 +25,7 @@ -define(QLC, qlc). -define(QLCs, "qlc"). -%-define(debug, true). +%%-define(debug, true). %% There are often many tests per testcase. Most tests are copied to a %% module, a file. The file is compiled and the test run. Should the @@ -42,10 +43,10 @@ -define(testcase, current_testcase). % don't know -define(t, test_server). -else. --include_lib("test_server/include/test_server.hrl"). --define(datadir, ?config(data_dir, Config)). --define(privdir, ?config(priv_dir, Config)). --define(testcase, ?config(?TESTCASE, Config)). +-include_lib("common_test/include/ct.hrl"). +-define(datadir, proplists:get_value(data_dir, Config)). +-define(privdir, proplists:get_value(priv_dir, Config)). +-define(testcase, proplists:get_value(?TESTCASE, Config)). -endif. -include_lib("stdlib/include/ms_transform.hrl"). @@ -72,11 +73,14 @@ otp_5644/1, otp_5195/1, otp_6038_bug/1, otp_6359/1, otp_6562/1, otp_6590/1, otp_6673/1, otp_6964/1, otp_7114/1, otp_7238/1, - otp_7232/1, otp_7552/1, otp_6674/1, otp_7714/1, + otp_7232/1, otp_7552/1, otp_6674/1, otp_7714/1, otp_11758/1, + otp_12946/1, manpage/1, - backward/1, forward/1]). + backward/1, forward/1, + + eep37/1]). %% Internal exports. -export([bad_table_throw/1, bad_table_exit/1, default_table/1, bad_table/1, @@ -103,19 +107,15 @@ handle_event/2, handle_call/2, handle_info/2, terminate/2]). -% Default timetrap timeout (set in init_per_testcase). --define(default_timeout, ?t:minutes(5)). - init_per_testcase(Case, Config) -> - ?line Dog = ?t:timetrap(?default_timeout), - [{?TESTCASE, Case}, {watchdog, Dog} | Config]. + [{?TESTCASE, Case} | Config]. end_per_testcase(_Case, _Config) -> - Dog = ?config(watchdog, _Config), - test_server:timetrap_cancel(Dog), ok. -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap,{minutes,5}}]. all() -> [{group, parse_transform}, {group, evaluation}, @@ -132,7 +132,7 @@ groups() -> evaluator, string_to_handle, table, process_dies, sort, keysort, filesort, cache, cache_list, filter, info, nested_info, lookup1, lookup2, lookup_rec, indices, - pre_fun, skip_filters]}, + pre_fun, skip_filters, eep37]}, {table_impls, [], [ets, dets]}, {join, [], [join_option, join_filter, join_lookup, join_merge, @@ -140,7 +140,7 @@ groups() -> {tickets, [], [otp_5644, otp_5195, otp_6038_bug, otp_6359, otp_6562, otp_6590, otp_6673, otp_6964, otp_7114, otp_7232, - otp_7238, otp_7552, otp_6674, otp_7714]}, + otp_7238, otp_7552, otp_6674, otp_7714, otp_11758, otp_12946]}, {compat, [], [backward, forward]}]. init_per_suite(Config) -> @@ -155,35 +155,30 @@ init_per_group(_GroupName, Config) -> end_per_group(_GroupName, Config) -> Config. -badarg(doc) -> - "Badarg."; -badarg(suite) -> []; badarg(Config) when is_list(Config) -> Ts = - [{badarg, - <<"-import(qlc, [q/1, q/2]). + [{badarg, + <<"-import(qlc, [q/1, q/2]). q(_, _, _) -> ok. - badarg() -> - qlc:q(foo), - qlc:q(foo, cache_all), - qlc:q(foo, cache_all, extra), - q(bar), - q(bar, cache_all), - q(bar, cache_all, extra). - ">>, +badarg() -> + qlc:q(foo), + qlc:q(foo, cache_all), + qlc:q(foo, cache_all, extra), + q(bar), + q(bar, cache_all), + q(bar, cache_all, extra). +">>, [], - {errors,[{5,?QLC,not_a_query_list_comprehension}, - {6,?QLC,not_a_query_list_comprehension}, - {8,?QLC,not_a_query_list_comprehension}, - {9,?QLC,not_a_query_list_comprehension}], - []}}], - ?line [] = compile(Config, Ts), +{errors,[{5,?QLC,not_a_query_list_comprehension}, + {6,?QLC,not_a_query_list_comprehension}, + {8,?QLC,not_a_query_list_comprehension}, + {9,?QLC,not_a_query_list_comprehension}], + []}}], + [] = compile(Config, Ts), ok. -nested_qlc(doc) -> - "Nested qlc expressions."; -nested_qlc(suite) -> []; +%% Nested qlc expressions. nested_qlc(Config) when is_list(Config) -> %% Nested QLC expressions. X is bound before the first one; Z and X %% before the second one. @@ -223,12 +218,10 @@ nested_qlc(Config) when is_list(Config) -> [warn_unused_vars], {warnings,[{{6,39},erl_lint,{shadowed_var,'X',generate}}]}} ], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -unused_var(doc) -> - "Unused variable with a name that should not be introduced."; -unused_var(suite) -> []; +%% Unused variable with a name that should not be introduced. unused_var(Config) when is_list(Config) -> Ts = [{unused_var, @@ -240,12 +233,10 @@ unused_var(Config) when is_list(Config) -> ">>, [warn_unused_vars], {warnings,[{{2,33},erl_lint,{unused_var,'Y1'}}]}}], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -lc(doc) -> - "Ordinary LC expression."; -lc(suite) -> []; +%% Ordinary LC expression. lc(Config) when is_list(Config) -> Ts = [{lc, @@ -254,12 +245,10 @@ lc(Config) when is_list(Config) -> ">>, [], {warnings,[{{2,30},erl_lint,{shadowed_var,'X',generate}}]}}], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -fun_clauses(doc) -> - "Fun with several clauses."; -fun_clauses(suite) -> []; +%% Fun with several clauses. fun_clauses(Config) when is_list(Config) -> Ts = [{fun_clauses, @@ -275,12 +264,10 @@ fun_clauses(Config) when is_list(Config) -> {{3,41},erl_lint,{shadowed_var,'X',generate}}, {{4,22},erl_lint,{shadowed_var,'X','fun'}}, {{4,41},erl_lint,{shadowed_var,'X',generate}}]}}], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -filter_var(doc) -> - "Variable introduced in filter."; -filter_var(suite) -> []; +%% Variable introduced in filter. filter_var(Config) when is_list(Config) -> Ts = [{filter_var, @@ -305,13 +292,11 @@ filter_var(Config) when is_list(Config) -> ">>, [], {errors,[{{2,25},erl_lint,{unsafe_var,'V',{'case',{3,19}}}}],[]}}], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -single(doc) -> - "Unused pattern variable."; -single(suite) -> []; +%% Unused pattern variable. single(Config) when is_list(Config) -> Ts = [{single, @@ -321,12 +306,10 @@ single(Config) when is_list(Config) -> ">>, [warn_unused_vars], {warnings,[{{2,30},erl_lint,{unused_var,'Y'}}]}}], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -exported_var(doc) -> - "Exported variable in list expression (rhs of generator)."; -exported_var(suite) -> []; +%% Exported variable in list expression (rhs of generator). exported_var(Config) when is_list(Config) -> Ts = [{exported_var, @@ -343,12 +326,10 @@ exported_var(Config) when is_list(Config) -> [warn_export_vars], {warnings,[{{7,37},erl_lint,{exported_var,'Z',{'case',{3,36}}}}, {{7,44},erl_lint,{exported_var,'Z',{'case',{3,36}}}}]}}], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -generator_vars(doc) -> - "Errors for generator variable used in list expression."; -generator_vars(suite) -> []; +%% Errors for generator variable used in list expression. generator_vars(Config) when is_list(Config) -> Ts = [{generator_vars, @@ -370,12 +351,10 @@ generator_vars(Config) when is_list(Config) -> {{9,33},?QLC,{used_generator_variable,'Z'}}, {{9,40},?QLC,{used_generator_variable,'Z'}}], []}}], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -nomatch(doc) -> - "Unreachable clauses also found when compiling."; -nomatch(suite) -> []; +%% Unreachable clauses also found when compiling. nomatch(Config) when is_list(Config) -> Ts = [{unreachable1, @@ -394,7 +373,8 @@ nomatch(Config) when is_list(Config) -> qlc:q([3 || {3=4} <- []]). ">>, [], - {warnings,[{{2,27},qlc,nomatch_pattern}]}}, + %% {warnings,[{{2,27},qlc,nomatch_pattern}]}}, + {warnings,[{2,v3_core,nomatch}]}}, {nomatch2, <<"nomatch() -> @@ -405,7 +385,8 @@ nomatch(Config) when is_list(Config) -> end, [{1},{2}]). ">>, [], - {warnings,[{{3,33},qlc,nomatch_pattern}]}}, + %% {warnings,[{{3,33},qlc,nomatch_pattern}]}}, + {warnings,[{3,v3_core,nomatch}]}}, {nomatch3, <<"nomatch() -> @@ -417,7 +398,8 @@ nomatch(Config) when is_list(Config) -> end, [{1,2},{2,3}]). ">>, [], - {warnings,[{{3,52},qlc,nomatch_pattern}]}}, + %% {warnings,[{{3,52},qlc,nomatch_pattern}]}}, + {warnings,[{3,v3_core,nomatch}]}}, {nomatch4, <<"nomatch() -> @@ -444,13 +426,11 @@ nomatch(Config) when is_list(Config) -> {warnings,[{3,v3_core,nomatch}]}} ], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -errors(doc) -> - "Errors within qlc expressions also found when compiling."; -errors(suite) -> []; +%% Errors within qlc expressions also found when compiling. errors(Config) when is_list(Config) -> Ts = [{errors1, @@ -459,12 +439,10 @@ errors(Config) when is_list(Config) -> ">>, [], {errors,[{{2,33},erl_lint,{unbound_var,'A'}}],[]}}], - ?line [] = compile(Config, Ts), + [] = compile(Config, Ts), ok. -pattern(doc) -> - "Patterns."; -pattern(suite) -> []; +%% Patterns. pattern(Config) when is_list(Config) -> Ts = [ <<"%% Records in patterns. No lookup. @@ -486,14 +464,12 @@ pattern(Config) when is_list(Config) -> end, [{<<\"hej\">>}])">> ], - ?line run(Config, <<"-record(a, {k,v}). + run(Config, <<"-record(a, {k,v}). -record(k, {t,v}).\n">>, Ts), ok. -eval(doc) -> - "eval/2"; -eval(suite) -> []; +%% eval/2 eval(Config) when is_list(Config) -> ScratchDir = filename:join([?privdir, "scratch","."]), @@ -609,12 +585,10 @@ eval(Config) when is_list(Config) -> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -cursor(doc) -> - "cursor/2"; -cursor(suite) -> []; +%% cursor/2 cursor(Config) when is_list(Config) -> ScratchDir = filename:join([?privdir, "scratch","."]), Ts = [<<"{'EXIT',{badarg,_}} = @@ -723,12 +697,10 @@ cursor(Config) when is_list(Config) -> ok = qlc:delete_cursor(C2)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -fold(doc) -> - "fold/4"; -fold(suite) -> []; +%% fold/4 fold(Config) when is_list(Config) -> ScratchDir = filename:join([?privdir, "scratch","."]), Ts = [<<"Q = qlc:q([X || X <- [1,2,1,2,1]]), @@ -818,12 +790,10 @@ fold(Config) when is_list(Config) -> (catch qlc:fold(F, [], Q, [{unique_all,false}])) ">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -eval_unique(doc) -> - "Test the unique_all option of eval."; -eval_unique(suite) -> []; +%% Test the unique_all option of eval. eval_unique(Config) when is_list(Config) -> Ts = [<<"QLC1 = qlc:q([X || X <- qlc:append([[1,1,2], [1,2,3,2,3]])]), [1,2,3] = qlc:eval(QLC1, {unique_all,true}), @@ -915,12 +885,10 @@ eval_unique(Config) when is_list(Config) -> {sort,{sort,{list,_},[{unique,true}]},[]} = i(Q)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -eval_cache(doc) -> - "Test the cache_all and unique_all options of eval."; -eval_cache(suite) -> []; +%% Test the cache_all and unique_all options of eval. eval_cache(Config) when is_list(Config) -> Ts = [ <<"E = ets:new(apa, [ordered_set]), @@ -1049,12 +1017,10 @@ eval_cache(Config) when is_list(Config) -> [1] = qlc:e(H, unique_all)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -append(doc) -> - "Test the append function."; -append(suite) -> []; +%% Test the append function. append(Config) when is_list(Config) -> Ts = [<<"C = qlc:cursor(qlc:q([X || X <- [0,1,2,3], begin 10/X > 0.0 end])), R = (catch qlc:next_answers(C)), @@ -1114,12 +1080,12 @@ append(Config) when is_list(Config) -> foo() -> bar">>, %% Used to work up to R11B. - % <<"apa = qlc:e(qlc:q([X || X <- qlc:append([[1,2,3], ugly()])])), - % ok. - % - % ugly() -> - % [a | apa]. - % foo() -> bar">>, + %% <<"apa = qlc:e(qlc:q([X || X <- qlc:append([[1,2,3], ugly()])])), + %% ok. + %% + %% ugly() -> + %% [a | apa]. + %% foo() -> bar">>, %% Maybe this one should fail. @@ -1172,99 +1138,93 @@ append(Config) when is_list(Config) -> [a,b,1,2,1,2] = qlc:e(Q)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -evaluator(doc) -> - "Simple call from evaluator."; -evaluator(suite) -> []; +%% Simple call from evaluator. evaluator(Config) when is_list(Config) -> - ?line true = is_alive(), + true = is_alive(), evaluator_2(Config, []), - ?line {ok, Node} = start_node(qlc_SUITE_evaluator), - ?line ok = rpc:call(Node, ?MODULE, evaluator_2, [Config, [compiler]]), - ?line ?t:stop_node(Node), + {ok, Node} = start_node(qlc_SUITE_evaluator), + ok = rpc:call(Node, ?MODULE, evaluator_2, [Config, [compiler]]), + test_server:stop_node(Node), ok. evaluator_2(Config, Apps) -> - ?line lists:foreach(fun(App) -> true = code:del_path(App) end, Apps), + lists:foreach(fun(App) -> true = code:del_path(App) end, Apps), FileName = filename:join(?privdir, "eval"), - ?line ok = file:write_file(FileName, + ok = file:write_file(FileName, <<"H = qlc:q([X || X <- L]), [1,2,3] = qlc:e(H).">>), - ?line Bs = erl_eval:add_binding('L', [1,2,3], erl_eval:new_bindings()), - ?line ok = file:eval(FileName, Bs), + Bs = erl_eval:add_binding('L', [1,2,3], erl_eval:new_bindings()), + ok = file:eval(FileName, Bs), %% The error message is "handled" a bit too much... %% (no trace of erl_lint left) - ?line ok = file:write_file(FileName, + ok = file:write_file(FileName, <<"H = qlc:q([X || X <- L]), qlc:e(H).">>), - ?line {error,_} = file:eval(FileName), + {error,_} = file:eval(FileName), %% Ugly error message; badarg is caught by file.erl. - ?line ok = file:write_file(FileName, + ok = file:write_file(FileName, <<"H = qlc:q([Z || {X,Y} <- [{a,2}], Z <- [Y]]), qlc:e(H).">>), - ?line {error,_} = file:eval(FileName), + {error,_} = file:eval(FileName), _ = file:delete(FileName), ok. start_node(Name) -> - ?line PA = filename:dirname(code:which(?MODULE)), - ?t:start_node(Name, slave, [{args, "-pa " ++ PA}]). + PA = filename:dirname(code:which(?MODULE)), + test_server:start_node(Name, slave, [{args, "-pa " ++ PA}]). -string_to_handle(doc) -> - "string_to_handle/1,2."; -string_to_handle(suite) -> []; +%% string_to_handle/1,2. string_to_handle(Config) when is_list(Config) -> - ?line {'EXIT',{badarg,_}} = (catch qlc:string_to_handle(14)), - ?line {'EXIT',{badarg,_}} = + {'EXIT',{badarg,_}} = (catch qlc:string_to_handle(14)), + {'EXIT',{badarg,_}} = (catch qlc:string_to_handle("[X || X <- [a].", unique_all)), - ?line R1 = {error, _, {_,erl_scan,_}} = qlc:string_to_handle("'"), - ?line "1: unterminated " ++ _ = lists:flatten(qlc:format_error(R1)), - ?line {error, _, {_,erl_parse,_}} = qlc:string_to_handle("foo"), - ?line {'EXIT',{badarg,_}} = (catch qlc:string_to_handle("foo, bar.")), - ?line R3 = {error, _, {_,?QLC,not_a_query_list_comprehension}} = + R1 = {error, _, {_,erl_scan,_}} = qlc:string_to_handle("'"), + "1: unterminated " ++ _ = lists:flatten(qlc:format_error(R1)), + {error, _, {_,erl_parse,_}} = qlc:string_to_handle("foo"), + {'EXIT',{badarg,_}} = (catch qlc:string_to_handle("foo, bar.")), + R3 = {error, _, {_,?QLC,not_a_query_list_comprehension}} = qlc:string_to_handle("bad."), - ?line "1: argument is not" ++ _ = lists:flatten(qlc:format_error(R3)), - ?line R4 = {error, _, {_,?QLC,{used_generator_variable,'Y'}}} = + "1: argument is not" ++ _ = lists:flatten(qlc:format_error(R3)), + R4 = {error, _, {_,?QLC,{used_generator_variable,'Y'}}} = qlc:string_to_handle("[X || begin Y = [1,2], true end, X <- Y]."), - ?line "1: generated variable 'Y'" ++ _ = + "1: generated variable 'Y'" ++ _ = lists:flatten(qlc:format_error(R4)), - ?line {error, _, {_,erl_lint,_}} = qlc:string_to_handle("[X || X <- A]."), - ?line H1 = qlc:string_to_handle("[X || X <- [1,2]]."), - ?line [1,2] = qlc:e(H1), - ?line H2 = qlc:string_to_handle("[X || X <- qlc:append([a,b]," + {error, _, {_,erl_lint,_}} = qlc:string_to_handle("[X || X <- A]."), + H1 = qlc:string_to_handle("[X || X <- [1,2]]."), + [1,2] = qlc:e(H1), + H2 = qlc:string_to_handle("[X || X <- qlc:append([a,b]," "qlc:e(qlc:q([X || X <- [c,d,e]])))]."), - ?line [a,b,c,d,e] = qlc:e(H2), + [a,b,c,d,e] = qlc:e(H2), %% The generated fun has many arguments (erl_eval has a maximum of 20). - ?line H3 = qlc:string_to_handle( + H3 = qlc:string_to_handle( "[{A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W} ||" " {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W} <- []]."), - ?line [] = qlc:e(H3), - ?line Bs1 = erl_eval:add_binding('L', [1,2,3], erl_eval:new_bindings()), - ?line H4 = qlc:string_to_handle("[X || X <- L].", [], Bs1), - ?line [1,2,3] = qlc:e(H4), - ?line H5 = qlc:string_to_handle("[X || X <- [1,2,1,2]].", [unique, cache]), - ?line [1,2] = qlc:e(H5), - - ?line Ets = ets:new(test, []), - ?line true = ets:insert(Ets, [{1}]), - ?line Bs2 = erl_eval:add_binding('E', Ets, erl_eval:new_bindings()), - ?line Q = "[X || {X} <- ets:table(E)].", - ?line [1] = qlc:e(qlc:string_to_handle(Q, [], Bs2)), - ?line [1] = qlc:e(qlc:string_to_handle(Q, {max_lookup,1000}, Bs2)), - ?line [1] = qlc:e(qlc:string_to_handle(Q, {max_lookup,infinity}, Bs2)), - ?line {'EXIT',{badarg,_}} = + [] = qlc:e(H3), + Bs1 = erl_eval:add_binding('L', [1,2,3], erl_eval:new_bindings()), + H4 = qlc:string_to_handle("[X || X <- L].", [], Bs1), + [1,2,3] = qlc:e(H4), + H5 = qlc:string_to_handle("[X || X <- [1,2,1,2]].", [unique, cache]), + [1,2] = qlc:e(H5), + + Ets = ets:new(test, []), + true = ets:insert(Ets, [{1}]), + Bs2 = erl_eval:add_binding('E', Ets, erl_eval:new_bindings()), + Q = "[X || {X} <- ets:table(E)].", + [1] = qlc:e(qlc:string_to_handle(Q, [], Bs2)), + [1] = qlc:e(qlc:string_to_handle(Q, {max_lookup,1000}, Bs2)), + [1] = qlc:e(qlc:string_to_handle(Q, {max_lookup,infinity}, Bs2)), + {'EXIT',{badarg,_}} = (catch qlc:string_to_handle(Q, {max_lookup,-1}, Bs2)), - ?line {'EXIT', {no_lookup_to_carry_out, _}} = + {'EXIT', {no_lookup_to_carry_out, _}} = (catch qlc:e(qlc:string_to_handle(Q, {lookup,true}, Bs2))), - ?line ets:delete(Ets), + ets:delete(Ets), ok. -table(doc) -> - "table"; -table(suite) -> []; +%% table table(Config) when is_list(Config) -> dets:start(), Ts = [ @@ -1346,11 +1306,11 @@ table(Config) when is_list(Config) -> ets:delete(E)">>, %% The info tag num_of_objects is currently not used. -% <<"E = ets:new(test, [ordered_set]), -% true = ets:insert(E, [{1,a},{2,b},{3,c}]), -% H = qlc:q([X || X <- qlc_SUITE:bad_table_info_fun_n_objects(E)]), -% {'EXIT', finito} = (catch {any_term,qlc:e(H)}), -% ets:delete(E)">>, +%% <<"E = ets:new(test, [ordered_set]), +%% true = ets:insert(E, [{1,a},{2,b},{3,c}]), +%% H = qlc:q([X || X <- qlc_SUITE:bad_table_info_fun_n_objects(E)]), +%% {'EXIT', finito} = (catch {any_term,qlc:e(H)}), +%% ets:delete(E)">>, <<"E = ets:new(test, [ordered_set]), true = ets:insert(E, [{1,a},{2,b},{3,c}]), @@ -1466,7 +1426,7 @@ table(Config) when is_list(Config) -> [1,2] = lookup_keys(Q) end, [{1,1},{2,2}])">> ], - ?line run(Config, Ts), + run(Config, Ts), Ts2 = [ %% [T || P <- Table, F] turned into a match spec. Records needed. @@ -1477,13 +1437,11 @@ table(Config) when is_list(Config) -> [{a,1,2},{a,3,4}] = lists:sort(qlc:eval(QH)), ets:delete(E)">> ], - ?line run(Config, <<"-record(a, {b,c}).\n">>, Ts2), + run(Config, <<"-record(a, {b,c}).\n">>, Ts2), ok. -process_dies(doc) -> - "Caller or cursor process dies."; -process_dies(suite) -> []; +%% Caller or cursor process dies. process_dies(Config) when is_list(Config) -> Ts = [ <<"E = ets:new(test, []), @@ -1622,12 +1580,10 @@ process_dies(Config) when is_list(Config) -> true = ets:delete(E), ok">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -sort(doc) -> - "The sort option."; -sort(suite) -> []; +%% The sort option. sort(Config) when is_list(Config) -> Ts = [ <<"H = qlc:q([X || X <- qlc:sort([1,2,3,2], {unique,true})]), @@ -1734,12 +1690,10 @@ sort(Config) when is_list(Config) -> end ], - ?line run(Config, Ts), + run(Config, Ts), ok. -keysort(doc) -> - "The sort option."; -keysort(suite) -> []; +%% The sort option. keysort(Config) when is_list(Config) -> Ts = [ @@ -1858,13 +1812,11 @@ keysort(Config) when is_list(Config) -> 100003 = length(R)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -filesort(doc) -> - "keysort/1,2, using a file."; -filesort(suite) -> []; +%% keysort/1,2, using a file. filesort(Config) when is_list(Config) -> Ts = [ <<"Q = qlc:q([X || X <- [{3},{1},{2}]]), @@ -1872,13 +1824,11 @@ filesort(Config) when is_list(Config) -> Q2 = qlc:q([{X,Y} || Y <- [1,2], X <- qlc:keysort([1],Q,Opts)]), [{{1},1},{{2},1},{{3},1},{{1},2},{{2},2},{{3},2}] = qlc:e(Q2)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -cache(doc) -> - "The cache option."; -cache(suite) -> []; +%% The cache option. cache(Config) when is_list(Config) -> Ts = [ <<"{'EXIT', {badarg, _}} = (catch qlc:q([X || X <- [1,2]], badarg))">>, @@ -2036,12 +1986,10 @@ cache(Config) when is_list(Config) -> []} = i(H, cache_all)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -cache_list(doc) -> - "OTP-6038. The {cache,list} option."; -cache_list(suite) -> []; +%% OTP-6038. The {cache,list} option. cache_list(Config) when is_list(Config) -> Ts = [ begin @@ -2327,12 +2275,10 @@ cache_list(Config) when is_list(Config) -> {'EXIT', {badarg, _}} = (catch qlc:e(Q, {max_list_size, foo}))">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -filter(doc) -> - "Filters and match specs."; -filter(suite) -> []; +%% Filters and match specs. filter(Config) when is_list(Config) -> Ts = [ <<"L = [1,2,3,4,5], @@ -2454,12 +2400,10 @@ filter(Config) when is_list(Config) -> [{2,b},{2,c},{3,b},{3,c}] = qlc:e(H)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -info(doc) -> - "info/2."; -info(suite) -> []; +%% info/2. info(Config) when is_list(Config) -> Ts = [ <<"{list, [1,2]} = i(qlc:q([X || X <- [1,2]])), @@ -2485,8 +2429,11 @@ info(Config) when is_list(Config) -> (catch qlc:info([X || {X} <- []], {n_elements, 0})), L = lists:seq(1, 1000), \"[1,2,3,4,5,6,7,8,9,10|'...']\" = qlc:info(L, {n_elements, 10}), - {cons,1,{integer,1,1},{atom,1,'...'}} = + {cons,A1,{integer,A2,1},{atom,A3,'...'}} = qlc:info(L, [{n_elements, 1},{format,abstract_code}]), + 1 = erl_anno:line(A1), + 1 = erl_anno:line(A2), + 1 = erl_anno:line(A3), Q = qlc:q([{X} || X <- [a,b,c,d,e,f]]), {call,_,_,[{cons,_,{atom,_,a},{cons,_,{atom,_,b},{cons,_,{atom,_,c}, {atom,_,'...'}}}}, @@ -2544,7 +2491,7 @@ info(Config) when is_list(Config) -> ets:delete(E)">>, <<"Q1 = qlc:q([W || W <- [a,b]]), - Q2 = qlc:q([Z || Z <- qlc:sort([1,2,300])], unique), + Q2 = qlc:q([Z || Z <- qlc:sort([55296,56296,57296])], unique), Q3 = qlc:q([{X,Y} || X <- qlc:keysort([2], [{1,a}]), Y <- qlc:append([Q1, Q2]), X > Y]), @@ -2552,7 +2499,7 @@ info(Config) when is_list(Config) -> [{generate, P1, {list, [{1,a}]}}, {generate, P2, {append, [{list, [a,b]}, {qlc, T2, [{generate, P3, - {sort, {list,[1,2,300]},[]}}], + {sort, {list,[55296,56296,57296]},[]}}], [{cache,ets},{unique,true}]}]}},F], []} = i(Q3, cache_all), {tuple, _, [{var,_,'X'}, {var,_,'Y'}]} = binary_to_term(T1), @@ -2562,7 +2509,7 @@ info(Config) when is_list(Config) -> {var, _, 'Z'} = binary_to_term(T2), {op, _, '>', {var, _, 'X'}, {var, _, 'Y'}} = binary_to_term(F), true = binary_to_list(<< - \"beginV1=qlc:q([Z||Z<-qlc:sort([1,2,300],[])],[{unique,true}]),\" + \"beginV1=qlc:q([Z||Z<-qlc:sort([55296,56296,57296],[])],[{unique,true}]),\" \"qlc:q([{X,Y}||X<-[{1,a}],Y<-qlc:append([[a,b],V1]),X>Y])end\" >>) == format_info(Q3, true)">>, @@ -2676,12 +2623,10 @@ info(Config) when is_list(Config) -> [{4},{5},{6}] = qlc:e(F(3))">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -nested_info(doc) -> - "Nested QLC expressions. QLC expressions in filter and template."; -nested_info(suite) -> []; +%% Nested QLC expressions. QLC expressions in filter and template. nested_info(Config) when is_list(Config) -> Ts = [ <<"L = [{1,a},{2,b},{3,c}], @@ -2782,13 +2727,11 @@ nested_info(Config) when is_list(Config) -> [{1,1},{1,1},{1,2},{1,2},{2,1},{2,1},{2,2},{2,2}] = qlc:e(Q)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -lookup1(doc) -> - "Lookup keys. Mostly test of patterns."; -lookup1(suite) -> []; +%% Lookup keys. Mostly test of patterns. lookup1(Config) when is_list(Config) -> Ts = [ <<"etsc(fun(E) -> @@ -2903,7 +2846,8 @@ lookup1(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{1},{a}])">>, - {warnings,[{{2,37},qlc,nomatch_pattern}]}}, + %% {warnings,[{{2,37},qlc,nomatch_pattern}]}}, + []}, <<"etsc(fun(E) -> Q = qlc:q([X || {X=X,Y=Y}={Y=Y,X=X} <- ets:table(E), @@ -2931,7 +2875,8 @@ lookup1(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{a},{b}])">>, - {warnings,[{{2,35},qlc,nomatch_pattern}]}}, + %% {warnings,[{{2,35},qlc,nomatch_pattern}]}}, + []}, {cres, <<"etsc(fun(E) -> @@ -2939,7 +2884,8 @@ lookup1(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{a},{b}])">>, - {warnings,[{{2,35},qlc,nomatch_pattern}]}}, + %% {warnings,[{{2,35},qlc,nomatch_pattern}]}}, + []}, <<"etsc(fun(E) -> Q = qlc:q([X || X = <<X>> <- ets:table(E)]), @@ -2986,15 +2932,14 @@ lookup1(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{a,b,c},{d,e,f}])">>, - {warnings,[{{2,34},qlc,nomatch_pattern}]}} + %% {warnings,[{{2,34},qlc,nomatch_pattern}]}} + []} ], - ?line run(Config, Ts), + run(Config, Ts), ok. -lookup2(doc) -> - "Lookup keys. Mostly test of filters."; -lookup2(suite) -> []; +%% Lookup keys. Mostly test of filters. lookup2(Config) when is_list(Config) -> Ts = [ <<"%% Only guards are inspected. No lookup. @@ -3019,8 +2964,9 @@ lookup2(Config) when is_list(Config) -> end, [{3,true},{4,true}])">>, <<"%% Only guards are inspected. No lookup. - E1 = create_ets(1, 10), - E2 = ets:new(join, []), + E1 = ets:new(e, [ordered_set]), + true = ets:insert(E1, [{1,1}, {2,2}, {3,3}, {4,4}, {5,5}]), + E2 = ets:new(join, [ordered_set]), true = ets:insert(E2, [{true,1},{false,2}]), Q = qlc:q([{X,Z} || {_,X} <- ets:table(E1), {Y,Z} <- ets:table(E2), @@ -3049,7 +2995,8 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{1}, {2}])">>, - {warnings,[{{3,46},qlc,nomatch_filter}]}}, + %% {warnings,[{{3,46},qlc,nomatch_filter}]}}, + []}, {cres, <<"etsc(fun(E) -> @@ -3058,7 +3005,8 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{1}, {2}])">>, - {warnings,[{{3,43},qlc,nomatch_filter}]}}, + %% {warnings,[{{3,43},qlc,nomatch_filter}]}}, + []}, {cres, <<"etsc(fun(E) -> @@ -3067,7 +3015,8 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{1}, {2}])">>, - {warnings,[{{3,48},qlc,nomatch_filter}]}}, + %% {warnings,[{{3,48},qlc,nomatch_filter}]}}, + []}, <<"etsc(fun(E) -> Q = qlc:q([{X,Y} || {X,Y} <- ets:table(E), @@ -3082,7 +3031,8 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{[3]},{[3,4]}])">>, - {warnings,[{{2,61},qlc,nomatch_filter}]}}, + %% {warnings,[{{2,61},qlc,nomatch_filter}]}}, + []}, <<"etsc(fun(E) -> U = 18, @@ -3114,7 +3064,8 @@ lookup2(Config) when is_list(Config) -> [] = lists:sort(qlc:e(Q)), false = lookup_keys(Q) end, [{2},{3},{4},{8}])">>, - {warnings,[{{4,44},qlc,nomatch_filter}]}}, + %% {warnings,[{{4,44},qlc,nomatch_filter}]}}, + []}, {cres, <<"etsc(fun(E) -> @@ -3124,7 +3075,8 @@ lookup2(Config) when is_list(Config) -> [] = lists:sort(qlc:e(Q)), false = lookup_keys(Q) end, [{2},{3},{4},{8}])">>, - {warnings,[{{4,35},qlc,nomatch_filter}]}}, + %% {warnings,[{{4,35},qlc,nomatch_filter}]}}, + []}, <<"F = fun(U) -> Q = qlc:q([X || {X} <- [a,b,c], @@ -3140,7 +3092,8 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{1,1},{2,1}])">>, - {warnings,[{{2,61},qlc,nomatch_filter}]}}, + %% {warnings,[{{2,61},qlc,nomatch_filter}]}}, + []}, <<"Two = 2.0, etsc(fun(E) -> @@ -3201,8 +3154,10 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{1,b},{2,3}])">>, + %% {warnings,[{2,sys_core_fold,nomatch_guard}, + %% {3,qlc,nomatch_filter}, + %% {3,sys_core_fold,{eval_failure,badarg}}]}}, {warnings,[{2,sys_core_fold,nomatch_guard}, - {3,qlc,nomatch_filter}, {3,sys_core_fold,{eval_failure,badarg}}]}}, <<"etsc(fun(E) -> @@ -3225,7 +3180,8 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{{1}},{{2}}])">>, - {warnings,[{{4,47},qlc,nomatch_filter}]}}, + %% {warnings,[{{4,47},qlc,nomatch_filter}]}}, + []}, {cres, <<"etsc(fun(E) -> @@ -3235,7 +3191,8 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{{1}},{{2}}])">>, - {warnings,[{{4,47},qlc,nomatch_filter}]}}, + %% {warnings,[{{4,47},qlc,nomatch_filter}]}}, + []}, <<"etsc(fun(E) -> Q = qlc:q([X || {X} <- ets:table(E), @@ -3295,7 +3252,8 @@ lookup2(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{3}, {4}])">>, - {warnings,[{{3,44},qlc,nomatch_filter}]}}, + %% {warnings,[{{3,44},qlc,nomatch_filter}]}}, + []}, <<"etsc(fun(E) -> Q = qlc:q([X || {{X,Y}} <- ets:table(E), @@ -3416,7 +3374,8 @@ lookup2(Config) when is_list(Config) -> end, [{1},{2}])">> ], - ?line run(Config, Ts), + + ok = run(Config, Ts), TsR = [ %% is_record/2,3: @@ -3454,7 +3413,8 @@ lookup2(Config) when is_list(Config) -> end, [{keypos,1}], [#r{}])">> ], - ?line run(Config, <<"-record(r, {a}).\n">>, TsR), + + ok = run(Config, <<"-record(r, {a}).\n">>, TsR), Ts2 = [ <<"etsc(fun(E) -> @@ -3564,7 +3524,6 @@ lookup2(Config) when is_list(Config) -> [{1,2},{2,2}] = qlc:e(Q), [2] = lookup_keys(Q) end, [{keypos,1}], [{1},{2},{3}])">>, - <<"%% Matchspec only. No cache. etsc(fun(E) -> Q = qlc:q([{X,Y} || @@ -3576,7 +3535,7 @@ lookup2(Config) when is_list(Config) -> {generate,_, {table,{ets,_,[_,[{traverse,_}]]}}}],[]} = i(Q), - [{1,2},{1,3},{2,2},{2,3}] = qlc:e(Q), + [{1,2},{1,3},{2,2},{2,3}] = lists:sort(qlc:e(Q)), false = lookup_keys(Q) end, [{keypos,1}], [{1},{2},{3}])">>, <<"%% Matchspec only. Cache @@ -3590,7 +3549,7 @@ lookup2(Config) when is_list(Config) -> {generate,_,{qlc,_, [{generate,_,{table,{ets,_,[_,[{traverse,_}]]}}}], [{cache,ets}]}}],[]} = i(Q), - [{1,2},{1,3},{2,2},{2,3}] = qlc:e(Q), + [{1,2},{1,3},{2,2},{2,3}] = lists:sort(qlc:e(Q)), false = lookup_keys(Q) end, [{keypos,1}], [{1},{2},{3}])">>, <<"%% An empty list. Always unique and cached. @@ -3643,7 +3602,7 @@ lookup2(Config) when is_list(Config) -> ], - ?line run(Config, Ts2), + ok = run(Config, Ts2), LTs = [ <<"etsc(fun(E) -> @@ -3675,13 +3634,12 @@ lookup2(Config) when is_list(Config) -> end, [{1,a},{2,b}])">> ], - ?line run(Config, LTs), + + ok = run(Config, LTs), ok. -lookup_rec(doc) -> - "Lookup keys. With records."; -lookup_rec(suite) -> []; +%% Lookup keys. With records. lookup_rec(Config) when is_list(Config) -> Ts = [ <<"etsc(fun(E) -> @@ -3698,7 +3656,8 @@ lookup_rec(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{keypos,2}], [#r{a = 17}, #r{a = 3}, #r{a = 5}])">>, - {warnings,[{{4,44},qlc,nomatch_filter}]}}, + %% {warnings,[{{4,44},qlc,nomatch_filter}]}}, + []}, <<"%% Compares an integer and a float. etsc(fun(E) -> @@ -3748,12 +3707,10 @@ lookup_rec(Config) when is_list(Config) -> [_] = lookup_keys(Q) end, [{keypos,2}], [#r{a=foo}])">> ], - ?line run(Config, <<"-record(r, {a}).\n">>, Ts), + run(Config, <<"-record(r, {a}).\n">>, Ts), ok. -indices(doc) -> - "Using indices for lookup."; -indices(suite) -> []; +%% Using indices for lookup. indices(Config) when is_list(Config) -> Ts = [ <<"L = [{1,a},{2,b},{3,c}], @@ -3815,12 +3772,10 @@ indices(Config) when is_list(Config) -> [{c,3,z,w}] = qlc:eval(QH)">> ], - ?line run(Config, <<"-record(r, {a}).\n">>, Ts), + run(Config, <<"-record(r, {a}).\n">>, Ts), ok. -pre_fun(doc) -> - "Test the table/2 callback functions parent_fun and stop_fun."; -pre_fun(suite) -> []; +%% Test the table/2 callback functions parent_fun and stop_fun. pre_fun(Config) when is_list(Config) -> Ts = [ <<"PF = process_flag(trap_exit, true), @@ -3896,12 +3851,10 @@ pre_fun(Config) when is_list(Config) -> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -skip_filters(doc) -> - "Lookup keys. With records."; -skip_filters(suite) -> []; +%% Lookup keys. With records. skip_filters(Config) when is_list(Config) -> %% Skipped filters TsS = [ @@ -4002,7 +3955,8 @@ skip_filters(Config) when is_list(Config) -> [] = qlc:e(Q), false = lookup_keys(Q) end, [{1,1},{2,0}])">>, - {warnings,[{{4,37},qlc,nomatch_filter}]}}, + %% {warnings,[{{4,37},qlc,nomatch_filter}]}}, + []}, <<"etsc(fun(E) -> Q = qlc:q([{A,B,C} || @@ -4020,7 +3974,7 @@ skip_filters(Config) when is_list(Config) -> end, [{0},{1},{2},{3},{4}])">> ], - ?line run(Config, TsS), + run(Config, TsS), Ts = [ <<"etsc(fun(E) -> @@ -4298,14 +4252,12 @@ skip_filters(Config) when is_list(Config) -> end, [{1},{2},{3}])">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -ets(doc) -> - "ets:table/1,2."; -ets(suite) -> []; +%% ets:table/1,2. ets(Config) when is_list(Config) -> Ts = [ <<"E = ets:new(t, [ordered_set]), @@ -4346,12 +4298,10 @@ ets(Config) when is_list(Config) -> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -dets(doc) -> - "dets:table/1,2."; -dets(suite) -> []; +%% dets:table/1,2. dets(Config) when is_list(Config) -> dets:start(), T = t, @@ -4444,14 +4394,12 @@ dets(Config) when is_list(Config) -> ], - ?line run(Config, Ts), + run(Config, Ts), _ = file:delete(Fname), ok. -join_option(doc) -> - "The 'join' option (any, lookup, merge, nested_loop). Also cache/unique."; -join_option(suite) -> []; +%% The 'join' option (any, lookup, merge, nested_loop). Also cache/unique. join_option(Config) when is_list(Config) -> Ts = [ <<"Q1 = qlc:q([X || X <- [1,2,3]],{join,merge}), @@ -4576,7 +4524,7 @@ join_option(Config) when is_list(Config) -> ets:delete(E1)">> ], - ?line run(Config, Ts), + run(Config, Ts), %% The 'cache' and 'unique' options of qlc/2 affects join. CUTs = [ @@ -4624,13 +4572,11 @@ join_option(Config) when is_list(Config) -> _],[{unique,true}]} = i(Q, Options), [{1,1,1},{2,2,1},{1,1,2},{2,2,2}] = qlc:e(Q, Options)">> ], - ?line run(Config, CUTs), + run(Config, CUTs), ok. -join_filter(doc) -> - "Various aspects of filters and join."; -join_filter(suite) -> []; +%% Various aspects of filters and join. join_filter(Config) when is_list(Config) -> Ts = [ <<"E1 = create_ets(1, 10), @@ -4667,12 +4613,10 @@ join_filter(Config) when is_list(Config) -> end, [{a},{b},{c}])">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -join_lookup(doc) -> - "Lookup join."; -join_lookup(suite) -> []; +%% Lookup join. join_lookup(Config) when is_list(Config) -> Ts = [ <<"E1 = create_ets(1, 10), @@ -4762,12 +4706,10 @@ join_lookup(Config) when is_list(Config) -> ets:delete(E)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -join_merge(doc) -> - "Merge join."; -join_merge(suite) -> []; +%% Merge join. join_merge(Config) when is_list(Config) -> Ts = [ <<"Q = qlc:q([{X,Y} || {X} <- [], {Y} <- [{1}], X =:= Y], @@ -5039,7 +4981,7 @@ join_merge(Config) when is_list(Config) -> [{2,a}] = qlc:e(Q)">> ], - ?line run(Config, Ts), + run(Config, Ts), %% Small examples. Returning an error term. ETs = [ @@ -5218,7 +5160,7 @@ join_merge(Config) when is_list(Config) -> err = qlc:e(Q)">> ], - ?line run(Config, ETs), + run(Config, ETs), %% Mostly examples where temporary files are needed while merging. FTs = [ @@ -5377,13 +5319,11 @@ join_merge(Config) when is_list(Config) -> ], - ?line run(Config, FTs), + run(Config, FTs), ok. -join_sort(doc) -> - "Merge join optimizations (avoid unnecessary sorting)."; -join_sort(suite) -> []; +%% Merge join optimizations (avoid unnecessary sorting). join_sort(Config) when is_list(Config) -> Ts = [ <<"H1_1 = qlc:keysort(1, [{1,2,3},{4,5,6}]), @@ -5663,12 +5603,10 @@ join_sort(Config) when is_list(Config) -> end, [{1,2},{3,4}])">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -join_complex(doc) -> - "Join of more than two columns."; -join_complex(suite) -> []; +%% Join of more than two columns. join_complex(Config) when is_list(Config) -> Ts = [{three, <<"three() -> @@ -5696,7 +5634,7 @@ join_complex(Config) when is_list(Config) -> {warnings,[{2,qlc,too_many_joins}]}} ], - ?line compile(Config, Ts), + compile(Config, Ts), Ts2 = [{three, <<"three() -> @@ -5725,14 +5663,12 @@ join_complex(Config) when is_list(Config) -> {[],["cannot handle more than one join efficiently"]}} ], - ?line compile_format(Config, Ts2), + compile_format(Config, Ts2), ok. -otp_5644(doc) -> - "OTP-5644. Handle the new language element M:F/A."; -otp_5644(suite) -> []; +%% OTP-5644. Handle the new language element M:F/A. otp_5644(Config) when is_list(Config) -> Ts = [ <<"Q = qlc:q([fun modul:mfa/0 || _ <- [1,2], @@ -5740,12 +5676,10 @@ otp_5644(Config) when is_list(Config) -> [_,_] = qlc:eval(Q)">> ], - ?line run(Config, Ts), + run(Config, Ts), ok. -otp_5195(doc) -> - "OTP-5195. Allow traverse functions returning terms."; -otp_5195(suite) -> []; +%% OTP-5195. Allow traverse functions returning terms. otp_5195(Config) when is_list(Config) -> %% Several minor improvements have been implemented in OTP-5195. %% The test cases are spread all over... except these. @@ -5823,7 +5757,7 @@ otp_5195(Config) when is_list(Config) -> ], - ?line run(Config, Ts), + run(Config, Ts), Ts2 = [<<"Q = qlc:q([{X,Y} || {X} <- [{1},{2},{3}], begin @@ -5832,13 +5766,11 @@ otp_5195(Config) when is_list(Config) -> end, X =:= Y]), [{3,3}] = qlc:e(Q)">>], - ?line run(Config, Ts2), + run(Config, Ts2), ok. -otp_6038_bug(doc) -> - "OTP-6038. Bug fixes: unique and keysort; cache."; -otp_6038_bug(suite) -> []; +%% OTP-6038. Bug fixes: unique and keysort; cache. otp_6038_bug(Config) when is_list(Config) -> %% The 'unique' option can no longer be merged with the keysort options. %% This used to return [{1,a},{1,c},{2,b},{2,d}], but since @@ -5848,7 +5780,7 @@ otp_6038_bug(Config) when is_list(Config) -> H2 = qlc:keysort(1, H1, [{unique,true}]), [{1,a},{2,b}] = qlc:e(H2)">>], - ?line run(Config, Ts), + run(Config, Ts), %% Sometimes the cache options did not empty the correct tables. CTs = [ @@ -5877,13 +5809,11 @@ otp_6038_bug(Config) when is_list(Config) -> L = [{X,Y} || X <- [1,2], Y <- L4], true = R =:= L">> ], - ?line run(Config, CTs), + run(Config, CTs), ok. -otp_6359(doc) -> - "OTP-6359. dets:select() never returns the empty list."; -otp_6359(suite) -> []; +%% OTP-6359. dets:select() never returns the empty list. otp_6359(Config) when is_list(Config) -> dets:start(), T = luna, @@ -5902,12 +5832,10 @@ otp_6359(Config) when is_list(Config) -> ok">>] ], - ?line run(Config, Ts), + run(Config, Ts), ok. -otp_6562(doc) -> - "OTP-6562. compressed = false (should be []) when sorting before join."; -otp_6562(suite) -> []; +%% OTP-6562. compressed = false (should be []) when sorting before join. otp_6562(Config) when is_list(Config) -> Bug = [ %% This example uses a file to sort E2 on the second column. It is @@ -5926,7 +5854,7 @@ otp_6562(Config) when is_list(Config) -> ets:delete(E1), ets:delete(E2)">> ], - ?line run(Config, Bug), + run(Config, Bug), Bits = [ {otp_6562_1, @@ -5938,18 +5866,16 @@ otp_6562(Config) when is_list(Config) -> {errors,[{2,qlc,binary_generator}], []}} ], - ?line [] = compile(Config, Bits), + [] = compile(Config, Bits), - ?line R1 = {error,qlc,{1,qlc,binary_generator}} + R1 = {error,qlc,{1,qlc,binary_generator}} = qlc:string_to_handle("[X || <<X:8>> <= <<\"hej\">>]."), - ?line "1: cannot handle binary generators\n" = + "1: cannot handle binary generators\n" = lists:flatten(qlc:format_error(R1)), ok. -otp_6590(doc) -> - "OTP-6590. Bug fix (join info)."; -otp_6590(suite) -> []; +%% OTP-6590. Bug fix (join info). otp_6590(Config) when is_list(Config) -> Ts = [<<"fun(Tab1Value) -> Q = qlc:q([T1#tab1.id || T1 <- [#tab1{id = id1, @@ -5961,13 +5887,11 @@ otp_6590(Config) when is_list(Config) -> [id1] = qlc:e(Q) end(v)">>], - ?line run(Config, <<"-record(tab1, {id, tab2_id, value}). + run(Config, <<"-record(tab1, {id, tab2_id, value}). -record(tab2, {id, value}).\n">>, Ts), ok. -otp_6673(doc) -> - "OTP-6673. Optimizations and fixes."; -otp_6673(suite) -> []; +%% OTP-6673. Optimizations and fixes. otp_6673(Config) when is_list(Config) -> Ts_PT = [<<"etsc(fun(E1) -> @@ -6023,7 +5947,7 @@ otp_6673(Config) when is_list(Config) -> end, [{1,x},{2,y},{3,z}])">>], - ?line run(Config, Ts_PT), + run(Config, Ts_PT), MS = ets:fun2ms(fun({X,_Y}=T) when X > 1 -> T end), Ts_RT = [ @@ -6060,13 +5984,11 @@ otp_6673(Config) when is_list(Config) -> end, [{x,1},{y,2},{z,3}])">> ], - ?line run(Config, Ts_RT), + run(Config, Ts_RT), ok. -otp_6964(doc) -> - "OTP-6964. New option 'tmpdir_usage'."; -otp_6964(suite) -> []; +%% OTP-6964. New option 'tmpdir_usage'. otp_6964(Config) when is_list(Config) -> T1 = [ <<"Q1 = qlc:q([{X} || X <- [1,2]]), @@ -6091,7 +6013,7 @@ otp_6964(Config) when is_list(Config) -> lists:flatten(qlc:format_error(ErrReply)), qlc_SUITE:install_error_logger(), 20000 = length(F(warning_msg)), - {error, joining} = qlc_SUITE:read_error_logger(), + {warning, joining} = qlc_SUITE:read_error_logger(), 20000 = length(F(info_msg)), {info, joining} = qlc_SUITE:read_error_logger(), 20000 = length(F(error_msg)), @@ -6100,7 +6022,7 @@ otp_6964(Config) when is_list(Config) -> _ = erlang:system_flag(backtrace_depth, D) end, qlc_SUITE:uninstall_error_logger()">>], - ?line run(Config, T1), + run(Config, T1), T2 = [ <<"%% File sorter. @@ -6126,14 +6048,14 @@ otp_6964(Config) when is_list(Config) -> {error, caching} = qlc_SUITE:read_error_logger(), {error, caching} = qlc_SUITE:read_error_logger(), 1 = length(F(warning_msg)), - {error, caching} = qlc_SUITE:read_error_logger(), - {error, caching} = qlc_SUITE:read_error_logger(), + {warning, caching} = qlc_SUITE:read_error_logger(), + {warning, caching} = qlc_SUITE:read_error_logger(), 1 = length(F(info_msg)), {info, caching} = qlc_SUITE:read_error_logger(), {info, caching} = qlc_SUITE:read_error_logger(), qlc_SUITE:uninstall_error_logger()">>], - ?line run(Config, T2), + run(Config, T2), T3 = [ <<"%% sort/keysort @@ -6159,11 +6081,11 @@ otp_6964(Config) when is_list(Config) -> L = F(info_msg), {info, sorting} = qlc_SUITE:read_error_logger(), L = F(warning_msg), - {error, sorting} = qlc_SUITE:read_error_logger(), + {warning, sorting} = qlc_SUITE:read_error_logger(), qlc_SUITE:uninstall_error_logger(), ets:delete(E1), ets:delete(E2)">>], - ?line run(Config, T3), + run(Config, T3), T4 = [ <<"%% cache list @@ -6186,7 +6108,7 @@ otp_6964(Config) when is_list(Config) -> R = lists:sort(F(error_msg)), {error, caching} = qlc_SUITE:read_error_logger(), R = lists:sort(F(warning_msg)), - {error, caching} = qlc_SUITE:read_error_logger(), + {warning, caching} = qlc_SUITE:read_error_logger(), qlc_SUITE:uninstall_error_logger(), ErrReply = F(not_allowed), {error,qlc,{tmpdir_usage,caching}} = ErrReply, @@ -6194,18 +6116,16 @@ otp_6964(Config) when is_list(Config) -> lists:flatten(qlc:format_error(ErrReply)) end, [{keypos,1}], [{I,a,lists:duplicate(100000,1)} || I <- lists:seq(1, 10)])">>], - ?line run(Config, T4), + run(Config, T4), ok. -otp_7238(doc) -> - "OTP-7238. info-option 'depth', &c."; -otp_7238(suite) -> []; +%% OTP-7238. info-option 'depth', &c. otp_7238(Config) when is_list(Config) -> dets:start(), T = otp_7238, Fname = filename(T, Config), - ?line ok = compile_gb_table(Config), + ok = compile_gb_table(Config), %% A few more warnings. T1 = [ @@ -6215,8 +6135,9 @@ otp_7238(Config) when is_list(Config) -> <<"nomatch_1() -> {qlc:q([X || X={X} <- []]), [t || \"a\"=\"b\" <- []]}.">>, [], - {warnings,[{{2,30},qlc,nomatch_pattern}, - {{2,44},v3_core,nomatch}]}}, + %% {warnings,[{{2,30},qlc,nomatch_pattern}, + %% {{2,44},v3_core,nomatch}]}}, + {warnings,[{2,v3_core,nomatch}]}}, %% Not found by qlc... {nomatch_2, @@ -6229,7 +6150,8 @@ otp_7238(Config) when is_list(Config) -> <<"nomatch_3() -> qlc:q([t || [$a, $b] = \"ba\" <- []]).">>, [], - {warnings,[{{2,37},qlc,nomatch_pattern}]}}, + %% {warnings,[{{2,37},qlc,nomatch_pattern}]}}, + {warnings,[{2,v3_core,nomatch}]}}, %% Not found by qlc... {nomatch_4, @@ -6250,44 +6172,51 @@ otp_7238(Config) when is_list(Config) -> qlc:q([X || X <- [], X =:= {X}]).">>, [], - {warnings,[{{3,30},qlc,nomatch_filter}]}}, + %% {warnings,[{{3,30},qlc,nomatch_filter}]}}, + []}, {nomatch_7, <<"nomatch_7() -> qlc:q([X || {X=Y,{Y}=X} <- []]).">>, [], - {warnings,[{{2,28},qlc,nomatch_pattern}]}}, + %% {warnings,[{{2,28},qlc,nomatch_pattern}]}}, + []}, {nomatch_8, <<"nomatch_8() -> qlc:q([X || {X={},X=[]} <- []]).">>, [], - {warnings,[{{2,28},qlc,nomatch_pattern}]}}, + %% {warnings,[{{2,28},qlc,nomatch_pattern}]}}, + []}, {nomatch_9, <<"nomatch_9() -> qlc:q([X || X <- [], X =:= {}, X =:= []]).">>, [], - {warnings,[{{2,49},qlc,nomatch_filter}]}}, + %% {warnings,[{{2,49},qlc,nomatch_filter}]}}, + []}, {nomatch_10, <<"nomatch_10() -> qlc:q([X || X <- [], ((X =:= 1) or (X =:= 2)) and (X =:= 3)]).">>, [], - {warnings,[{{3,53},qlc,nomatch_filter}]}}, + %% {warnings,[{{3,53},qlc,nomatch_filter}]}}, + []}, {nomatch_11, <<"nomatch_11() -> qlc:q([X || X <- [], x =:= []]).">>, [], - {warnings,[{{2,39},qlc,nomatch_filter}]}}, + %% {warnings,[{{2,39},qlc,nomatch_filter}]}}, + {warnings,[{2,sys_core_fold,nomatch_guard}]}}, {nomatch_12, <<"nomatch_12() -> qlc:q([X || X={} <- [], X =:= []]).">>, [], - {warnings,[{{2,42},qlc,nomatch_filter}]}}, + %% {warnings,[{{2,42},qlc,nomatch_filter}]}}, + []}, {nomatch_13, <<"nomatch_13() -> @@ -6295,8 +6224,9 @@ otp_7238(Config) when is_list(Config) -> X={X} <- [], Y={Y} <- []]).">>, [], - {warnings,[{{3,29},qlc,nomatch_pattern}, - {{4,29},qlc,nomatch_pattern}]}}, + %% {warnings,[{{3,29},qlc,nomatch_pattern}, + %% {{4,29},qlc,nomatch_pattern}]}}, + []}, {nomatch_14, <<"nomatch_14() -> @@ -6304,7 +6234,8 @@ otp_7238(Config) when is_list(Config) -> 1 > 0, 1 > X]).">>, [], - {warnings,[{{2,29},qlc,nomatch_pattern}]}}, + %% {warnings,[{{2,29},qlc,nomatch_pattern}]}}, + []}, {nomatch_15, <<"nomatch_15() -> @@ -6313,7 +6244,8 @@ otp_7238(Config) when is_list(Config) -> 1 > 0, 1 > X]).">>, [], - {warnings,[{{2,32},qlc,nomatch_pattern}]}}, + %% {warnings,[{{2,32},qlc,nomatch_pattern}]}}, + []}, %% Template warning. {nomatch_template1, @@ -6322,7 +6254,7 @@ otp_7238(Config) when is_list(Config) -> [], {warnings,[{2,sys_core_fold,no_clause_match}]}} ], - ?line [] = compile(Config, T1), + [] = compile(Config, T1), %% 'depth' is a new option used by info() T2 = [ @@ -6548,22 +6480,23 @@ otp_7238(Config) when is_list(Config) -> qlc:info(Q, [{format,abstract_code},{depth, 2}])">> ], - ?line run(Config, T2), + run(Config, T2), T3 = [ - {nomatch_6, - <<"nomatch_6() -> - qlc:q([X || X <- [], - X =:= {X}]).">>, - [], - {[],["filter evaluates to 'false'"]}}, - - {nomatch_7, - <<"nomatch_7() -> - qlc:q([X || {X=Y,{Y}=X} <- []]).">>, - [], - {[],["pattern cannot possibly match"]}}], - ?line compile_format(Config, T3), +%% {nomatch_6, +%% <<"nomatch_6() -> +%% qlc:q([X || X <- [], +%% X =:= {X}]).">>, +%% [], +%% {[],["filter evaluates to 'false'"]}}, + +%% {nomatch_7, +%% <<"nomatch_7() -> +%% qlc:q([X || {X=Y,{Y}=X} <- []]).">>, +%% [], +%% {[],["pattern cannot possibly match"]}} + ], + compile_format(Config, T3), %% *Very* simple test - just check that it doesn't crash. Type = [{cres, @@ -6571,13 +6504,11 @@ otp_7238(Config) when is_list(Config) -> {'EXIT',{{badfun,_},_}} = (catch qlc:e(Q))">>, [type_checker], []}], - ?line run(Config, Type), + run(Config, Type), ok. -otp_7114(doc) -> - "OTP-7114. Match spec, table and duplicated objects.."; -otp_7114(suite) -> []; +%% OTP-7114. Match spec, table and duplicated objects... otp_7114(Config) when is_list(Config) -> Ts = [<<"T = ets:new(t, [bag]), [ets:insert(T, {t, I, I div 2}) || I <- lists:seq(1,10)], @@ -6588,11 +6519,9 @@ otp_7114(Config) when is_list(Config) -> [0,1,2,3,4,5] = qlc:e(qlc:sort(qlc:e(Q1)), unique_all), ets:delete(T), ok">>], - ?line run(Config, Ts). + run(Config, Ts). -otp_7232(doc) -> - "OTP-7232. qlc:info() bug (pids, ports, refs, funs)."; -otp_7232(suite) -> []; +%% OTP-7232. qlc:info() bug (pids, ports, refs, funs). otp_7232(Config) when is_list(Config) -> Ts = [<<"L = [fun math:sqrt/1, list_to_pid(\"<0.4.1>\"), erlang:make_ref()], @@ -6607,12 +6536,12 @@ otp_7232(Config) when is_list(Config) -> {nil,_}]} = qlc:info(qlc:sort(L),{format,abstract_code})">>, - <<"Q1 = qlc:q([X || X <- [1000,2000]]), + <<"Q1 = qlc:q([X || X <- [55296,56296]]), Q = qlc:sort(Q1, {order, fun(A,B)-> A>B end}), - \"qlc:sort([1000,2000],[{order,fun'-function/0-fun-2-'/2}])\" = + \"qlc:sort([55296,56296],[{order,fun'-function/0-fun-2-'/2}])\" = format_info(Q, true), AC = qlc:info(Q, {format, abstract_code}), - \"qlc:sort([1000,2000], [{order,fun '-function/0-fun-2-'/2}])\" = + \"qlc:sort([55296,56296], [{order,fun '-function/0-fun-2-'/2}])\" = binary_to_list(iolist_to_binary(erl_pp:expr(AC)))">>, %% OTP-7234. erl_parse:abstract() handles bit strings @@ -6620,11 +6549,9 @@ otp_7232(Config) when is_list(Config) -> \"[<<8,1:1>>]\" = qlc:info(Q)">> ], - ?line run(Config, Ts). + run(Config, Ts). -otp_7552(doc) -> - "OTP-7552. Merge join bug."; -otp_7552(suite) -> []; +%% OTP-7552. Merge join bug. otp_7552(Config) when is_list(Config) -> %% The poor performance cannot be observed unless the %% (redundant) join filter is skipped. @@ -6647,11 +6574,9 @@ otp_7552(Config) when is_list(Config) -> Qn = F(nested_loop), true = lists:sort(qlc:e(Qm, {max_list_size,20})) =:= lists:sort(qlc:e(Qn))">>], - ?line run(Config, Ts). + run(Config, Ts). -otp_7714(doc) -> - "OTP-7714. Merge join bug."; -otp_7714(suite) -> []; +%% OTP-7714. Merge join bug. otp_7714(Config) when is_list(Config) -> %% The original example uses Mnesia. This one does not. Ts = [<<"E1 = ets:new(set,[]), @@ -6666,14 +6591,23 @@ otp_7714(Config) when is_list(Config) -> [{a,1},{a,2},{a,3}] = lists:sort(qlc:e(Q)), ets:delete(E1), ets:delete(E2)">>], - ?line run(Config, Ts). - -otp_6674(doc) -> - "OTP-6674. match/comparison."; -otp_6674(suite) -> []; + run(Config, Ts). + +%% OTP-11758. Bug. +otp_11758(Config) when is_list(Config) -> + Ts = [<<"T = ets:new(r, [{keypos, 2}]), + L = [{rrr, xxx, aaa}, {rrr, yyy, bbb}], + true = ets:insert(T, L), + QH = qlc:q([{rrr, B, C} || {rrr, B, C} <- ets:table(T), + (B =:= xxx) or (B =:= yyy) and (C =:= aaa)]), + [{rrr,xxx,aaa}] = qlc:e(QH), + ets:delete(T)">>], + run(Config, Ts). + +%% OTP-6674. match/comparison. otp_6674(Config) when is_list(Config) -> - ?line ok = compile_gb_table(Config), + ok = compile_gb_table(Config), Ts = [%% lookup join <<"E = ets:new(join, [ordered_set]), @@ -6807,7 +6741,8 @@ otp_6674(Config) when is_list(Config) -> A == 192, B =:= 192.0, {Y} <- [{0},{1},{2}], X == Y]), - {block,0, + A0 = erl_anno:new(0), + {block,A0, [{match,_,_, {call,_,_, [{lc,_,_, @@ -7095,14 +7030,22 @@ otp_6674(Config) when is_list(Config) -> ], - ?line run(Config, Ts). + run(Config, Ts). + +%% Syntax error. +otp_12946(Config) when is_list(Config) -> + Text = + <<"-export([init/0]). + init() -> + ok. + y">>, + {errors,[{4,erl_parse,_}],[]} = compile_file(Config, Text, []), + ok. -manpage(doc) -> - "Examples from qlc(3)."; -manpage(suite) -> []; +%% Examples from qlc(3). manpage(Config) when is_list(Config) -> - ?line ok = compile_gb_table(Config), + ok = compile_gb_table(Config), Ts = [ <<"QH = qlc:q([{X,Y} || X <- [a,b], Y <- [1,2]]), @@ -7257,7 +7200,7 @@ manpage(Config) when is_list(Config) -> ets:match_spec_compile([{{{'$1','$2'},'_'},[],['$1']}]))\", L = qlc:info(QH)">> ], - ?line run(Config, Ts), + run(Config, Ts), L = [1,2,3], Bs = erl_eval:add_binding('L', L, erl_eval:new_bindings()), @@ -7275,7 +7218,7 @@ manpage(Config) when is_list(Config) -> true = qlc:info(QH1) =:= qlc:info(QH2), true = ets:delete(Tab)">>]], - ?line run(Config, ETs), + run(Config, ETs), %% dets(3) DTs = [ @@ -7288,16 +7231,16 @@ manpage(Config) when is_list(Config) -> true = qlc:info(QH1) =:= qlc:info(QH2), ok = dets:close(T)">>]], - ?line run(Config, DTs), + run(Config, DTs), ok. compile_gb_table(Config) -> GB_table_file = filename("gb_table.erl", Config), - ?line ok = file:write_file(GB_table_file, gb_table()), - ?line {ok, gb_table} = compile:file(GB_table_file, [{outdir,?privdir}]), - ?line code:purge(gb_table), - ?line {module, gb_table} = + ok = file:write_file(GB_table_file, gb_table()), + {ok, gb_table} = compile:file(GB_table_file, [{outdir,?privdir}]), + code:purge(gb_table), + {module, gb_table} = code:load_abs(filename:rootname(GB_table_file)), ok. @@ -7363,9 +7306,7 @@ gb_iter(I0, N, EFun) -> ">>. -backward(doc) -> - "OTP-6674. Join info and extra constants."; -backward(suite) -> []; +%% OTP-6674. Join info and extra constants. backward(Config) when is_list(Config) -> try_old_join_info(Config), ok. @@ -7377,7 +7318,8 @@ try_old_join_info(Config) -> {ok, M} = compile:file(File, [{outdir, ?datadir}]), {module, M} = code:load_abs(filename:rootname(File)), H = M:create_handle(), - {block,0, + A0 = erl_anno:new(0), + {block,A0, [{match,_,_, {call,_,_, [{lc,_,_, @@ -7399,9 +7341,6 @@ try_old_join_info(Config) -> qlc:info(H2, {format,debug}), [{1,1},{2,2}] = qlc:e(H2). -forward(doc) -> - ""; -forward(suite) -> []; forward(Config) when is_list(Config) -> Ts = [ %% LC_fun() returns something unknown. @@ -7410,12 +7349,12 @@ forward(Config) when is_list(Config) -> {'EXIT', {{unsupported_qlc_handle,_},_}} = (catch qlc:e(FakeH))">>, %% 'f1' should be used for new stuff that does not interfer with old behavior -% %% The unused element 'f1' of #qlc_table seems to be used. -% <<"DF = fun() -> foo end, -% FakeH = {qlc_handle,{qlc_table,DF, -% true,DF,DF,DF,DF,DF, -% undefined,not_undefined,undefined,no_match_spec}}, -% {'EXIT', {{unsupported_qlc_handle,_},_}} = (catch qlc:e(FakeH))">>, +%% %% The unused element 'f1' of #qlc_table seems to be used. +%% <<"DF = fun() -> foo end, +%% FakeH = {qlc_handle,{qlc_table,DF, +%% true,DF,DF,DF,DF,DF, +%% undefined,not_undefined,undefined,no_match_spec}}, +%% {'EXIT', {{unsupported_qlc_handle,_},_}} = (catch qlc:e(FakeH))">>, %% #qlc_opt has changed. <<"H = qlc:q([X || X <- []]), @@ -7424,7 +7363,15 @@ forward(Config) when is_list(Config) -> {'EXIT', {{unsupported_qlc_handle,_},_}} = (catch qlc:e(FakeH))">> ], - ?line run(Config, Ts), + run(Config, Ts), + ok. + +eep37(Config) when is_list(Config) -> + Ts = [ + <<"H = (fun _Handle() -> qlc:q([X || X <- []]) end)(), + [] = qlc:eval(H)">> + ], + run(Config, Ts), ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -7749,8 +7696,8 @@ table(List, Indices, KeyPos, ParentFun) -> end, FormatFun = fun(all) -> - L = 17, - {call,L,{remote,L,{atom,1,?MODULE},{atom,L,the_list}}, + L = erl_anno:new(17), + {call,L,{remote,L,{atom,L,?MODULE},{atom,L,the_list}}, [erl_parse:abstract(List, 17)]}; ({lookup, Column, Values}) -> {?MODULE, list_keys, [Values, Column, List]} @@ -7868,7 +7815,7 @@ run_test(Config, Extra, {cres, Body, Opts, ExpectedCompileReturn}) -> {module, _} = code:load_abs(AbsFile, Mod), Ms0 = erlang:process_info(self(),messages), - Before = {get(), pps(), ets:all(), Ms0}, + Before = {{get(), ets:all(), Ms0}, pps()}, %% Prepare the check that the qlc module does not call qlc_pt. _ = [unload_pt() || {file, Name} <- [code:is_loaded(qlc_pt)], @@ -7876,7 +7823,7 @@ run_test(Config, Extra, {cres, Body, Opts, ExpectedCompileReturn}) -> R = case catch Mod:function() of {'EXIT', _Reason} = Error -> - ?t:format("failed, got ~p~n", [Error]), + io:format("failed, got ~p~n", [Error]), fail(SourceFile); Reply -> Reply @@ -7887,7 +7834,7 @@ run_test(Config, Extra, {cres, Body, Opts, ExpectedCompileReturn}) -> {file, cover_compiled} -> ok; {file, _} -> - ?t:format("qlc_pt was loaded in runtime~n", []), + io:format("qlc_pt was loaded in runtime~n", []), fail(SourceFile); false -> ok @@ -7898,12 +7845,29 @@ run_test(Config, Extra, {cres, Body, Opts, ExpectedCompileReturn}) -> run_test(Config, Extra, Body) -> run_test(Config, Extra, {cres,Body,[]}). -wait_for_expected(R, Before, SourceFile, Wait) -> +wait_for_expected(R, {Strict0,PPS0}=Before, SourceFile, Wait) -> Ms = erlang:process_info(self(),messages), - After = {get(), pps(), ets:all(), Ms}, + After = {_,PPS1} = {{get(), ets:all(), Ms}, pps()}, case {R, After} of {ok, Before} -> ok; + {ok, {Strict0,_}} -> + {Ports0,Procs0} = PPS0, + {Ports1,Procs1} = PPS1, + case {Ports1 -- Ports0, Procs1 -- Procs0} of + {[], []} -> ok; + _ when Wait -> + timer:sleep(1000), + wait_for_expected(R, Before, SourceFile, false); + {PortsDiff,ProcsDiff} -> + io:format("failure, got ~p~n, expected ~p\n", + [PPS1, PPS0]), + show("Old port", Ports0 -- Ports1), + show("New port", PortsDiff), + show("Old proc", Procs0 -- Procs1), + show("New proc", ProcsDiff), + fail(SourceFile) + end; _ when Wait -> timer:sleep(1000), wait_for_expected(R, Before, SourceFile, false); @@ -7970,7 +7934,7 @@ compile_file(Config, Test0, Opts0) -> case compile:file(File, Opts) of {ok, _M, Ws} -> warnings(File, Ws); {error, [{File,Es}], []} -> {errors, Es, []}; - {error, [{File,Es}], [{File,Ws}]} -> {error, Es, Ws} + {error, [{File,Es}], [{File,Ws}]} -> {errors, Es, Ws} end. comp_compare(T, T) -> @@ -8035,6 +7999,17 @@ filename(Name, Config) when is_atom(Name) -> filename(Name, Config) -> filename:join(?privdir, Name). +show(_S, []) -> + ok; +show(S, [{Pid, Name, InitCall}|Pids]) when is_pid(Pid) -> + io:format("~s: ~w (~w), ~w: ~p~n", + [S, Pid, proc_reg_name(Name), InitCall, + erlang:process_info(Pid)]), + show(S, Pids); +show(S, [{Port, _}|Ports]) when is_port(Port)-> + io:format("~s: ~w: ~p~n", [S, Port, erlang:port_info(Port)]), + show(S, Ports). + pps() -> {port_list(), process_list()}. @@ -8047,6 +8022,9 @@ process_list() -> safe_second_element(process_info(P, initial_call))} || P <- processes(), is_process_alive(P)]. +proc_reg_name({registered_name, Name}) -> Name; +proc_reg_name([]) -> no_reg_name. + safe_second_element({_,Info}) -> Info; safe_second_element(Other) -> Other. @@ -8057,16 +8035,15 @@ warnings(File, Ws) -> end. expected(Test, Expected, Got, File) -> - ?t:format("~nTest ~p failed. ", [Test]), + io:format("~nTest ~p failed. ", [Test]), expected(Expected, Got, File). expected(Expected, Got, File) -> - ?t:format("Expected~n ~p~n, but got~n ~p~n", [Expected, Got]), + io:format("Expected~n ~p~n, but got~n ~p~n", [Expected, Got]), fail(File). fail(Source) -> - io:format("failed~n"), - ?t:fail({failed,testcase,on,Source}). + ct:fail({failed,testcase,on,Source}). %% Copied from global_SUITE.erl. @@ -8082,11 +8059,13 @@ read_error_logger() -> {error, Why}; {info, Why} -> {info, Why}; + {warning, Why} -> + {warning, Why}; {error, Pid, Tuple} -> {error, Pid, Tuple} after 1000 -> - ?line io:format("No reply after 1 s\n", []), - ?line ?t:fail() + io:format("No reply after 1 s\n", []), + ct:fail(failed) end. %%----------------------------------------------------------------- @@ -8096,8 +8075,7 @@ read_error_logger() -> init(Tester) -> {ok, Tester}. -handle_event({error, _GL, {_Pid, _Msg, [Why, _]}}, Tester) - when is_atom(Why) -> +handle_event({error, _GL, {_Pid, _Msg, [Why, _]}}, Tester) when is_atom(Why) -> Tester ! {error, Why}, {ok, Tester}; handle_event({error, _GL, {_Pid, _Msg, [P, T]}}, Tester) when is_pid(P) -> @@ -8106,6 +8084,9 @@ handle_event({error, _GL, {_Pid, _Msg, [P, T]}}, Tester) when is_pid(P) -> handle_event({info_msg, _GL, {_Pid, _Msg, [Why, _]}}, Tester) -> Tester ! {info, Why}, {ok, Tester}; +handle_event({warning_msg, _GL, {_Pid, _Msg, [Why, _]}}, Tester) when is_atom(Why) -> + Tester ! {warning, Why}, + {ok, Tester}; handle_event(_Event, State) -> {ok, State}. |