Index: chrome/test/data/extensions/greasemonkey_api_test.js |
diff --git a/chrome/test/data/extensions/greasemonkey_api_test.js b/chrome/test/data/extensions/greasemonkey_api_test.js |
index d43e2a08e8b44ee773f38b1f860818b8127a2b5d..e629ceed932aa0f3a7c3ef73e327205a71408e3b 100644 |
--- a/chrome/test/data/extensions/greasemonkey_api_test.js |
+++ b/chrome/test/data/extensions/greasemonkey_api_test.js |
@@ -1,6 +1,8 @@ |
var localStorage; |
var document; |
var window; |
+var XMLHttpRequest; |
+var lastCreatedXhr; |
function testGetSetValue() { |
localStorage = new LocalStorageFake(); |
@@ -65,19 +67,100 @@ function testGetResourceText() { |
} |
function testAddStyle() { |
+ var documentElement = new ElementFake(''); |
var head = new ElementFake('head'); |
- document = new DocumentFake(head); |
+ document = new DocumentFake(documentElement, head); |
var css = 'color: #decaff;'; |
GM_addStyle(css); |
+ assert(0, documentElement.childNodes.length); |
assert(1, head.childNodes.length); |
var style = head.childNodes[0]; |
assert("style", style.tagName); |
assert("text/css", style.type); |
- assert(css, style.innerHTML); |
+ assert(1, style.childNodes.length); |
+ var textNode = style.childNodes[0]; |
+ assert(css, textNode.text); |
+ |
+ document = new DocumentFake(documentElement, null); |
+ GM_addStyle(css); |
+ assert(1, documentElement.childNodes.length); |
+ var style = documentElement.childNodes[0]; |
+ assert("text/css", style.type); |
+ assert(1, style.childNodes.length); |
+ textNode = style.childNodes[0]; |
+ assert(css, textNode.text); |
} |
function testXmlhttpRequest() { |
- var xhr = GM_xmlhttpRequest({}); |
+ XMLHttpRequest = XMLHttpRequestFake; |
+ var url = 'http://example.com'; |
+ |
+ var onLoadCallback = function(state) { |
+ onLoadCallbackResponseState = state; |
+ }; |
+ var onErrorCallback = function(state) { |
+ onErrorCallbackResponseState = state; |
+ }; |
+ var onReadyStateChangeCallback = function(state) { |
+ onReadyStateChangeCallbackResponseState = state; |
+ }; |
+ |
+ var details = { |
+ onload: onLoadCallback, |
+ onerror: onErrorCallback, |
+ onreadystatechange: onReadyStateChangeCallback, |
+ method: 'GET', |
+ url: url, |
+ overrideMimeType: 'text/html', |
+ headers: { |
+ 'X-Header': 'foo' |
+ }, |
+ data: 'data' |
+ }; |
+ |
+ GM_xmlhttpRequest(details); |
+ var xhr = lastCreatedXhr; |
+ |
+ assert('GET', xhr.openedMethod); |
+ assert(url, xhr.openedUrl); |
+ assert('text/html', xhr.overrideMimeType); |
+ assert('foo', xhr.requestHeaders['X-Header']); |
+ assert('data', xhr.sentBody); |
+ |
+ xhr.responseText = 'foo'; |
+ xhr.responseHeaders['X-Response'] = 'foo'; |
+ xhr.status = 200; |
+ xhr.statusText = 'OK'; |
+ |
+ xhr.readyState = 1; |
+ xhr.onreadystatechange(); |
+ var state = onReadyStateChangeCallbackResponseState; |
+ assert(xhr.responseText, state.responseText); |
+ assert(xhr.readyState, state.readyState); |
+ assert('', state.responseHeaders); |
+ assert(0, state.status); |
+ assert('', state.statusText); |
+ assert('', state.finalUrl); |
+ |
+ xhr.readyState = 0; |
+ xhr.onerror(); |
+ state = onErrorCallbackResponseState; |
+ assert(xhr.responseText, state.responseText); |
+ assert(xhr.readyState, state.readyState); |
+ assert('', state.responseHeaders); |
+ assert(0, state.status); |
+ assert('', state.statusText); |
+ assert('', state.finalUrl); |
+ |
+ xhr.readyState = 4; |
+ xhr.onload(); |
+ state = onLoadCallbackResponseState; |
+ assert(xhr.responseText, state.responseText); |
+ assert(xhr.readyState, state.readyState); |
+ assert('X-Response: foo\r\n', state.responseHeaders); |
+ assert(xhr.status, state.status); |
+ assert(xhr.statusText, state.statusText); |
+ assert(url, state.finalUrl); |
} |
function testRegisterMenuCommand() { |
@@ -155,7 +238,8 @@ LocalStorageFake.prototype = { |
} |
} |
-function DocumentFake(head) { |
+function DocumentFake(documentElement, head) { |
+ this.documentElement = documentElement; |
this.head_ = head; |
} |
DocumentFake.prototype = { |
@@ -167,224 +251,69 @@ DocumentFake.prototype = { |
}, |
createElement: function(tagName) { |
return new ElementFake(tagName); |
+ }, |
+ createTextNode: function(text) { |
+ return new TextNodeFake(text); |
} |
} |
function ElementFake(tagName) { |
this.tagName = tagName; |
+ this.childNodes = []; |
} |
ElementFake.prototype = { |
- childNodes: [], |
appendChild: function(e) { |
this.childNodes.push(e); |
return e; |
- }, |
-} |
- |
-function assert(expected, actual) { |
- if (expected !== actual) { |
- throw new Error('Assert failed: "' + expected + '" !== "' + actual + '"'); |
} |
} |
-function fail() { |
- throw new Error('Fail'); |
-} |
- |
-function assertThrow(f) { |
- var threw = false; |
- try { |
- f(); |
- } catch(e) { |
- threw = true; |
- } |
- if (!threw) { |
- throw new Error('Assert failed, expression did not throw.'); |
- } |
-} |
-var localStorage; |
-var document; |
-var window; |
- |
-function testGetSetValue() { |
- localStorage = new LocalStorageFake(); |
- GM_setValue('string', 'value'); |
- assert('value', GM_getValue('string')); |
- GM_setValue('integer', 123); |
- assert(123, GM_getValue('integer')); |
- GM_setValue('boolean', true); |
- assert(true, GM_getValue('boolean')); |
- |
- assert(undefined, GM_getValue('notset')); |
- assert('default', GM_getValue('notset', 'default')); |
- |
- // illegal values |
- assertThrow(function() { |
- GM_setValue('illegal value', null); |
- }); |
- assertThrow(function() { |
- GM_setValue('illegal value', 1.5); |
- }); |
-} |
- |
-function testDeleteValue() { |
- localStorage = new LocalStorageFake(); |
- GM_setValue('delete', 'value'); |
- assert('value', GM_getValue('delete')); |
- GM_deleteValue('delete'); |
- assert(undefined, GM_getValue('delete')); |
- GM_deleteValue('notset'); |
-} |
- |
-function testListValues() { |
- localStorage = new LocalStorageFake(); |
- var a = GM_listValues(); |
- assert(0, a.length); |
- |
- GM_setValue('one', 'first'); |
- a = GM_listValues(); |
- assert(1, a.length); |
- assert('one', a[0]); |
- |
- GM_setValue('two', 'second'); |
- a = GM_listValues(); |
- |
- // Test that keys that are not namespaced can't be read. |
- localStorage.setItem('three', 'third'); |
- assert(2, a.length); |
- assert(true, a.indexOf('one') >= 0); |
- assert(true, a.indexOf('two') >= 0); |
-} |
- |
-function testGetResourceURL() { |
- assertThrow(function() { |
- var resource = GM_getResourceURL('urlResourceName'); |
- }); |
-} |
- |
-function testGetResourceText() { |
- assertThrow(function() { |
- var resource = GM_getResourceText('textResourceName'); |
- }); |
-} |
- |
-function testAddStyle() { |
- var head = new ElementFake('head'); |
- document = new DocumentFake(head); |
- var css = 'color: #decaff;'; |
- GM_addStyle(css); |
- assert(1, head.childNodes.length); |
- var style = head.childNodes[0]; |
- assert("style", style.tagName); |
- assert("text/css", style.type); |
- assert(css, style.innerHTML); |
-} |
- |
-function testXmlhttpRequest() { |
- var xhr = GM_xmlhttpRequest({}); |
-} |
- |
-function testRegisterMenuCommand() { |
- assertThrow(function() { |
- GM_registerMenuCommand('name', function() {}, 'a', '', 'a'); |
- }); |
-} |
- |
-function testOpenInTab() { |
- var mockWindow = { |
- open: function(url, name, opt_options) { |
- this.openedUrl = url; |
- this.openedName = name; |
- this.openedOptions = opt_options; |
- } |
- }; |
- window = mockWindow; |
- var url = 'http://example.com'; |
- GM_openInTab(url); |
- assert(mockWindow.openedUrl, url); |
-} |
- |
-function testLog() { |
- var mockWindow = { |
- console: { |
- message: null, |
- log: function(message) { |
- this.message = message; |
- } |
- } |
- }; |
- window = mockWindow; |
- var message = 'hello world'; |
- GM_log(message); |
- assert(message, mockWindow.console.message); |
-} |
- |
-function LocalStorageFake() { |
- this.map_ = {}; |
- this.keys_ = []; |
-} |
-LocalStorageFake.prototype = { |
- length: 0, |
- key: function(index) { |
- if (index >= this.length) { |
- throw new Error('INDEX_SIZE_ERR'); |
- } |
- return this.keys_[index]; |
+function TextNodeFake(text) { |
+ this.text = text; |
+} |
+ |
+function XMLHttpRequestFake() { |
+ lastCreatedXhr = this; |
+ this.onload = null; |
+ this.onerror = null; |
+ this.onreadystatechange = null; |
+ this.openedMethod = null; |
+ this.openededUrl = null; |
+ this.overriddenMimeType = null; |
+ this.requestHeaders = {}; |
+ this.sentBody = null; |
+ this.responseText = null; |
+ this.readyState = null; |
+ this.responseHeaders = {}; |
+ this.status = null; |
+ this.statusText = null; |
+} |
+XMLHttpRequestFake.prototype = { |
+ open: function(method, url) { |
+ this.openedMethod = method; |
+ this.openedUrl = url; |
}, |
- getItem: function(key) { |
- if (key in this.map_) { |
- return this.map_[key]; |
- } |
- return null; |
+ overrideMimeType: function(mimeType) { |
+ this.overrideMimeType = mimeType; |
}, |
- setItem: function(key, data) { |
- this.map_[key] = data; |
- this.updateKeys_(); |
+ setRequestHeader: function(header, value) { |
+ this.requestHeaders[header] = value; |
}, |
- removeItem: function(key) { |
- delete this.map_[key]; |
- this.updateKeys_(); |
- }, |
- clear: function() { |
- this.map_ = {}; |
- this.updateKeys_(); |
+ send: function(opt_body) { |
+ this.sentBody = opt_body; |
}, |
- updateKeys_: function() { |
- var keys = []; |
- for (var key in this.map_) { |
- keys.push(key); |
- } |
- this.keys_ = keys; |
- this.length = keys.length; |
- } |
-} |
- |
-function DocumentFake(head) { |
- this.head_ = head; |
-} |
-DocumentFake.prototype = { |
- getElementsByTagName: function(tagName) { |
- if (tagName == 'head' && this.head_) { |
- return [this.head_]; |
+ getAllResponseHeaders: function() { |
+ var s = ''; |
+ for (var header in this.responseHeaders) { |
+ // The delimiter used in Webkit's XMLHttpRequest is \r\n, however |
+ // the new Chrome networking code (and Firefox) uses \n, so watch |
+ // out for this! |
+ s += header + ': ' + this.responseHeaders[header] + '\r\n'; |
} |
- return []; |
- }, |
- createElement: function(tagName) { |
- return new ElementFake(tagName); |
+ return s; |
} |
} |
-function ElementFake(tagName) { |
- this.tagName = tagName; |
-} |
-ElementFake.prototype = { |
- childNodes: [], |
- appendChild: function(e) { |
- this.childNodes.push(e); |
- return e; |
- }, |
-} |
- |
function assert(expected, actual) { |
if (expected !== actual) { |
throw new Error('Assert failed: "' + expected + '" !== "' + actual + '"'); |
@@ -406,3 +335,4 @@ function assertThrow(f) { |
throw new Error('Assert failed, expression did not throw.'); |
} |
} |
+ |