| OLD | NEW |
| (Empty) |
| 1 var localStorage; | |
| 2 var document; | |
| 3 var window; | |
| 4 var XMLHttpRequest; | |
| 5 var lastCreatedXhr; | |
| 6 | |
| 7 function testGetSetValue() { | |
| 8 localStorage = new LocalStorageFake(); | |
| 9 GM_setValue('string', 'value'); | |
| 10 assert('value', GM_getValue('string')); | |
| 11 GM_setValue('integer', 123); | |
| 12 assert(123, GM_getValue('integer')); | |
| 13 GM_setValue('boolean', true); | |
| 14 assert(true, GM_getValue('boolean')); | |
| 15 | |
| 16 assert(undefined, GM_getValue('notset')); | |
| 17 assert('default', GM_getValue('notset', 'default')); | |
| 18 | |
| 19 // illegal values | |
| 20 assertThrow(function() { | |
| 21 GM_setValue('illegal value', null); | |
| 22 }); | |
| 23 assertThrow(function() { | |
| 24 GM_setValue('illegal value', 1.5); | |
| 25 }); | |
| 26 } | |
| 27 | |
| 28 function testDeleteValue() { | |
| 29 localStorage = new LocalStorageFake(); | |
| 30 GM_setValue('delete', 'value'); | |
| 31 assert('value', GM_getValue('delete')); | |
| 32 GM_deleteValue('delete'); | |
| 33 assert(undefined, GM_getValue('delete')); | |
| 34 GM_deleteValue('notset'); | |
| 35 } | |
| 36 | |
| 37 function testListValues() { | |
| 38 localStorage = new LocalStorageFake(); | |
| 39 var a = GM_listValues(); | |
| 40 assert(0, a.length); | |
| 41 | |
| 42 GM_setValue('one', 'first'); | |
| 43 a = GM_listValues(); | |
| 44 assert(1, a.length); | |
| 45 assert('one', a[0]); | |
| 46 | |
| 47 GM_setValue('two', 'second'); | |
| 48 a = GM_listValues(); | |
| 49 | |
| 50 // Test that keys that are not namespaced can't be read. | |
| 51 localStorage.setItem('three', 'third'); | |
| 52 assert(2, a.length); | |
| 53 assert(true, a.indexOf('one') >= 0); | |
| 54 assert(true, a.indexOf('two') >= 0); | |
| 55 } | |
| 56 | |
| 57 function testGetResourceURL() { | |
| 58 assertThrow(function() { | |
| 59 var resource = GM_getResourceURL('urlResourceName'); | |
| 60 }); | |
| 61 } | |
| 62 | |
| 63 function testGetResourceText() { | |
| 64 assertThrow(function() { | |
| 65 var resource = GM_getResourceText('textResourceName'); | |
| 66 }); | |
| 67 } | |
| 68 | |
| 69 function testAddStyle() { | |
| 70 var documentElement = new ElementFake(''); | |
| 71 var head = new ElementFake('head'); | |
| 72 document = new DocumentFake(documentElement, head); | |
| 73 var css = 'color: #decaff;'; | |
| 74 GM_addStyle(css); | |
| 75 assert(0, documentElement.childNodes.length); | |
| 76 assert(1, head.childNodes.length); | |
| 77 var style = head.childNodes[0]; | |
| 78 assert("style", style.tagName); | |
| 79 assert("text/css", style.type); | |
| 80 assert(1, style.childNodes.length); | |
| 81 var textNode = style.childNodes[0]; | |
| 82 assert(css, textNode.text); | |
| 83 | |
| 84 document = new DocumentFake(documentElement, null); | |
| 85 GM_addStyle(css); | |
| 86 assert(1, documentElement.childNodes.length); | |
| 87 var style = documentElement.childNodes[0]; | |
| 88 assert("text/css", style.type); | |
| 89 assert(1, style.childNodes.length); | |
| 90 textNode = style.childNodes[0]; | |
| 91 assert(css, textNode.text); | |
| 92 } | |
| 93 | |
| 94 function testXmlhttpRequest() { | |
| 95 XMLHttpRequest = XMLHttpRequestFake; | |
| 96 var url = 'http://example.com'; | |
| 97 | |
| 98 var onLoadCallback = function(state) { | |
| 99 onLoadCallbackResponseState = state; | |
| 100 }; | |
| 101 var onErrorCallback = function(state) { | |
| 102 onErrorCallbackResponseState = state; | |
| 103 }; | |
| 104 var onReadyStateChangeCallback = function(state) { | |
| 105 onReadyStateChangeCallbackResponseState = state; | |
| 106 }; | |
| 107 | |
| 108 var details = { | |
| 109 onload: onLoadCallback, | |
| 110 onerror: onErrorCallback, | |
| 111 onreadystatechange: onReadyStateChangeCallback, | |
| 112 method: 'GET', | |
| 113 url: url, | |
| 114 overrideMimeType: 'text/html', | |
| 115 headers: { | |
| 116 'X-Header': 'foo' | |
| 117 }, | |
| 118 data: 'data' | |
| 119 }; | |
| 120 | |
| 121 GM_xmlhttpRequest(details); | |
| 122 var xhr = lastCreatedXhr; | |
| 123 | |
| 124 assert('GET', xhr.openedMethod); | |
| 125 assert(url, xhr.openedUrl); | |
| 126 assert('text/html', xhr.overrideMimeType); | |
| 127 assert('foo', xhr.requestHeaders['X-Header']); | |
| 128 assert('data', xhr.sentBody); | |
| 129 | |
| 130 xhr.responseText = 'foo'; | |
| 131 xhr.responseHeaders['X-Response'] = 'foo'; | |
| 132 xhr.status = 200; | |
| 133 xhr.statusText = 'OK'; | |
| 134 | |
| 135 xhr.readyState = 1; | |
| 136 xhr.onreadystatechange(); | |
| 137 var state = onReadyStateChangeCallbackResponseState; | |
| 138 assert(xhr.responseText, state.responseText); | |
| 139 assert(xhr.readyState, state.readyState); | |
| 140 assert('', state.responseHeaders); | |
| 141 assert(0, state.status); | |
| 142 assert('', state.statusText); | |
| 143 assert('', state.finalUrl); | |
| 144 | |
| 145 xhr.readyState = 0; | |
| 146 xhr.onerror(); | |
| 147 state = onErrorCallbackResponseState; | |
| 148 assert(xhr.responseText, state.responseText); | |
| 149 assert(xhr.readyState, state.readyState); | |
| 150 assert('', state.responseHeaders); | |
| 151 assert(0, state.status); | |
| 152 assert('', state.statusText); | |
| 153 assert('', state.finalUrl); | |
| 154 | |
| 155 xhr.readyState = 4; | |
| 156 xhr.onload(); | |
| 157 state = onLoadCallbackResponseState; | |
| 158 assert(xhr.responseText, state.responseText); | |
| 159 assert(xhr.readyState, state.readyState); | |
| 160 assert('X-Response: foo\r\n', state.responseHeaders); | |
| 161 assert(xhr.status, state.status); | |
| 162 assert(xhr.statusText, state.statusText); | |
| 163 assert(url, state.finalUrl); | |
| 164 } | |
| 165 | |
| 166 function testRegisterMenuCommand() { | |
| 167 assertThrow(function() { | |
| 168 GM_registerMenuCommand('name', function() {}, 'a', '', 'a'); | |
| 169 }); | |
| 170 } | |
| 171 | |
| 172 function testOpenInTab() { | |
| 173 var mockWindow = { | |
| 174 open: function(url, name, opt_options) { | |
| 175 this.openedUrl = url; | |
| 176 this.openedName = name; | |
| 177 this.openedOptions = opt_options; | |
| 178 } | |
| 179 }; | |
| 180 window = mockWindow; | |
| 181 var url = 'http://example.com'; | |
| 182 GM_openInTab(url); | |
| 183 assert(mockWindow.openedUrl, url); | |
| 184 } | |
| 185 | |
| 186 function testLog() { | |
| 187 var mockWindow = { | |
| 188 console: { | |
| 189 message: null, | |
| 190 log: function(message) { | |
| 191 this.message = message; | |
| 192 } | |
| 193 } | |
| 194 }; | |
| 195 window = mockWindow; | |
| 196 var message = 'hello world'; | |
| 197 GM_log(message); | |
| 198 assert(message, mockWindow.console.message); | |
| 199 } | |
| 200 | |
| 201 function LocalStorageFake() { | |
| 202 this.map_ = {}; | |
| 203 this.keys_ = []; | |
| 204 } | |
| 205 LocalStorageFake.prototype = { | |
| 206 length: 0, | |
| 207 key: function(index) { | |
| 208 if (index >= this.length) { | |
| 209 throw new Error('INDEX_SIZE_ERR'); | |
| 210 } | |
| 211 return this.keys_[index]; | |
| 212 }, | |
| 213 getItem: function(key) { | |
| 214 if (key in this.map_) { | |
| 215 return this.map_[key]; | |
| 216 } | |
| 217 return null; | |
| 218 }, | |
| 219 setItem: function(key, data) { | |
| 220 this.map_[key] = data; | |
| 221 this.updateKeys_(); | |
| 222 }, | |
| 223 removeItem: function(key) { | |
| 224 delete this.map_[key]; | |
| 225 this.updateKeys_(); | |
| 226 }, | |
| 227 clear: function() { | |
| 228 this.map_ = {}; | |
| 229 this.updateKeys_(); | |
| 230 }, | |
| 231 updateKeys_: function() { | |
| 232 var keys = []; | |
| 233 for (var key in this.map_) { | |
| 234 keys.push(key); | |
| 235 } | |
| 236 this.keys_ = keys; | |
| 237 this.length = keys.length; | |
| 238 } | |
| 239 } | |
| 240 | |
| 241 function DocumentFake(documentElement, head) { | |
| 242 this.documentElement = documentElement; | |
| 243 this.head_ = head; | |
| 244 } | |
| 245 DocumentFake.prototype = { | |
| 246 getElementsByTagName: function(tagName) { | |
| 247 if (tagName == 'head' && this.head_) { | |
| 248 return [this.head_]; | |
| 249 } | |
| 250 return []; | |
| 251 }, | |
| 252 createElement: function(tagName) { | |
| 253 return new ElementFake(tagName); | |
| 254 }, | |
| 255 createTextNode: function(text) { | |
| 256 return new TextNodeFake(text); | |
| 257 } | |
| 258 } | |
| 259 | |
| 260 function ElementFake(tagName) { | |
| 261 this.tagName = tagName; | |
| 262 this.childNodes = []; | |
| 263 } | |
| 264 ElementFake.prototype = { | |
| 265 appendChild: function(e) { | |
| 266 this.childNodes.push(e); | |
| 267 return e; | |
| 268 } | |
| 269 } | |
| 270 | |
| 271 function TextNodeFake(text) { | |
| 272 this.text = text; | |
| 273 } | |
| 274 | |
| 275 function XMLHttpRequestFake() { | |
| 276 lastCreatedXhr = this; | |
| 277 this.onload = null; | |
| 278 this.onerror = null; | |
| 279 this.onreadystatechange = null; | |
| 280 this.openedMethod = null; | |
| 281 this.openededUrl = null; | |
| 282 this.overriddenMimeType = null; | |
| 283 this.requestHeaders = {}; | |
| 284 this.sentBody = null; | |
| 285 this.responseText = null; | |
| 286 this.readyState = null; | |
| 287 this.responseHeaders = {}; | |
| 288 this.status = null; | |
| 289 this.statusText = null; | |
| 290 } | |
| 291 XMLHttpRequestFake.prototype = { | |
| 292 open: function(method, url) { | |
| 293 this.openedMethod = method; | |
| 294 this.openedUrl = url; | |
| 295 }, | |
| 296 overrideMimeType: function(mimeType) { | |
| 297 this.overrideMimeType = mimeType; | |
| 298 }, | |
| 299 setRequestHeader: function(header, value) { | |
| 300 this.requestHeaders[header] = value; | |
| 301 }, | |
| 302 send: function(opt_body) { | |
| 303 this.sentBody = opt_body; | |
| 304 }, | |
| 305 getAllResponseHeaders: function() { | |
| 306 var s = ''; | |
| 307 for (var header in this.responseHeaders) { | |
| 308 // The delimiter used in Webkit's XMLHttpRequest is \r\n, however | |
| 309 // the new Chrome networking code (and Firefox) uses \n, so watch | |
| 310 // out for this! | |
| 311 s += header + ': ' + this.responseHeaders[header] + '\r\n'; | |
| 312 } | |
| 313 return s; | |
| 314 } | |
| 315 } | |
| 316 | |
| 317 function assert(expected, actual) { | |
| 318 if (expected !== actual) { | |
| 319 throw new Error('Assert failed: "' + expected + '" !== "' + actual + '"'); | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 function fail() { | |
| 324 throw new Error('Fail'); | |
| 325 } | |
| 326 | |
| 327 function assertThrow(f) { | |
| 328 var threw = false; | |
| 329 try { | |
| 330 f(); | |
| 331 } catch(e) { | |
| 332 threw = true; | |
| 333 } | |
| 334 if (!threw) { | |
| 335 throw new Error('Assert failed, expression did not throw.'); | |
| 336 } | |
| 337 } | |
| 338 | |
| OLD | NEW |