Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Variables used in js-test.js assertions. | |
| 2 var exceptionName; | |
| 3 var exceptionMessage; | |
| 4 var exceptionProto; | |
| 5 var closeEvent; | |
| 6 | |
| 7 // Constants. | |
| 8 const invalidAccessErr = "InvalidAccessError"; | |
| 9 const syntaxErr = "SyntaxError"; | |
| 10 const normalClosure = 1000; | |
| 11 const abnormalClosure = 1006; | |
| 12 const url = "ws://127.0.0.1:8880/close"; | |
| 13 const ws_handlers = ["onopen", "onerror", "onclose", "onmessage"]; | |
| 14 | |
| 15 // An explicit timeout is used so that we can capture the test output. | |
| 16 var timeout; | |
| 17 | |
| 18 const badCodesTestCodes = [ | |
| 19 999, 1001, 2999, 5000, 65536 + 1000, 0x100000000 + 1000, 2999.9, NaN, "0", " 100", 1/0, -1/0, 0/0, | |
| 20 ]; | |
| 21 | |
| 22 const badReasonTestReasons = [ | |
| 23 "123456789012345678901234567890123456789012345678901234567890123456789012345 6789012345678901234567890123456789012345678901234", // 124 Byte | |
| 24 "123456789012345678901234567890123456789012345678901234567890123456789012345 67890123456789012345678901234567890123456789012\u00a9", // length is 123, but 12 4 Byte in UTF-8 | |
| 25 ]; | |
| 26 | |
| 27 function createFailHandler(name, ws, reject) | |
| 28 { | |
| 29 return function () { | |
|
yhirano
2015/02/27 06:26:44
Please be consistent whether you put a space after
Adam Rice
2015/02/27 09:34:28
Originally this test used function () {...} style,
| |
| 30 removeAllHandlers(ws); | |
| 31 reject(name + " was called."); | |
| 32 }; | |
| 33 } | |
| 34 | |
| 35 function setDefaultHandlers(ws, reject) | |
| 36 { | |
| 37 ws_handlers.forEach(function (handler) { | |
| 38 ws[handler] = createFailHandler(handler, ws, reject); | |
| 39 }); | |
| 40 } | |
| 41 | |
| 42 // Ensure that the WebSocket can be garbage collected. | |
| 43 function removeAllHandlers(ws) | |
| 44 { | |
| 45 ws_handlers.forEach(function (handler) { | |
| 46 ws[handler] = undefined; | |
| 47 }); | |
| 48 } | |
| 49 | |
| 50 // Verify that close() throws an exception when an invalid close code is passed. | |
| 51 function badCodesTest() | |
| 52 { | |
| 53 return new Promise(function (resolve, reject) { | |
| 54 debug("badCodesTest: started"); | |
| 55 var ws = new WebSocket(url); | |
| 56 setDefaultHandlers(ws, reject); | |
| 57 for (var id = 0; id < badCodesTestCodes.length; ++id) { | |
|
yhirano
2015/02/27 06:26:44
[optional] You can use |for (var test_code of badC
Adam Rice
2015/02/27 09:34:28
I didn't know that worked yet. Thanks.
| |
| 58 var test_code = badCodesTestCodes[id]; | |
| 59 debug("badCodesTest: " + test_code); | |
| 60 try { | |
| 61 ws.close(test_code); | |
| 62 reject("Exception not thrown for code " + test_code); | |
| 63 return; | |
| 64 } catch (e) { | |
| 65 exceptionName = e.name; | |
| 66 exceptionMessage = e.message; | |
| 67 exceptionProto = Object.getPrototypeOf(e); | |
| 68 shouldBeTrue("exceptionProto === DOMException.prototype"); | |
| 69 shouldBeEqualToString("exceptionName", invalidAccessErr); | |
| 70 var expectedCode = test_code; | |
| 71 if (!expectedCode) | |
| 72 expectedCode = 0; | |
| 73 else if (expectedCode > 65535) | |
| 74 expectedCode = 65535; | |
| 75 else if (expectedCode < 0) | |
| 76 expectedCode = 0; | |
| 77 expectedCode = Math.floor(expectedCode); | |
| 78 shouldBeEqualToString("exceptionMessage", "Failed to execute 'cl ose' on 'WebSocket': The code must be either 1000, or between 3000 and 4999. " + expectedCode + " is neither."); | |
| 79 } | |
| 80 } | |
| 81 removeAllHandlers(ws); | |
| 82 resolve(); | |
| 83 }); | |
| 84 } | |
| 85 | |
| 86 // Verify that passing a valid code does not throw an exception. | |
| 87 function goodCodeTest() | |
| 88 { | |
| 89 return new Promise(function (resolve, reject) { | |
| 90 debug("goodCodeTest: started"); | |
| 91 var ws = new WebSocket(url); | |
| 92 setDefaultHandlers(ws, reject); | |
| 93 ws.onclose = function (e) | |
| 94 { | |
| 95 closeEvent = e; | |
| 96 shouldBeEqualToNumber("closeEvent.code", abnormalClosure); | |
| 97 resolve(); | |
| 98 }; | |
| 99 ws.onerror = function() | |
| 100 { | |
| 101 testPassed("onerror was called."); | |
| 102 }; | |
| 103 ws.close(1000.0); | |
| 104 }); | |
| 105 } | |
| 106 | |
| 107 // Verify that unpaired surrogates in the reason string are converted to U+FFFD | |
| 108 // before sending to the remote server. | |
| 109 function invalidUnicodeReasonTest() | |
| 110 { | |
| 111 return new Promise(function (resolve, reject) { | |
| 112 debug("invalidUnicodeReasonTest: started"); | |
| 113 var ws = new WebSocket(url); | |
|
yhirano
2015/02/27 06:26:44
+setDefaultHandlers
Adam Rice
2015/02/27 09:34:28
Done.
| |
| 114 ws.onopen = function() { | |
| 115 // 0xD834 is an unpaired surrogate. | |
| 116 var invalidString = String.fromCharCode(0xD834); | |
| 117 ws.close(1000, invalidString); | |
| 118 }; | |
| 119 ws.onclose = function(e) { | |
| 120 closeEvent = e; | |
| 121 shouldBeTrue("closeEvent.wasClean"); | |
| 122 shouldBeEqualToString("closeEvent.reason", "\uFFFD"); | |
| 123 resolve(); | |
| 124 }; | |
| 125 }); | |
| 126 } | |
| 127 | |
| 128 // Verify that invalid reason strings passed to close() result in an exception | |
| 129 // being thrown. | |
| 130 function badReasonTest() | |
| 131 { | |
| 132 return new Promise(function (resolve, reject) { | |
| 133 debug("badReasonTest: started"); | |
| 134 var ws = new WebSocket(url); | |
| 135 setDefaultHandlers(ws, reject); | |
| 136 for (var id = 0; id < badReasonTestReasons.length; ++id) { | |
| 137 var test_reason = badReasonTestReasons[id]; | |
| 138 debug("badReasonTest: " + test_reason); | |
| 139 try { | |
| 140 ws.close(normalClosure, test_reason); | |
| 141 reject("Exception not thrown for bad reason " + test_reason); | |
| 142 return; | |
| 143 } catch (e) { | |
| 144 exceptionName = e.name; | |
| 145 exceptionProto = Object.getPrototypeOf(e); | |
| 146 shouldBeTrue("exceptionProto === DOMException.prototype"); | |
| 147 shouldBeEqualToString("exceptionName", syntaxErr); | |
| 148 } | |
| 149 } | |
| 150 removeAllHandlers(ws); | |
| 151 resolve(); | |
| 152 }); | |
| 153 } | |
| 154 | |
| 155 // Verify that a valid reason code passed to close() does not result in an | |
| 156 // exception. | |
| 157 function goodReasonTest() | |
| 158 { | |
| 159 return new Promise(function (resolve, reject) { | |
| 160 debug("goodReasonTest: started"); | |
| 161 var ws = new WebSocket(url); | |
|
yhirano
2015/02/27 06:26:44
+setDefaultHandlers
Adam Rice
2015/02/27 09:34:28
Done.
| |
| 162 ws.onclose = function (e) | |
| 163 { | |
| 164 closeEvent = e; | |
| 165 shouldBeEqualToNumber("closeEvent.code", abnormalClosure); | |
| 166 resolve(); | |
| 167 }; | |
| 168 ws.onerror = function() | |
| 169 { | |
| 170 testPassed("onerror was called."); | |
| 171 }; | |
| 172 // 123 byte reason should not throw. | |
| 173 ws.close(normalClosure, "12345678901234567890123456789012345678901234567 8901234567890123456789012345678901234567890123456789012345678901234567890123"); | |
| 174 }); | |
| 175 } | |
| 176 | |
| 177 // Verify that valid close codes and reasons are correctly send to the | |
| 178 // WebSocket server. | |
| 179 function codeAndReasonTest() | |
| 180 { | |
| 181 const codes = [ | |
| 182 1000, | |
| 183 3000, | |
| 184 4000, | |
| 185 4999 | |
| 186 ]; | |
| 187 const reasons = [ | |
| 188 "OK, Bye!", | |
| 189 "3000", | |
| 190 "code is 4000", | |
| 191 "\u00a9 Google" | |
| 192 ]; | |
| 193 return new Promise(function(resolve, reject) { | |
| 194 debug("codeAndReasonTest: started"); | |
| 195 // Tests are run in series to produce deterministic output. | |
| 196 var promise = Promise.resolve(); | |
| 197 for (var id = 0; id < codes.length; ++id) { | |
| 198 promise = promise.then(codeAndReasonSingleCase(codes[id], reasons[id ])); | |
| 199 } | |
| 200 promise.then(resolve); | |
| 201 }); | |
| 202 } | |
| 203 | |
| 204 // (Return a function which returns a Promise to) handle a single code/reason | |
| 205 // pair for the codeAndReasonTest. | |
| 206 function codeAndReasonSingleCase(test_code, test_reason) { | |
| 207 return function() { | |
| 208 return new Promise(function (resolve, reject) { | |
| 209 debug("codeAndReasonTest: " + test_code + ", '" + test_reason + "'") ; | |
| 210 var ws = new WebSocket(url); | |
| 211 setDefaultHandlers(ws, reject); | |
| 212 ws.onopen = function () | |
| 213 { | |
| 214 ws.close(test_code, test_reason); | |
| 215 }; | |
| 216 ws.onclose = function (e) | |
| 217 { | |
| 218 closeEvent = e; | |
| 219 shouldBeTrue("closeEvent.wasClean"); | |
| 220 shouldBeEqualToNumber("closeEvent.code", test_code); | |
| 221 shouldBeEqualToString("closeEvent.reason", test_reason); | |
| 222 resolve(); | |
| 223 }; | |
| 224 }); | |
| 225 }; | |
| 226 } | |
| 227 | |
| 228 function cleanup() { | |
| 229 clearTimeout(timeout); | |
| 230 finishJSTest(); | |
| 231 } | |
| 232 | |
| 233 function onTimeout() { | |
| 234 handleRejection("Timeout"); | |
| 235 } | |
| 236 | |
| 237 function handleRejection(reason) { | |
| 238 if (reason instanceof Error) { | |
| 239 // Get a stack trace if an exception fired. | |
| 240 testFailed(reason.stack); | |
| 241 } else { | |
| 242 testFailed(reason); | |
| 243 } | |
| 244 cleanup(); | |
| 245 } | |
| 246 | |
| 247 function testClose() { | |
| 248 // Set an explicit timeout in order to keep text output on failure. | |
| 249 timeout = setTimeout(onTimeout, 5000); | |
| 250 // Tests are run in series to produce deterministic output. | |
| 251 badCodesTest() | |
| 252 .then(goodCodeTest) | |
| 253 .then(invalidUnicodeReasonTest) | |
| 254 .then(badReasonTest) | |
| 255 .then(goodReasonTest) | |
| 256 .then(codeAndReasonTest) | |
| 257 .then(cleanup) | |
| 258 .catch(handleRejection); | |
| 259 } | |
| OLD | NEW |