1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2006-2016. 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%% 22-module(andor_SUITE). 23 24-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, 25 init_per_testcase/2,end_per_testcase/2, 26 init_per_suite/1,end_per_suite/1, 27 t_andalso/1,t_orelse/1,inside/1,overlap/1, 28 combined/1,in_case/1]). 29 30-include_lib("common_test/include/ct.hrl"). 31 32-warning("Ignore me -- testing that the debugger can handle warnings"). 33 34suite() -> 35 [{ct_hooks,[ts_install_cth]}, 36 {timetrap,{minutes,1}}]. 37 38all() -> 39 cases(). 40 41groups() -> 42 []. 43 44init_per_group(_GroupName, Config) -> 45 Config. 46 47end_per_group(_GroupName, Config) -> 48 Config. 49 50 51init_per_testcase(_Case, Config) -> 52 test_lib:interpret(?MODULE), 53 Config. 54 55end_per_testcase(_Case, _Config) -> 56 ok. 57 58init_per_suite(Config) when is_list(Config) -> 59 test_lib:interpret(?MODULE), 60 true = lists:member(?MODULE, int:interpreted()), 61 Config. 62 63end_per_suite(Config) when is_list(Config) -> 64 ok. 65 66cases() -> 67 [t_andalso, t_orelse, inside, overlap, combined, 68 in_case]. 69 70t_andalso(Config) when is_list(Config) -> 71 Bs = [true,false], 72 Ps = [{X,Y} || X <- Bs, Y <- Bs], 73 lists:foreach(fun (P) -> t_andalso_1(P) end, Ps), 74 75 true = true andalso true, 76 false = true andalso false, 77 false = false andalso true, 78 false = false andalso false, 79 80 false = false andalso glurf, 81 false = false andalso exit(exit_now), 82 83 true = not id(false) andalso not id(false), 84 false = not id(false) andalso not id(true), 85 false = not id(true) andalso not id(false), 86 false = not id(true) andalso not id(true), 87 88 {'EXIT',{badarg,_}} = (catch not id(glurf) andalso id(true)), 89 {'EXIT',{badarg,_}} = (catch not id(false) andalso not id(glurf)), 90 false = id(false) andalso not id(glurf), 91 false = false andalso not id(glurf), 92 93 ok. 94 95t_orelse(Config) when is_list(Config) -> 96 Bs = [true,false], 97 Ps = [{X,Y} || X <- Bs, Y <- Bs], 98 lists:foreach(fun (P) -> t_orelse_1(P) end, Ps), 99 100 true = true orelse true, 101 true = true orelse false, 102 true = false orelse true, 103 false = false orelse false, 104 105 true = true orelse glurf, 106 true = true orelse exit(exit_now), 107 108 true = not id(false) orelse not id(false), 109 true = not id(false) orelse not id(true), 110 true = not id(true) orelse not id(false), 111 false = not id(true) orelse not id(true), 112 113 {'EXIT',{badarg,_}} = (catch not id(glurf) orelse id(true)), 114 {'EXIT',{badarg,_}} = (catch not id(true) orelse not id(glurf)), 115 true = id(true) orelse not id(glurf), 116 true = true orelse not id(glurf), 117 118 ok. 119 120t_andalso_1({X,Y}) -> 121 io:fwrite("~w andalso ~w: ",[X,Y]), 122 V1 = echo(X) andalso echo(Y), 123 V1 = if 124 X andalso Y -> true; 125 true -> false 126 end, 127 check(V1, X and Y). 128 129t_orelse_1({X,Y}) -> 130 io:fwrite("~w orelse ~w: ",[X,Y]), 131 V1 = echo(X) orelse echo(Y), 132 V1 = if 133 X orelse Y -> true; 134 true -> false 135 end, 136 check(V1, X or Y). 137 138inside(Config) when is_list(Config) -> 139 true = inside(-8, 1), 140 false = inside(-53.5, -879798), 141 false = inside(1.0, -879), 142 false = inside(59, -879), 143 false = inside(-11, 1.0), 144 false = inside(100, 0.2), 145 false = inside(100, 1.2), 146 false = inside(-53.5, 4), 147 false = inside(1.0, 5.3), 148 false = inside(59, 879), 149 ok. 150 151inside(Xm, Ym) -> 152 X = -10.0, 153 Y = -2.0, 154 W = 20.0, 155 H = 4.0, 156 Res = inside(Xm, Ym, X, Y, W, H), 157 Res = if 158 X =< Xm andalso Xm < X+W andalso Y =< Ym andalso Ym < Y+H -> true; 159 true -> false 160 end, 161 case not id(Res) of 162 Outside -> 163 Outside = if 164 not(X =< Xm andalso Xm < X+W andalso Y =< Ym andalso Ym < Y+H) -> true; 165 true -> false 166 end 167 end, 168 {Res,Xm,Ym,X,Y,W,H} = inside_guard(Xm, Ym, X, Y, W, H), 169 io:format("~p =< ~p andalso ~p < ~p andalso ~p =< ~p andalso ~p < ~p ==> ~p", 170 [X,Xm,Xm,X+W,Y,Ym,Ym,Y+H,Res]), 171 Res. 172 173inside(Xm, Ym, X, Y, W, H) -> 174 X =< Xm andalso Xm < X+W andalso Y =< Ym andalso Ym < Y+H. 175 176inside_guard(Xm, Ym, X, Y, W, H) when X =< Xm andalso Xm < X+W 177 andalso Y =< Ym andalso Ym < Y+H -> 178 {true,Xm,Ym,X,Y,W,H}; 179inside_guard(Xm, Ym, X, Y, W, H) -> 180 {false,Xm,Ym,X,Y,W,H}. 181 182overlap(Config) when is_list(Config) -> 183 true = overlap(7.0, 2.0, 8.0, 0.5), 184 true = overlap(7.0, 2.0, 8.0, 2.5), 185 true = overlap(7.0, 2.0, 5.3, 2), 186 true = overlap(7.0, 2.0, 0.0, 100.0), 187 188 false = overlap(-1, 2, -35, 0.5), 189 false = overlap(-1, 2, 777, 0.5), 190 false = overlap(-1, 2, 2, 10), 191 false = overlap(2, 10, 12, 55.3), 192 ok. 193 194overlap(Pos1, Len1, Pos2, Len2) -> 195 Res = case Pos1 of 196 Pos1 when (Pos2 =< Pos1 andalso Pos1 < Pos2+Len2) 197 orelse (Pos1 =< Pos2 andalso Pos2 < Pos1+Len1) -> 198 true; 199 Pos1 -> false 200 end, 201 Res = (Pos2 =< Pos1 andalso Pos1 < Pos2+Len2) 202 orelse (Pos1 =< Pos2 andalso Pos2 < Pos1+Len1), 203 Res = case Pos1 of 204 Pos1 when (Pos2 =< Pos1 andalso Pos1 < Pos2+Len2) 205 orelse (Pos1 =< Pos2 andalso Pos2 < Pos1+Len1) -> 206 true; 207 Pos1 -> false 208 end, 209 id(Res). 210 211 212-define(COMB(A,B,C), (A andalso B orelse C)). 213 214combined(Config) when is_list(Config) -> 215 false = comb(false, false, false), 216 true = comb(false, false, true), 217 false = comb(false, true, false), 218 true = comb(false, true, true), 219 220 false = comb(true, false, false), 221 true = comb(true, true, false), 222 true = comb(true, false, true), 223 true = comb(true, true, true), 224 225 false = comb(false, blurf, false), 226 true = comb(false, blurf, true), 227 true = comb(true, true, blurf), 228 229 false = ?COMB(false, false, false), 230 true = ?COMB(false, false, true), 231 false = ?COMB(false, true, false), 232 true = ?COMB(false, true, true), 233 234 false = ?COMB(true, false, false), 235 true = ?COMB(true, true, false), 236 true = ?COMB(true, false, true), 237 true = ?COMB(true, true, true), 238 239 false = ?COMB(false, blurf, false), 240 true = ?COMB(false, blurf, true), 241 true = ?COMB(true, true, blurf), 242 243 ok. 244-undef(COMB). 245 246comb(A, B, C) -> 247 Res = A andalso B orelse C, 248 Res = if 249 A andalso B orelse C -> true; 250 true -> false 251 end, 252 NotRes = if 253 not(A andalso B orelse C) -> true; 254 true -> false 255 end, 256 NotRes = id(not Res), 257 Res = A andalso B orelse C, 258 Res = if 259 A andalso B orelse C -> true; 260 true -> false 261 end, 262 NotRes = id(not Res), 263 Res = if 264 A andalso B orelse C -> true; 265 true -> false 266 end, 267 id(Res). 268 269%% Test that a boolean expression in a case expression is properly 270%% optimized (in particular, that the error behaviour is correct). 271in_case(Config) when is_list(Config) -> 272 edge_rings = in_case_1(1, 1, 1, 1, 1), 273 not_loop = in_case_1(0.5, 1, 1, 1, 1), 274 loop = in_case_1(0.5, 0.9, 1.1, 1, 4), 275 {'EXIT',{badarith,_}} = (catch in_case_1(1, 1, 1, 1, 0)), 276 {'EXIT',{badarith,_}} = (catch in_case_1(1, 1, 1, 1, nan)), 277 {'EXIT',{badarg,_}} = (catch in_case_1(1, 1, 1, blurf, 1)), 278 {'EXIT',{badarith,_}} = (catch in_case_1([nan], 1, 1, 1, 1)), 279 ok. 280 281in_case_1(LenUp, LenDw, LenN, Rotation, Count) -> 282 Res = in_case_1_body(LenUp, LenDw, LenN, Rotation, Count), 283 Res = in_case_1_guard(LenUp, LenDw, LenN, Rotation, Count), 284 Res. 285 286in_case_1_body(LenUp, LenDw, LenN, Rotation, Count) -> 287 case (LenUp/Count > 0.707) and (LenN/Count > 0.707) and 288 (abs(Rotation) > 0.707) of 289 true -> 290 edge_rings; 291 false -> 292 case (LenUp >= 1) or (LenDw >= 1) or 293 (LenN =< 1) or (Count < 4) of 294 true -> 295 not_loop; 296 false -> 297 loop 298 end 299 end. 300 301in_case_1_guard(LenUp, LenDw, LenN, Rotation, Count) -> 302 case (LenUp/Count > 0.707) andalso (LenN/Count > 0.707) andalso 303 (abs(Rotation) > 0.707) of 304 true -> edge_rings; 305 false when LenUp >= 1 orelse LenDw >= 1 orelse 306 LenN =< 1 orelse Count < 4 -> not_loop; 307 false -> loop 308 end. 309 310check(V1, V0) -> 311 if V1 /= V0 -> 312 io:fwrite("error: ~w.\n", [V1]), 313 ct:fail(failed); 314 true -> 315 io:fwrite("ok: ~w.\n", [V1]) 316 end. 317 318echo(X) -> 319 io:fwrite("eval(~w); ",[X]), 320 X. 321 322id(I) -> I. 323