1<!DOCTYPE html> 2<!-- 3Copyright 2015 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7 8<script> 9'use strict'; 10 11var testing_common = (function() { 12 13 var originalXMLHttpRequest = window.XMLHttpRequest; 14 var fixture = null; 15 var xhrMock = null; 16 17 var XMLHttpRequestMock = function() { 18 this.responseMap_ = {}; 19 window.XMLHttpRequest = this.getMock(); 20 }; 21 22 XMLHttpRequestMock.prototype.getMock = function() { 23 // TODO(chrisphan): Add support for error state. 24 var self = this; 25 return function() { 26 this.status = 200; 27 this.onerror = function() {}; 28 this.open = function(method, url, async) { 29 this.url = url; 30 }; 31 this.abort = function() {}; 32 this.setRequestHeader = function() {}; 33 this.onload = function() {}; 34 this.send = function(param) { 35 var requestStr = this.url + '?' + sortQueryPart(param); 36 if (requestStr in self.responseMap_) { 37 this.responseText = self.responseMap_[requestStr]; 38 this.onload(); 39 } else if ('*' in self.responseMap_) { 40 this.responseText = self.responseMap_['*']; 41 this.onload(); 42 } else { 43 console.warn('XMLHttpRequest sent without a handler: ' + requestStr); 44 } 45 }; 46 }; 47 }; 48 49 XMLHttpRequestMock.prototype.add = function(param, response) { 50 if (param != '*') { 51 param = sortQueryPart(param); 52 } 53 this.responseMap_[param] = response; 54 }; 55 56 function addXhrMock(param, response) { 57 if (!xhrMock) { 58 xhrMock = new XMLHttpRequestMock(); 59 } 60 xhrMock.add(param, response); 61 }; 62 63 function clearXhrMock() { 64 window.XMLHttpRequest = originalXMLHttpRequest; 65 xhrMock = null; 66 }; 67 68 /** 69 * Does a deep copy of the object. 70 * @param {*} obj Object to copy. 71 * @return {*} A copy of the object. 72 */ 73 function deepCopy(obj) { 74 return JSON.parse(JSON.stringify(obj)); 75 }; 76 77 function addToFixture(node) { 78 if (!fixture) { 79 fixture = document.createElement('div'); 80 document.body.appendChild(fixture); 81 } 82 fixture.appendChild(node); 83 }; 84 85 function clearFixture() { 86 if (fixture) { 87 fixture.innerHTML = ''; 88 } 89 }; 90 91 var paramString = function(params) { 92 var keys = Object.keys(params).sort(); 93 return keys.map(function(key) { 94 return key + '=' + encodeURIComponent(params[key]); 95 }).join('&'); 96 }; 97 98 var sortQueryPart = function(paramStr) { 99 var params = {}; 100 var path = paramStr.substring(0, paramStr.indexOf('?') + 1); 101 var query = paramStr.substring(paramStr.indexOf('?') + 1); 102 var queryParts = query.split('&'); 103 for (var i = 0; i < queryParts.length; i++) { 104 var pair = queryParts[i].split('='); 105 params[pair[0]] = pair.length == 1 ? '' : pair[1]; 106 } 107 var keys = Object.keys(params).sort(); 108 query = keys.map(function(key) { 109 return key + '=' + params[key]; 110 }).join('&'); 111 return path + query; 112 }; 113 114 return { 115 addXhrMock: addXhrMock, 116 clearXhrMock: clearXhrMock, 117 deepCopy: deepCopy, 118 addToFixture: addToFixture, 119 clearFixture: clearFixture, 120 paramString: paramString, 121 sortQueryPart: sortQueryPart 122 }; 123})(); 124 125</script> 126