| 1 | %%% Copyright (C) Dominic Williams, Nicolas Charpentier |
|---|
| 2 | %%% All rights reserved. |
|---|
| 3 | %%% See file COPYING. |
|---|
| 4 | |
|---|
| 5 | -module (tester_test). |
|---|
| 6 | -export ([run_all/0]). |
|---|
| 7 | -export ([tree/0]). |
|---|
| 8 | -test (run_all). |
|---|
| 9 | |
|---|
| 10 | run_all () -> |
|---|
| 11 | Name = list_to_atom (fixtures: unique_string ()), |
|---|
| 12 | {ok, Host} = inet: gethostname (), |
|---|
| 13 | Host_atom = list_to_atom (Host), |
|---|
| 14 | {ok, Node} = slave: start_link (Host_atom, Name), |
|---|
| 15 | ok = run_all (Node), |
|---|
| 16 | ok = slave: stop (Node). |
|---|
| 17 | |
|---|
| 18 | run_all (Node) -> |
|---|
| 19 | Fun = run_fun (Node), |
|---|
| 20 | ok = fixtures: use_tree (tree (), Fun). |
|---|
| 21 | |
|---|
| 22 | run_fun (Node) -> |
|---|
| 23 | fun (Root, _) -> |
|---|
| 24 | runs_a_test (Node, Root), |
|---|
| 25 | reruns_a_test_when_given_module (Node, Root), |
|---|
| 26 | runs_given_tests (Node, Root), |
|---|
| 27 | runs_given_test_sequence (Node, Root), |
|---|
| 28 | reloads_corrected_module (Node, Root), |
|---|
| 29 | deletes_a_module (Node, Root), |
|---|
| 30 | deletes_a_test_module (Node, Root), |
|---|
| 31 | runs_new_tests_failed_then_successful (Node, Root), |
|---|
| 32 | provides_failed_test_and_location (Node, Root), |
|---|
| 33 | stops (Node, Root), |
|---|
| 34 | ok |
|---|
| 35 | end. |
|---|
| 36 | |
|---|
| 37 | send (Root, Modules, Tester) -> |
|---|
| 38 | Paths = [modules: to_file_name (M, Root) || M <- Modules], |
|---|
| 39 | Binaries = [modules: to_binary (P) || P <- Paths], |
|---|
| 40 | false = lists: any (fun (M) -> code: is_loaded (M) end, Modules), |
|---|
| 41 | Tester ! {run, Binaries}, |
|---|
| 42 | Results = receive_all ([]), |
|---|
| 43 | false = lists: any (fun (M) -> code: is_loaded (M) end, Modules), |
|---|
| 44 | Results. |
|---|
| 45 | |
|---|
| 46 | notify_me () -> |
|---|
| 47 | Self = self (), |
|---|
| 48 | fun (M) -> Self ! M end. |
|---|
| 49 | |
|---|
| 50 | runs_a_test (Node, Root) -> |
|---|
| 51 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 52 | [{2, 0, 0}, {2, 1, 1}, Error, {2, 2, 1}] = send (Root, [eg_test], Tester), |
|---|
| 53 | {badmatch, nok} = dict: fetch (error, Error), |
|---|
| 54 | [{eg_test, nok, 0} | _] = dict: fetch (stack_trace, Error), |
|---|
| 55 | ok. |
|---|
| 56 | |
|---|
| 57 | reruns_a_test_when_given_module (Node, Root) -> |
|---|
| 58 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 59 | [{1, 0, 0}, Error, {1, 1, 0}] = send (Root, [eg_test_of_code], Tester), |
|---|
| 60 | undef = dict: fetch (error, Error), |
|---|
| 61 | Stack_trace = dict: fetch (stack_trace, Error), |
|---|
| 62 | [{eg_code, ok, []}, {eg_test_of_code, ok, 0} | _] = Stack_trace, |
|---|
| 63 | [{1, 0, 0}, {1, 1, 1}] = send (Root, [eg_code], Tester), |
|---|
| 64 | ok. |
|---|
| 65 | |
|---|
| 66 | runs_given_test_sequence (Node, Root) -> |
|---|
| 67 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 68 | [{2, 0, 0}, {2, 1, 1}, _, {2, 2, 1}] = send (Root, [eg_test], Tester), |
|---|
| 69 | [{2, 0, 0}, _, {2, 1, 0}, {2, 2, 1}] = send (Root, [eg_code], Tester), |
|---|
| 70 | Result = send (Root, [eg_test_of_code], Tester), |
|---|
| 71 | [{3, 0, 0}, {3, 1, 1}, _, {3, 2, 1}, {3, 3, 2}] = Result, |
|---|
| 72 | ok. |
|---|
| 73 | |
|---|
| 74 | runs_given_tests (Node, Root) -> |
|---|
| 75 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 76 | Modules = [eg_test, eg_code, eg_test_of_code], |
|---|
| 77 | Result = send (Root, Modules, Tester), |
|---|
| 78 | [{3, 0, 0}, {3, 1, 1}, _, {3, 2, 1}, {3, 3, 2}] = Result, |
|---|
| 79 | ok. |
|---|
| 80 | |
|---|
| 81 | reloads_corrected_module (Node, _) -> |
|---|
| 82 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 83 | Binary = modules: forms_to_binary (eg_test_form ("nok")), |
|---|
| 84 | Tester ! {run, [Binary]}, |
|---|
| 85 | [{1, 0, 0}, Error, {1, 1, 0}] = receive_all ([]), |
|---|
| 86 | Correct_binary = modules: forms_to_binary (eg_test_form ("ok")), |
|---|
| 87 | Tester ! {run, [Correct_binary]}, |
|---|
| 88 | [{1, 0, 0}, {1, 1, 1}] = receive_all ([]), |
|---|
| 89 | Tester ! {run, [Binary]}, |
|---|
| 90 | [{1, 0, 0}, Error, {1, 1, 0}] = receive_all ([]), |
|---|
| 91 | ok. |
|---|
| 92 | |
|---|
| 93 | deletes_a_module (Node, Root) -> |
|---|
| 94 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 95 | [{1, 0, 0}, {1, 1, 1}] = send (Root, [eg_test_of_code], Tester), |
|---|
| 96 | Tester ! {delete,[eg_code]}, |
|---|
| 97 | [{1, 0, 0}, Error, {1, 1, 0}] = receive_all ([]), |
|---|
| 98 | undef = dict: fetch (error, Error), |
|---|
| 99 | [{eg_code, ok, []} | _] = dict: fetch (stack_trace, Error), |
|---|
| 100 | [{1, 0, 0}, {1, 1, 1}] = send (Root, [eg_code], Tester), |
|---|
| 101 | ok. |
|---|
| 102 | |
|---|
| 103 | deletes_a_test_module (Node, Root) -> |
|---|
| 104 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 105 | [{1, 0, 0}, {1, 1, 1}] = send (Root, [eg_test_of_code], Tester), |
|---|
| 106 | Tester ! {delete,[eg_test_of_code]}, |
|---|
| 107 | [{0, 0, 0}] = receive_all ([]), |
|---|
| 108 | [{1, 0, 0}, {1, 1, 1}] = send (Root, [eg_test_of_code], Tester), |
|---|
| 109 | ok. |
|---|
| 110 | |
|---|
| 111 | runs_new_tests_failed_then_successful (Node, Root) -> |
|---|
| 112 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 113 | Modules = [eg_code, eg_test_of_code_failed], |
|---|
| 114 | Result = send (Root, Modules, Tester), |
|---|
| 115 | [{1, 0, 0}, Error, {1, 1, 0}] = Result, |
|---|
| 116 | {badmatch, bad_eg_code} = dict: fetch (error, Error), |
|---|
| 117 | Result_after_new_test = send (Root, [eg_test_not_exports], Tester), |
|---|
| 118 | [{2, 0, 0}, {2, 1, 1}, Error, {2, 2, 1}] = Result_after_new_test, |
|---|
| 119 | New_run = send (Root, [eg_test_of_code], Tester), |
|---|
| 120 | [{3, 0, 0}, {3, 1, 1}, Error, {3, 2, 1}, {3, 3, 2}] = New_run, |
|---|
| 121 | ok. |
|---|
| 122 | |
|---|
| 123 | provides_failed_test_and_location (Node, Root) -> |
|---|
| 124 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 125 | [{2, 0, 0}, {2, 1, 1}, Error, {2, 2, 1}] = send (Root, [eg_test], Tester), |
|---|
| 126 | Filename = filename: join (Root, "eg_test.erl"), |
|---|
| 127 | {eg_test, nok, 0, Filename, 6} = dict: fetch (location, Error), |
|---|
| 128 | ok. |
|---|
| 129 | |
|---|
| 130 | stops (Node, Root) -> |
|---|
| 131 | Tester = spawn_link (tester, init, [notify_me (), Node]), |
|---|
| 132 | Modules = [eg_code, eg_test_of_code], |
|---|
| 133 | Paths = [modules: to_file_name (M, Root) || M <- Modules], |
|---|
| 134 | Binaries = [modules: to_binary (P) || P <- Paths], |
|---|
| 135 | Tester ! {run, Binaries}, |
|---|
| 136 | Tester ! {self (), stop}, |
|---|
| 137 | Results = receive_all ([]), |
|---|
| 138 | [{1, 0, 0}, {1, 1, 1}] = Results, |
|---|
| 139 | ok = receive {Tester, bye} -> ok after 100 -> timeout end. |
|---|
| 140 | |
|---|
| 141 | receive_all (Ms) -> |
|---|
| 142 | receive |
|---|
| 143 | {Run, Run, Passed} -> |
|---|
| 144 | lists: reverse ([{Run, Run, Passed} | Ms]); |
|---|
| 145 | M -> |
|---|
| 146 | receive_all ([M | Ms]) |
|---|
| 147 | end. |
|---|
| 148 | |
|---|
| 149 | eg_test_form (String) -> |
|---|
| 150 | [{attribute,1,file,{"./eg_test.erl",1}}, |
|---|
| 151 | {attribute,1,module,eg_test}, |
|---|
| 152 | {attribute,2,export,[{ok,0}]}, |
|---|
| 153 | {attribute,3,test,exports}, |
|---|
| 154 | {function,4, |
|---|
| 155 | ok, |
|---|
| 156 | 0, |
|---|
| 157 | [{clause,4, |
|---|
| 158 | [], |
|---|
| 159 | [], |
|---|
| 160 | [{match,5, |
|---|
| 161 | {atom,5,ok}, |
|---|
| 162 | {call,5, |
|---|
| 163 | {atom,5,list_to_atom}, |
|---|
| 164 | [{string,5,String}]}}]}]}, |
|---|
| 165 | {eof,7}]. |
|---|
| 166 | |
|---|
| 167 | tree () -> |
|---|
| 168 | [{file, "eg_test.erl", |
|---|
| 169 | ["-module (eg_test).", |
|---|
| 170 | "-test (exports).", |
|---|
| 171 | "-export ([ok/0, nok/0]).", |
|---|
| 172 | "ok () ->", |
|---|
| 173 | " ok = list_to_existing_atom (\"ok\").", |
|---|
| 174 | "nok () ->", |
|---|
| 175 | " ok = list_to_existing_atom (\"nok\")."]}, |
|---|
| 176 | {file, "eg_test_of_code.erl", |
|---|
| 177 | ["-module (eg_test_of_code).", |
|---|
| 178 | "-test (exports).", |
|---|
| 179 | "-export ([ok/0]).", |
|---|
| 180 | "ok () ->", |
|---|
| 181 | " ok = eg_code: ok ()."]}, |
|---|
| 182 | {file, "eg_code.erl", |
|---|
| 183 | ["-module (eg_code).", |
|---|
| 184 | "-export ([ok/0]).", |
|---|
| 185 | "ok () ->", |
|---|
| 186 | " ok."]}, |
|---|
| 187 | {file, "eg_test_of_code_failed.erl", |
|---|
| 188 | ["-module (eg_test_of_code_failed).", |
|---|
| 189 | "-test (exports).", |
|---|
| 190 | "-export ([ok/0]).", |
|---|
| 191 | "", |
|---|
| 192 | "ok () ->", |
|---|
| 193 | " Result = eg_code: ok (),", |
|---|
| 194 | " Result = bad_eg_code."]}, |
|---|
| 195 | {file, "eg_test_not_exports.erl", |
|---|
| 196 | ["-module (eg_test_not_exports).", |
|---|
| 197 | "-test (ok).", |
|---|
| 198 | "-export ([ok/0, nok/0]).", |
|---|
| 199 | "ok () ->", |
|---|
| 200 | " ok = list_to_existing_atom (\"ok\").", |
|---|
| 201 | "nok () ->", |
|---|
| 202 | " ok = list_to_existing_atom (\"nok\")."]} |
|---|
| 203 | ]. |
|---|
| 204 | |
|---|