OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 (function() { | 5 (function() { |
6 | 6 |
7 'use strict'; | 7 'use strict'; |
8 | 8 |
9 module('base'); | 9 module('base'); |
10 | 10 |
11 test('mix(dest, src) should copy properties from |src| to |dest|', | 11 test('mix(dest, src) should copy properties from |src| to |dest|', |
12 function() { | 12 function() { |
13 var src = { a: 'a', b: 'b'}; | 13 var src = { a: 'a', b: 'b'}; |
14 var dest = { c: 'c'}; | 14 var dest = { c: 'c'}; |
15 | 15 |
16 base.mix(dest, src); | 16 base.mix(dest, src); |
17 deepEqual(dest, {a: 'a', b: 'b', c: 'c'}); | 17 deepEqual(dest, {a: 'a', b: 'b', c: 'c'}); |
18 }); | 18 }); |
19 | 19 |
20 test('mix(dest, src) should assert if properties are overwritten', | 20 test('mix(dest, src) should assert if properties are overwritten', |
21 function() { | 21 function() { |
22 var src = { a: 'a', b: 'b'}; | 22 var src = { a: 'a', b: 'b'}; |
23 var dest = { a: 'a'}; | 23 var dest = { a: 'a'}; |
24 | 24 |
25 sinon.spy(base.debug, 'assert'); | 25 sinon.$setupStub(base.debug, 'assert'); |
26 | 26 |
27 try { | 27 try { |
28 base.mix(dest, src); | 28 base.mix(dest, src); |
29 } catch (e) { | 29 } catch (e) { |
30 } finally { | 30 } finally { |
31 sinon.assert.called(base.debug.assert); | 31 sinon.assert.called(base.debug.assert); |
32 base.debug.assert.restore(); | 32 base.debug.assert.$testStub.restore(); |
33 } | 33 } |
34 }); | 34 }); |
35 | 35 |
36 test('values(obj) should return an array containing the values of |obj|', | 36 test('values(obj) should return an array containing the values of |obj|', |
37 function() { | 37 function() { |
38 var output = base.values({ a: 'a', b: 'b'}); | 38 var output = base.values({ a: 'a', b: 'b'}); |
39 | 39 |
40 notEqual(output.indexOf('a'), -1, '"a" should be in the output'); | 40 notEqual(output.indexOf('a'), -1, '"a" should be in the output'); |
41 notEqual(output.indexOf('b'), -1, '"b" should be in the output'); | 41 notEqual(output.indexOf('b'), -1, '"b" should be in the output'); |
42 }); | 42 }); |
(...skipping 22 matching lines...) Expand all Loading... |
65 test('modify the original after deepCopy(obj) should not affect the copy', | 65 test('modify the original after deepCopy(obj) should not affect the copy', |
66 function() { | 66 function() { |
67 var original = [1, 2, 3, 4]; | 67 var original = [1, 2, 3, 4]; |
68 var copy = base.deepCopy(original); | 68 var copy = base.deepCopy(original); |
69 original[2] = 1000; | 69 original[2] = 1000; |
70 QUnit.deepEqual(copy, [1, 2, 3, 4]); | 70 QUnit.deepEqual(copy, [1, 2, 3, 4]); |
71 }); | 71 }); |
72 | 72 |
73 test('dispose(obj) should invoke the dispose method on |obj|', | 73 test('dispose(obj) should invoke the dispose method on |obj|', |
74 function() { | 74 function() { |
75 var obj = { | 75 /** |
76 dispose: sinon.spy() | 76 * @constructor |
77 }; | 77 * @implements {base.Disposable} |
| 78 */ |
| 79 base.MockDisposable = function() {}; |
| 80 base.MockDisposable.prototype.dispose = sinon.spy(); |
| 81 |
| 82 var obj = new base.MockDisposable(); |
78 base.dispose(obj); | 83 base.dispose(obj); |
79 sinon.assert.called(obj.dispose); | 84 sinon.assert.called(obj.dispose); |
80 }); | 85 }); |
81 | 86 |
82 test('dispose(obj) should not crash if |obj| is null', | 87 test('dispose(obj) should not crash if |obj| is null', |
83 function() { | 88 function() { |
84 expect(0); | 89 expect(0); |
85 base.dispose(null); | 90 base.dispose(null); |
86 }); | 91 }); |
87 | 92 |
(...skipping 16 matching lines...) Expand all Loading... |
104 '&escapist=%3A%2F%3F%23%5B%5D%40%24%26%2B%2C%3B%3D'); | 109 '&escapist=%3A%2F%3F%23%5B%5D%40%24%26%2B%2C%3B%3D'); |
105 }); | 110 }); |
106 | 111 |
107 test('escapeHTML(str) should escape special characters', function() { | 112 test('escapeHTML(str) should escape special characters', function() { |
108 QUnit.equal( | 113 QUnit.equal( |
109 base.escapeHTML('<script>alert("hello")</script>'), | 114 base.escapeHTML('<script>alert("hello")</script>'), |
110 '<script>alert("hello")</script>'); | 115 '<script>alert("hello")</script>'); |
111 }); | 116 }); |
112 | 117 |
113 QUnit.asyncTest('Promise.sleep(delay) should fulfill the promise after |delay|', | 118 QUnit.asyncTest('Promise.sleep(delay) should fulfill the promise after |delay|', |
| 119 /** |
| 120 * 'this' is not defined for jscompile, so it can't figure out the type of |
| 121 * this.clock. |
| 122 * @suppress {reportUnknownTypes|checkVars|checkTypes} |
| 123 */ |
114 function() { | 124 function() { |
115 var isCalled = false; | 125 var isCalled = false; |
116 var clock = this.clock; | 126 var clock = /** @type {QUnit.Clock} */ (this.clock); |
117 | 127 |
118 base.Promise.sleep(100).then(function(){ | 128 base.Promise.sleep(100).then(function(){ |
119 isCalled = true; | 129 isCalled = true; |
120 ok(true, 'Promise.sleep() is fulfilled after delay.'); | 130 ok(true, 'Promise.sleep() is fulfilled after delay.'); |
121 QUnit.start(); | 131 QUnit.start(); |
122 }); | 132 }); |
123 | 133 |
124 // Tick the clock for 2 seconds and check if the promise is fulfilled. | 134 // Tick the clock for 2 seconds and check if the promise is fulfilled. |
125 clock.tick(2); | 135 clock.tick(2); |
126 | 136 |
127 // Promise fulfillment always occur on a new stack. Therefore, we will run | 137 // Promise fulfillment always occur on a new stack. Therefore, we will run |
128 // the verification in a requestAnimationFrame. | 138 // the verification in a requestAnimationFrame. |
129 window.requestAnimationFrame(function(){ | 139 window.requestAnimationFrame(function(){ |
130 ok(!isCalled, 'Promise.sleep() should not be fulfilled prematurely.'); | 140 ok(!isCalled, 'Promise.sleep() should not be fulfilled prematurely.'); |
131 clock.tick(101); | 141 clock.tick(101); |
132 }.bind(this)); | 142 }); |
133 }); | 143 }); |
134 | 144 |
135 QUnit.asyncTest('Promise.negate should fulfill iff the promise does not.', | 145 QUnit.asyncTest('Promise.negate should fulfill iff the promise does not.', |
136 function() { | 146 function() { |
137 | 147 |
138 base.Promise.negate(Promise.reject()).then( | 148 base.Promise.negate(Promise.reject()).then( |
139 ok.bind(null, true), | 149 QUnit.ok.bind(null, true), |
140 ok.bind(null, false)); | 150 /** @type {Function} */ (QUnit.ok.bind(null, false))); |
141 base.Promise.negate(Promise.resolve()).then( | 151 base.Promise.negate(Promise.resolve()).then( |
142 ok.bind(null, false), | 152 QUnit.ok.bind(null, false), |
143 ok.bind(null, true)); | 153 /** @type {Function} */ (QUnit.ok.bind(null, true))); |
144 window.requestAnimationFrame(function(){ | 154 window.requestAnimationFrame(function(){ |
145 QUnit.start(); | 155 QUnit.start(); |
146 }); | 156 }); |
147 }); | 157 }); |
148 | 158 |
149 module('base.Deferred'); | 159 module('base.Deferred'); |
150 | 160 |
151 QUnit.asyncTest('resolve() should fulfill the underlying promise.', function() { | 161 QUnit.asyncTest('resolve() should fulfill the underlying promise.', function() { |
| 162 /** @returns {Promise} */ |
152 function async() { | 163 function async() { |
153 var deferred = new base.Deferred(); | 164 var deferred = new base.Deferred(); |
154 deferred.resolve('bar'); | 165 deferred.resolve('bar'); |
155 return deferred.promise(); | 166 return deferred.promise(); |
156 } | 167 } |
157 | 168 |
158 async().then(function(value){ | 169 async().then( |
159 QUnit.equal(value, 'bar'); | 170 /** @param {string} value */ |
160 QUnit.start(); | 171 function(value){ |
161 }, function() { | 172 QUnit.equal(value, 'bar'); |
162 QUnit.ok(false, 'The reject handler should not be invoked.'); | 173 QUnit.start(); |
163 }); | 174 }, function() { |
| 175 QUnit.ok(false, 'The reject handler should not be invoked.'); |
| 176 }); |
164 }); | 177 }); |
165 | 178 |
166 QUnit.asyncTest('reject() should fail the underlying promise.', function() { | 179 QUnit.asyncTest('reject() should fail the underlying promise.', function() { |
| 180 /** @returns {Promise} */ |
167 function async() { | 181 function async() { |
168 var deferred = new base.Deferred(); | 182 var deferred = new base.Deferred(); |
169 deferred.reject('bar'); | 183 deferred.reject('bar'); |
170 return deferred.promise(); | 184 return deferred.promise(); |
171 } | 185 } |
172 | 186 |
173 async().then(function(){ | 187 async().then(function(){ |
174 QUnit.ok(false, 'The then handler should not be invoked.'); | 188 QUnit.ok(false, 'The then handler should not be invoked.'); |
175 }, function(value) { | 189 }, function(value) { |
176 QUnit.equal(value, 'bar'); | 190 QUnit.equal(value, 'bar'); |
177 QUnit.start(); | 191 QUnit.start(); |
178 }); | 192 }); |
179 }); | 193 }); |
180 | 194 |
181 | 195 |
| 196 /** @type {base.EventSourceImpl} */ |
182 var source = null; | 197 var source = null; |
183 var listener = null; | 198 var listener = null; |
184 | 199 |
185 module('base.EventSource', { | 200 module('base.EventSource', { |
186 setup: function() { | 201 setup: function() { |
187 source = new base.EventSourceImpl(); | 202 source = new base.EventSourceImpl(); |
188 source.defineEvents(['foo', 'bar']); | 203 source.defineEvents(['foo', 'bar']); |
189 listener = sinon.spy(); | 204 listener = sinon.spy(); |
190 source.addEventListener('foo', listener); | 205 source.addEventListener('foo', listener); |
191 }, | 206 }, |
(...skipping 30 matching lines...) Expand all Loading... |
222 }); | 237 }); |
223 | 238 |
224 test('raiseEvent() should not invoke listeners of a different event', | 239 test('raiseEvent() should not invoke listeners of a different event', |
225 function() { | 240 function() { |
226 source.raiseEvent('bar'); | 241 source.raiseEvent('bar'); |
227 sinon.assert.notCalled(listener); | 242 sinon.assert.notCalled(listener); |
228 }); | 243 }); |
229 | 244 |
230 test('raiseEvent() should assert when undeclared events are raised', | 245 test('raiseEvent() should assert when undeclared events are raised', |
231 function() { | 246 function() { |
232 sinon.spy(base.debug, 'assert'); | 247 sinon.$setupStub(base.debug, 'assert'); |
233 try { | 248 try { |
234 source.raiseEvent('undefined'); | 249 source.raiseEvent('undefined'); |
235 } catch (e) { | 250 } catch (e) { |
236 } finally { | 251 } finally { |
237 sinon.assert.called(base.debug.assert); | 252 sinon.assert.called(base.debug.assert); |
238 base.debug.assert.restore(); | 253 base.debug.assert.$testStub.restore(); |
239 } | 254 } |
240 }); | 255 }); |
241 | 256 |
242 test( | 257 test( |
243 'removeEventListener() should not invoke the listener in subsequent ' + | 258 'removeEventListener() should not invoke the listener in subsequent ' + |
244 'calls to |raiseEvent|', | 259 'calls to |raiseEvent|', |
245 function() { | 260 function() { |
246 source.raiseEvent('foo'); | 261 source.raiseEvent('foo'); |
247 sinon.assert.calledOnce(listener); | 262 sinon.assert.calledOnce(listener); |
248 | 263 |
(...skipping 12 matching lines...) Expand all Loading... |
261 | 276 |
262 source.addEventListener('foo', sink.listener); | 277 source.addEventListener('foo', sink.listener); |
263 source.raiseEvent('foo'); | 278 source.raiseEvent('foo'); |
264 sinon.assert.calledOnce(sink.listener); | 279 sinon.assert.calledOnce(sink.listener); |
265 | 280 |
266 source.raiseEvent('foo'); | 281 source.raiseEvent('foo'); |
267 sinon.assert.calledOnce(sink.listener); | 282 sinon.assert.calledOnce(sink.listener); |
268 }); | 283 }); |
269 | 284 |
270 test('encodeUtf8() can encode UTF8 strings', function() { | 285 test('encodeUtf8() can encode UTF8 strings', function() { |
| 286 /** @type {function(ArrayBuffer):Array} */ |
271 function toJsArray(arrayBuffer) { | 287 function toJsArray(arrayBuffer) { |
272 var result = []; | 288 var result = []; |
273 var array = new Uint8Array(arrayBuffer); | 289 var array = new Uint8Array(arrayBuffer); |
274 for (var i = 0; i < array.length; ++i) { | 290 for (var i = 0; i < array.length; ++i) { |
275 result.push(array[i]); | 291 result.push(array[i]); |
276 } | 292 } |
277 return result; | 293 return result; |
278 } | 294 } |
279 | 295 |
280 // ASCII. | 296 // ASCII. |
(...skipping 21 matching lines...) Expand all Loading... |
302 /* Ѓ */ 0xD0, 0x83, | 318 /* Ѓ */ 0xD0, 0x83, |
303 /* ф */ 0xD1, 0x84]).buffer), | 319 /* ф */ 0xD1, 0x84]).buffer), |
304 "挂Ѓф"); | 320 "挂Ѓф"); |
305 | 321 |
306 // Unicode surrogate pair for U+1F603. | 322 // Unicode surrogate pair for U+1F603. |
307 QUnit.equal(base.decodeUtf8(new Uint8Array([0xF0, 0x9F, 0x98, 0x83]).buffer), | 323 QUnit.equal(base.decodeUtf8(new Uint8Array([0xF0, 0x9F, 0x98, 0x83]).buffer), |
308 "😃"); | 324 "😃"); |
309 }); | 325 }); |
310 | 326 |
311 })(); | 327 })(); |
OLD | NEW |