1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2016-2020. 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-module(bif_SUITE).
21
22-include_lib("syntax_tools/include/merl.hrl").
23
24-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
25	 init_per_group/2,end_per_group/2,
26	 beam_validator/1,trunc_and_friends/1,cover_safe_and_pure_bifs/1]).
27
28suite() ->
29    [{ct_hooks,[ts_install_cth]}].
30
31all() ->
32    [{group,p}].
33
34groups() ->
35    [{p,[parallel],
36      [beam_validator,
37       trunc_and_friends,
38       cover_safe_and_pure_bifs
39      ]}].
40
41init_per_suite(Config) ->
42    test_lib:recompile(?MODULE),
43    Config.
44
45end_per_suite(_Config) ->
46    ok.
47
48init_per_group(_GroupName, Config) ->
49    Config.
50
51end_per_group(_GroupName, Config) ->
52    Config.
53
54%% Cover code in beam_validator.
55
56beam_validator(Config) ->
57    [false,Config] = food(Config),
58
59    true = is_number(42.0),
60    false = is_port(Config),
61
62    ok.
63
64food(Curriculum) ->
65    [try
66	 is_bitstring(functions)
67     catch _ ->
68	     0
69     end, Curriculum].
70
71%% Test trunc/1, round/1, floor/1, ceil/1.
72trunc_and_friends(_Config) ->
73    Bifs = [trunc,round,floor,ceil],
74    Fs = trunc_and_friends_1(Bifs),
75    Mod = ?FUNCTION_NAME,
76    Calls = [begin
77		 Atom = erl_syntax:function_name(N),
78		 ?Q("'@Atom'()")
79	     end || N <- Fs],
80    Tree = ?Q(["-module('@Mod@').",
81	       "-export([test/0]).",
82	       "test() -> _@Calls, ok.",
83	       "id(I) -> I."]) ++ Fs,
84    merl:print(Tree),
85    Opts = test_lib:opt_opts(?MODULE),
86    {ok,_Bin} = merl:compile_and_load(Tree, Opts),
87    Mod:test(),
88    ok.
89
90trunc_and_friends_1([F|Fs]) ->
91    Func = list_to_atom("f"++integer_to_list(length(Fs))),
92    [trunc_template(Func, F)|trunc_and_friends_1(Fs)];
93trunc_and_friends_1([]) -> [].
94
95trunc_template(Func, Bif) ->
96    Val = 42.77,
97    Res = erlang:Bif(Val),
98    FloatRes = float(Res),
99    ?Q("'@Func@'() ->
100        Var = id(_@Val@),
101        if _@Bif@(Var) =:= _@Res@ -> ok end,
102	if _@Bif@(Var) == _@FloatRes@ -> ok end,
103	if _@Bif@(Var) == _@Res@ -> ok end,
104        _@Res@ = _@Bif@(Var),
105        try begin _@Bif@(a), ok end
106        catch error:badarg -> ok end,
107        ok.").
108
109cover_safe_and_pure_bifs(Config) ->
110    _ = get(),
111    _ = get_keys(a),
112    _ = group_leader(),
113    _ = is_alive(),
114    _ = min(Config, []),
115    _ = nodes(),
116    _ = erlang:ports(),
117    _ = pre_loaded(),
118    _ = processes(),
119    _ = registered(),
120    _ = term_to_binary(Config),
121    42 = list_to_integer("2A", 16),
122
123    ok.
124