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 |