1 module tests.server; 2 3 import unit_threaded; 4 import cucumber.server; 5 import vibe.data.json; 6 7 8 void testFail() { 9 //handleRequest!__MODULE__("fsafs").shouldThrow!JSONException; 10 shouldEqual(handleRequest!__MODULE__(`["fsafs"]`), `["fail"]`); 11 shouldEqual(handleRequest!__MODULE__(`["foo"]`), `["fail"]`); 12 } 13 14 void testNoMatches() { 15 shouldEqual(handleRequest!__MODULE__(`["step_matches",{"name_to_match":"foo"}]`), `["success",[]]`); 16 } 17 18 private string[] funcCalls; 19 20 @Match(`^we're wired$`) 21 void match1() { 22 funcCalls ~= "match1"; 23 } 24 25 @Match(`^2nd match$`) 26 void match2() { 27 funcCalls ~= "match2"; 28 } 29 30 @Match(`^\drd .+`) 31 void match3() { 32 funcCalls ~= "match3"; 33 } 34 35 void checkSuccessJson(string str, in string id, in string[] args) { 36 import std.algorithm; 37 auto json = parseJson(str); 38 shouldEqual(json[0], "success"); 39 auto obj = json[1][0]; 40 shouldEqual(obj["id"], id); 41 string[] objArgs; 42 foreach(arg; obj["args"]) 43 objArgs ~= arg.toString; 44 shouldEqual(objArgs, args); 45 } 46 47 @SingleThreaded 48 void testMatchesNoDetails() { 49 checkSuccessJson(handleRequest!__MODULE__(`["step_matches",{"name_to_match":"we're wired"}]`), 50 "1", []); 51 checkSuccessJson(handleRequest!__MODULE__(`["step_matches",{"name_to_match":"we're wired"}]`), 52 "1", []); 53 checkSuccessJson(handleRequest!__MODULE__(`["step_matches",{"name_to_match":"we're wired"}]`), 54 "1", []); 55 checkSuccessJson(handleRequest!__MODULE__(`["step_matches",{"name_to_match":"2nd match"}]`), 56 "2", []); 57 checkSuccessJson(handleRequest!__MODULE__(`["step_matches",{"name_to_match":"3rd match"}]`), 58 "3", []); 59 60 } 61 62 @SingleThreaded 63 void testMatchesDetails() { 64 { 65 auto reply = handleRequest!__MODULE__(`["step_matches",{"name_to_match":"we're wired"}]`, Yes.details); 66 const json = parseJson(reply); //reply can't be const 67 writelnUt("json is ", json); 68 69 shouldEqual(json[0].get!string, "success"); 70 shouldEqual(json[1].length, 1); 71 72 shouldEqual(json[1][0]["id"].to!int, 1); 73 shouldEqual(json[1][0]["args"].length.to!int, 0); 74 shouldEqual(json[1][0]["source"].to!string, "tests.server.match1:19"); 75 shouldEqual(json[1][0]["regexp"].to!string, "^we're wired$"); 76 } 77 { 78 auto reply = handleRequest!__MODULE__(`["step_matches",{"name_to_match":"2nd match"}]`, Yes.details); 79 const json = parseJson(reply); //reply can't be const 80 writelnUt("json is ", json); 81 82 shouldEqual(json[0].get!string, "success"); 83 shouldEqual(json[1].length, 1); 84 85 shouldEqual(json[1][0]["id"].to!int, 2); 86 shouldEqual(json[1][0]["args"].length.to!int, 0); 87 shouldEqual(json[1][0]["source"].to!string, "tests.server.match2:24"); 88 shouldEqual(json[1][0]["regexp"].to!string, "^2nd match$"); 89 } 90 } 91 92 private auto jsonReply(string request) { 93 auto reply = handleRequest!__MODULE__(request); 94 return parseJson(reply); 95 } 96 97 @Match(`das pending1`) 98 void pendingFunc1() { 99 funcCalls ~= "pending1"; 100 pending("I'll do it later"); 101 } 102 103 @Match(`das pending2`) 104 void pendingFunc2() { 105 funcCalls ~= "pending2"; 106 pending("But I'm le tired"); 107 } 108 109 110 @SingleThreaded 111 void testInvokePending() { 112 { 113 const matchesReply = jsonReply(`["step_matches",{"name_to_match":"das pending1"}]`); 114 const id = matchesReply[1][0]["id"].to!string; 115 const beginReply = jsonReply(`["begin_scenario"]`); 116 shouldEqual(beginReply.toString(), `["success"]`); 117 118 funcCalls = []; 119 const invokeReply = jsonReply(`["invoke", {"id": "` ~ id ~ `", "args": []}]`); 120 shouldEqual(funcCalls, ["pending1"]); 121 shouldEqual(invokeReply[0], "pending"); 122 shouldEqual(invokeReply[1], "I'll do it later"); 123 } 124 { 125 const matchesReply = jsonReply(`["step_matches",{"name_to_match":"das pending2"}]`); 126 const id = matchesReply[1][0]["id"].to!string; 127 const beginReply = jsonReply(`["begin_scenario"]`); 128 shouldEqual(beginReply.toString(), `["success"]`); 129 130 funcCalls = []; 131 const invokeReply = jsonReply(`["invoke", {"id": "` ~ id ~ `", "args": []}]`); 132 shouldEqual(funcCalls, ["pending2"]); 133 shouldEqual(invokeReply[0], "pending"); 134 shouldEqual(invokeReply[1], "But I'm le tired"); 135 } 136 } 137 138 @SingleThreaded 139 void testInvokePass() { 140 const matchesReply = jsonReply(`["step_matches",{"name_to_match":"we're wired"}]`); 141 writelnUt("Reply: ", matchesReply); 142 143 const beginReply = jsonReply(`["begin_scenario"]`); 144 shouldEqual(beginReply.toString(), `["success"]`); 145 146 funcCalls = []; 147 const id = matchesReply[1][0]["id"].to!string; 148 const invokeReply = jsonReply(`["invoke", {"id": "` ~ id ~ `", "args": []}]`); 149 writelnUt("Reply: ", invokeReply); 150 151 shouldEqual(funcCalls, ["match1"]); 152 shouldEqual(invokeReply[0], "success"); 153 shouldEqual(invokeReply.length, 1); 154 155 const endReply = jsonReply(`["end_scenario"]`); 156 shouldEqual(endReply.toString(), `["success"]`); 157 } 158 159 class TestException: Exception { 160 this(string msg) { 161 super(msg); 162 } 163 } 164 165 @Given(`oops gonna fail`) 166 void gonnaFail() { 167 funcCalls ~= "gonna fail"; 168 throw new TestException("I did it again"); 169 } 170 171 @SingleThreaded 172 void testInvokeFail() { 173 const matchesReply = jsonReply(`["step_matches",{"name_to_match":"oops gonna fail"}]`); 174 writelnUt("Reply: ", matchesReply); 175 176 const beginReply = jsonReply(`["begin_scenario"]`); 177 shouldEqual(beginReply.toString(), `["success"]`); 178 179 funcCalls = []; 180 const id = matchesReply[1][0]["id"].to!string; 181 const invokeReply = jsonReply(`["invoke", {"id": "` ~ id ~ `", "args": []}]`); 182 writelnUt("Reply: ", invokeReply); 183 184 writelnUt("Start of the checks"); 185 shouldEqual(funcCalls, ["gonna fail"]); 186 shouldEqual(invokeReply.length, 2); 187 shouldEqual(invokeReply[0], "fail"); 188 shouldEqual(invokeReply[1]["message"].to!string, "I did it again"); 189 shouldEqual(invokeReply[1]["exception"].to!string, "tests.server.TestException"); 190 191 const endReply = jsonReply(`["end_scenario"]`); 192 shouldEqual(endReply.toString(), `["success"]`); 193 }