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.
11 QUnit
.test('mix(dest, src) should copy properties from |src| to |dest|',
13 var src
= { a
: 'a', b
: 'b'};
17 assert
.deepEqual(dest
, {a
: 'a', b
: 'b', c
: 'c'});
20 QUnit
.test('mix(dest, src) should not override property.', function(assert
) {
21 var src
= { a
: 'a', b
: 'b'};
22 var dest
= { a
: 'a2'};
24 assert
.equal(dest
['a'], 'a2');
25 assert
.equal(dest
['b'], 'b');
28 QUnit
.test('values(obj) should return an array containing the values of |obj|',
30 var output
= base
.values({ a
: 'a', b
: 'b'});
32 assert
.notEqual(output
.indexOf('a'), -1, '"a" should be in the output');
33 assert
.notEqual(output
.indexOf('b'), -1, '"b" should be in the output');
36 QUnit
.test('deepCopy(obj) should return null on NaN and undefined',
38 assert
.equal(base
.deepCopy(NaN
), null);
39 assert
.equal(base
.deepCopy(undefined), null);
42 QUnit
.test('deepCopy(obj) should copy primitive types recursively',
44 assert
.equal(base
.deepCopy(1), 1);
45 assert
.equal(base
.deepCopy('hello'), 'hello');
46 assert
.equal(base
.deepCopy(false), false);
47 assert
.equal(base
.deepCopy(null), null);
48 assert
.deepEqual(base
.deepCopy([1, 2]), [1, 2]);
49 assert
.deepEqual(base
.deepCopy({'key': 'value'}), {'key': 'value'});
50 assert
.deepEqual(base
.deepCopy(
51 {'key': {'key_nested': 'value_nested'}}),
52 {'key': {'key_nested': 'value_nested'}}
54 assert
.deepEqual(base
.deepCopy([1, [2, [3]]]), [1, [2, [3]]]);
57 QUnit
.test('modify the original after deepCopy(obj) should not affect the copy',
59 var original
= [1, 2, 3, 4];
60 var copy
= base
.deepCopy(original
);
62 assert
.deepEqual(copy
, [1, 2, 3, 4]);
65 QUnit
.test('dispose(obj) should invoke the dispose method on |obj|',
69 * @implements {base.Disposable}
71 base
.MockDisposable = function() {};
72 base
.MockDisposable
.prototype.dispose
= sinon
.spy();
74 var obj
= new base
.MockDisposable();
76 sinon
.assert
.called(obj
.dispose
);
79 QUnit
.test('dispose(obj) should not crash if |obj| is null',
86 'urljoin(url, opt_param) should return url if |opt_param| is missing',
89 base
.urlJoin('http://www.chromium.org'), 'http://www.chromium.org');
92 QUnit
.test('urljoin(url, opt_param) should urlencode |opt_param|',
94 var result
= base
.urlJoin('http://www.chromium.org', {
97 escapist
: ':/?#[]@$&+,;='
101 'http://www.chromium.org?a=a&foo=foo' +
102 '&escapist=%3A%2F%3F%23%5B%5D%40%24%26%2B%2C%3B%3D');
105 QUnit
.test('escapeHTML(str) should escape special characters', function(assert
){
107 base
.escapeHTML('<script>alert("hello")</script>'),
108 '<script>alert("hello")</script>');
111 QUnit
.test('Promise.sleep(delay) should fulfill the promise after |delay|',
113 * 'this' is not defined for jscompile, so it can't figure out the type of
115 * @suppress {reportUnknownTypes|checkVars|checkTypes}
118 var isCalled
= false;
119 var clock
= /** @type {QUnit.Clock} */ (this.clock
);
121 var promise
= base
.Promise
.sleep(100).then(function(){
123 assert
.ok(true, 'Promise.sleep() is fulfilled after delay.');
126 // Tick the clock for 2 seconds and check if the promise is fulfilled.
129 // Promise fulfillment always occur on a new stack. Therefore, we will run
130 // the verification in a requestAnimationFrame.
131 window
.requestAnimationFrame(function(){
133 !isCalled
, 'Promise.sleep() should not be fulfilled prematurely.');
140 QUnit
.test('Promise.negate should fulfill iff the promise does not.',
142 return base
.Promise
.negate(Promise
.reject())
145 }).catch(function() {
148 return base
.Promise
.negate(Promise
.resolve());
151 }).catch(function() {
156 QUnit
.module('base.Deferred');
158 QUnit
.test('resolve() should fulfill the underlying promise.', function(assert
){
159 /** @returns {Promise} */
161 var deferred
= new base
.Deferred();
162 deferred
.resolve('bar');
163 return deferred
.promise();
166 return async().then(function(/** string */ value
){
167 assert
.equal(value
, 'bar');
169 assert
.ok(false, 'The reject handler should not be invoked.');
173 QUnit
.test('reject() should fail the underlying promise.', function(assert
) {
174 /** @returns {Promise} */
176 var deferred
= new base
.Deferred();
177 deferred
.reject('bar');
178 return deferred
.promise();
181 return async().then(function(){
182 assert
.ok(false, 'The then handler should not be invoked.');
184 assert
.equal(value
, 'bar');
189 /** @type {base.EventSourceImpl} */
193 QUnit
.module('base.EventSource', {
194 beforeEach: function() {
195 source
= new base
.EventSourceImpl();
196 source
.defineEvents(['foo', 'bar']);
197 listener
= sinon
.spy();
198 source
.addEventListener('foo', listener
);
200 afterEach: function() {
206 QUnit
.test('raiseEvent() should invoke the listener', function() {
207 source
.raiseEvent('foo');
208 sinon
.assert
.called(listener
);
212 'raiseEvent() should invoke the listener with the correct event data',
217 source
.raiseEvent('foo', data
);
218 sinon
.assert
.calledWith(listener
, data
);
222 'raiseEvent() should not invoke listeners that are added during raiseEvent',
224 source
.addEventListener('foo', function() {
225 source
.addEventListener('foo', function() {
230 source
.raiseEvent('foo');
233 QUnit
.test('raiseEvent() should not invoke listeners of a different event',
235 source
.raiseEvent('bar');
236 sinon
.assert
.notCalled(listener
);
239 QUnit
.test('raiseEvent() should assert when undeclared events are raised',
241 sinon
.stub(base
.debug
, 'assert');
243 source
.raiseEvent('undefined');
246 sinon
.assert
.called(base
.debug
.assert
);
247 $testStub(base
.debug
.assert
).restore();
252 'removeEventListener() should not invoke the listener in subsequent ' +
253 'calls to |raiseEvent|',
255 source
.raiseEvent('foo');
256 sinon
.assert
.calledOnce(listener
);
258 source
.removeEventListener('foo', listener
);
259 source
.raiseEvent('foo');
260 sinon
.assert
.calledOnce(listener
);
263 QUnit
.test('removeEventListener() should work even if the listener ' +
264 'is removed during |raiseEvent|',
267 sink
.listener
= sinon
.spy(function() {
268 source
.removeEventListener('foo', sink
.listener
);
271 source
.addEventListener('foo', sink
.listener
);
272 source
.raiseEvent('foo');
273 sinon
.assert
.calledOnce(sink
.listener
);
275 source
.raiseEvent('foo');
276 sinon
.assert
.calledOnce(sink
.listener
);
279 QUnit
.test('encodeUtf8() can encode UTF8 strings', function(assert
) {
280 /** @type {function(ArrayBuffer):Array} */
281 function toJsArray(arrayBuffer
) {
283 var array
= new Uint8Array(arrayBuffer
);
284 for (var i
= 0; i
< array
.length
; ++i
) {
285 result
.push(array
[i
]);
291 assert
.deepEqual(toJsArray(base
.encodeUtf8("ABC")), [0x41, 0x42, 0x43]);
293 // Some arbitrary characters from the basic Unicode plane.
295 toJsArray(base
.encodeUtf8("挂Ѓф")),
296 [/* 挂 */ 0xE6, 0x8C, 0x82, /* Ѓ */ 0xD0, 0x83, /* ф */ 0xD1, 0x84]);
298 // Unicode surrogate pair for U+1F603.
299 assert
.deepEqual(toJsArray(base
.encodeUtf8("😃")),
300 [0xF0, 0x9F, 0x98, 0x83]);
303 QUnit
.test('decodeUtf8() can decode UTF8 strings', function(assert
) {
305 assert
.equal(base
.decodeUtf8(new Uint8Array([0x41, 0x42, 0x43]).buffer
),
308 // Some arbitrary characters from the basic Unicode plane.
311 new Uint8Array([/* 挂 */ 0xE6, 0x8C, 0x82,
313 /* ф */ 0xD1, 0x84]).buffer
),
316 // Unicode surrogate pair for U+1F603.
317 assert
.equal(base
.decodeUtf8(new Uint8Array([0xF0, 0x9F, 0x98, 0x83]).buffer
),