OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // This file contains various mock objects for the chrome platform to make | |
6 // unit testing easier. | |
7 | |
8 Entry = function() {}; | |
9 | |
10 var chromeMocks = {}; | |
11 | |
12 /** @constructor */ | |
13 chrome.Event = function() {}; | |
14 | |
15 /** @param {Function} callback */ | |
16 chrome.Event.prototype.addListener = function(callback) {}; | |
17 | |
18 /** @param {Function} callback */ | |
19 chrome.Event.prototype.removeListener = function(callback) {}; | |
20 | |
21 | |
22 (function(){ | |
23 | |
24 /** | |
25 * @constructor | |
26 */ | |
27 chromeMocks.Event = function() { | |
28 this.listeners_ = []; | |
29 }; | |
30 | |
31 /** @param {Function} callback */ | |
32 chromeMocks.Event.prototype.addListener = function(callback) { | |
33 this.listeners_.push(callback); | |
34 }; | |
35 | |
36 /** @param {Function} callback */ | |
37 chromeMocks.Event.prototype.removeListener = function(callback) { | |
38 for (var i = 0; i < this.listeners_.length; i++) { | |
39 if (this.listeners_[i] === callback) { | |
40 this.listeners_.splice(i, 1); | |
41 break; | |
42 } | |
43 } | |
44 }; | |
45 | |
46 /** | |
47 * @param {...*} var_args | |
48 * @return {void} | |
49 */ | |
50 chromeMocks.Event.prototype.mock$fire = function(var_args) { | |
51 var params = Array.prototype.slice.call(arguments); | |
52 this.listeners_.forEach( | |
53 /** @param {Function} listener */ | |
54 function(listener){ | |
55 listener.apply(null, params); | |
56 }); | |
57 }; | |
58 | |
59 /** @type {Object} */ | |
60 chromeMocks.runtime = {}; | |
61 | |
62 /** @constructor */ | |
63 chromeMocks.runtime.Port = function() { | |
64 this.onMessage = new chromeMocks.Event(); | |
65 this.onDisconnect = new chromeMocks.Event(); | |
66 | |
67 /** @type {string} */ | |
68 this.name = ''; | |
69 | |
70 /** @type {chrome.runtime.MessageSender} */ | |
71 this.sender = null; | |
72 }; | |
73 | |
74 chromeMocks.runtime.Port.prototype.disconnect = function() {}; | |
75 | |
76 /** | |
77 * @param {Object} message | |
78 */ | |
79 chromeMocks.runtime.Port.prototype.postMessage = function(message) {}; | |
80 | |
81 /** @type {chromeMocks.Event} */ | |
82 chromeMocks.runtime.onMessage = new chromeMocks.Event(); | |
83 | |
84 /** | |
85 * @param {string?} extensionId | |
86 * @param {*} message | |
87 * @param {function(*)=} responseCallback | |
88 */ | |
89 chromeMocks.runtime.sendMessage = function(extensionId, message, | |
90 responseCallback) { | |
91 base.debug.assert( | |
92 extensionId === null, | |
93 'The mock only supports sending messages to the same extension.'); | |
94 extensionId = chrome.runtime.id; | |
95 window.requestAnimationFrame(function() { | |
96 var message_copy = base.deepCopy(message); | |
97 chromeMocks.runtime.onMessage.mock$fire( | |
98 message_copy, {id: extensionId}, responseCallback); | |
99 }); | |
100 }; | |
101 | |
102 /** @type {string} */ | |
103 chromeMocks.runtime.id = 'extensionId'; | |
104 | |
105 /** @type {Object} */ | |
106 chromeMocks.storage = {}; | |
107 | |
108 // Sample implementation of chrome.StorageArea according to | |
109 // https://developer.chrome.com/apps/storage#type-StorageArea | |
110 /** @constructor */ | |
111 chromeMocks.StorageArea = function() { | |
112 /** @type {Object} */ | |
113 this.storage_ = {}; | |
114 }; | |
115 | |
116 /** | |
117 * @param {!Object} keys | |
118 * @return {Array<string>} | |
119 */ | |
120 function getKeys(keys) { | |
121 if (typeof keys === 'string') { | |
122 return [keys]; | |
123 } else if (typeof keys === 'object') { | |
124 return Object.keys(keys); | |
125 } | |
126 return []; | |
127 } | |
128 | |
129 /** | |
130 * @param {!Object} keys | |
131 * @param {Function} onDone | |
132 */ | |
133 chromeMocks.StorageArea.prototype.get = function(keys, onDone) { | |
134 if (!keys) { | |
135 onDone(base.deepCopy(this.storage_)); | |
136 return; | |
137 } | |
138 | |
139 var result = (typeof keys === 'object') ? keys : {}; | |
140 getKeys(keys).forEach( | |
141 /** @param {string} key */ | |
142 function(key) { | |
143 if (key in this.storage_) { | |
144 result[key] = base.deepCopy(this.storage_[key]); | |
145 } | |
146 }, this); | |
147 onDone(result); | |
148 }; | |
149 | |
150 /** @param {Object} value */ | |
151 chromeMocks.StorageArea.prototype.set = function(value) { | |
152 for (var key in value) { | |
153 this.storage_[key] = base.deepCopy(value[key]); | |
154 } | |
155 }; | |
156 | |
157 /** | |
158 * @param {!Object} keys | |
159 */ | |
160 chromeMocks.StorageArea.prototype.remove = function(keys) { | |
161 getKeys(keys).forEach( | |
162 /** @param {string} key */ | |
163 function(key) { | |
164 delete this.storage_[key]; | |
165 }, this); | |
166 }; | |
167 | |
168 chromeMocks.StorageArea.prototype.clear = function() { | |
169 this.storage_ = null; | |
170 }; | |
171 | |
172 /** @type {chromeMocks.StorageArea} */ | |
173 chromeMocks.storage.local = new chromeMocks.StorageArea(); | |
174 | |
175 var originals_ = null; | |
176 | |
177 /** | |
178 * Activates a list of Chrome components to mock | |
179 * @param {Array<string>} components | |
180 */ | |
181 chromeMocks.activate = function(components) { | |
182 if (originals_) { | |
183 throw new Error('chromeMocks.activate() can only be called once.'); | |
184 } | |
185 originals_ = {}; | |
186 components.forEach(function(component) { | |
187 if (!chromeMocks[component]) { | |
188 throw new Error('No mocks defined for chrome.' + component); | |
189 } | |
190 originals_[component] = chrome[component]; | |
191 chrome[component] = chromeMocks[component]; | |
192 }); | |
193 }; | |
194 | |
195 chromeMocks.restore = function() { | |
196 if (!originals_) { | |
197 throw new Error('You must call activate() before restore().'); | |
198 } | |
199 for (var components in originals_) { | |
200 chrome[components] = originals_[components]; | |
201 } | |
202 originals_ = null; | |
203 }; | |
204 | |
205 })(); | |
OLD | NEW |