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