Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / remoting / webapp / base / js / base_unittest.js
blobe5ec7dfddc0f6a32bc87f086e22d7e6c56c401e1
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.
5 (function() {
7 'use strict';
9 var getRandomValuesStub = null;
11 QUnit.module('base', {
12 afterEach: function() {
13 if (getRandomValuesStub) {
14 getRandomValuesStub.restore();
15 getRandomValuesStub = null;
18 });
20 QUnit.test('mix(dest, src) should copy properties from |src| to |dest|',
21 function(assert) {
22 var src = { a: 'a', b: 'b'};
23 var dest = { c: 'c'};
25 base.mix(dest, src);
26 assert.deepEqual(dest, {a: 'a', b: 'b', c: 'c'});
27 });
29 QUnit.test('mix(dest, src) should not override property.', function(assert) {
30 var src = { a: 'a', b: 'b'};
31 var dest = { a: 'a2'};
32 base.mix(dest, src);
33 assert.equal(dest['a'], 'a2');
34 assert.equal(dest['b'], 'b');
35 });
37 QUnit.test('values(obj) should return an array containing the values of |obj|',
38 function(assert) {
39 var output = base.values({ a: 'a', b: 'b'});
41 assert.notEqual(output.indexOf('a'), -1, '"a" should be in the output');
42 assert.notEqual(output.indexOf('b'), -1, '"b" should be in the output');
43 });
45 QUnit.test('deepCopy(obj) should return null on NaN and undefined',
46 function(assert) {
47 assert.equal(base.deepCopy(NaN), null);
48 assert.equal(base.deepCopy(undefined), null);
49 });
51 QUnit.test('deepCopy(obj) should copy primitive types recursively',
52 function(assert) {
53 assert.equal(base.deepCopy(1), 1);
54 assert.equal(base.deepCopy('hello'), 'hello');
55 assert.equal(base.deepCopy(false), false);
56 assert.equal(base.deepCopy(null), null);
57 assert.deepEqual(base.deepCopy([1, 2]), [1, 2]);
58 assert.deepEqual(base.deepCopy({'key': 'value'}), {'key': 'value'});
59 assert.deepEqual(base.deepCopy(
60 {'key': {'key_nested': 'value_nested'}}),
61 {'key': {'key_nested': 'value_nested'}}
63 assert.deepEqual(base.deepCopy([1, [2, [3]]]), [1, [2, [3]]]);
64 });
66 QUnit.test('copyWithoutNullFields returns a new object',
67 function(assert) {
68 var obj = {
69 a: 'foo',
70 b: 42
72 var copy = base.copyWithoutNullFields(obj);
73 assert.notEqual(obj, copy);
74 assert.deepEqual(obj, copy);
75 });
77 QUnit.test('copyWithoutNullFields removes null and undefined fields',
78 function(assert) {
79 /** @const */
80 var obj = {
81 a: 'foo',
82 b: 42,
83 zero: 0,
84 emptyString: '',
85 nullField: null,
86 undefinedField: undefined
88 var copy = base.copyWithoutNullFields(obj);
89 assert.equal(copy['a'], obj['a']);
90 assert.equal(copy['b'], obj['b']);
91 assert.equal(copy['zero'], 0);
92 assert.equal(copy['emptyString'], '');
93 assert.ok(!('nullField' in copy));
94 assert.ok(!('undefinedField' in copy));
95 });
97 QUnit.test('copyWithoutNullFields(null) returns a new empty bject',
98 function(assert) {
99 assert.deepEqual(
100 base.copyWithoutNullFields(null),
101 {});
102 assert.notEqual(
103 base.copyWithoutNullFields(null),
104 base.copyWithoutNullFields(null));
105 assert.deepEqual(
106 base.copyWithoutNullFields(undefined),
107 {});
108 assert.notEqual(
109 base.copyWithoutNullFields(undefined),
110 base.copyWithoutNullFields(undefined));
113 QUnit.test('modify the original after deepCopy(obj) should not affect the copy',
114 function(assert) {
115 var original = [1, 2, 3, 4];
116 var copy = base.deepCopy(original);
117 original[2] = 1000;
118 assert.deepEqual(copy, [1, 2, 3, 4]);
121 QUnit.test('dispose(obj) should invoke the dispose method on |obj|',
122 function(assert) {
124 * @constructor
125 * @implements {base.Disposable}
127 base.MockDisposable = function() {};
128 base.MockDisposable.prototype.dispose = sinon.spy();
130 var obj = new base.MockDisposable();
131 base.dispose(obj);
132 sinon.assert.called(obj.dispose);
135 QUnit.test('dispose(obj) should not crash if |obj| is null',
136 function(assert) {
137 assert.expect(0);
138 base.dispose(null);
141 QUnit.test(
142 'urljoin(url, opt_param) should return url if |opt_param| is missing',
143 function(assert) {
144 assert.equal(
145 base.urlJoin('http://www.chromium.org'), 'http://www.chromium.org');
148 QUnit.test('urljoin(url, opt_param) should urlencode |opt_param|',
149 function(assert) {
150 var result = base.urlJoin('http://www.chromium.org', {
151 a: 'a',
152 foo: 'foo',
153 escapist: ':/?#[]@$&+,;='
155 assert.equal(
156 result,
157 'http://www.chromium.org?a=a&foo=foo' +
158 '&escapist=%3A%2F%3F%23%5B%5D%40%24%26%2B%2C%3B%3D');
161 QUnit.test('escapeHTML(str) should escape special characters', function(assert){
162 assert.equal(
163 base.escapeHTML('<script>alert("hello")</script>'),
164 '&lt;script&gt;alert("hello")&lt;/script&gt;');
167 QUnit.test('Promise.sleep(delay) should fulfill the promise after |delay|',
169 * 'this' is not defined for jscompile, so it can't figure out the type of
170 * this.clock.
171 * @suppress {reportUnknownTypes|checkVars|checkTypes}
173 function(assert) {
174 var isCalled = false;
175 var clock = /** @type {QUnit.Clock} */ (this.clock);
177 var promise = base.Promise.sleep(100).then(function(){
178 isCalled = true;
179 assert.ok(true, 'Promise.sleep() is fulfilled after delay.');
182 // Tick the clock for 2 seconds and check if the promise is fulfilled.
183 clock.tick(2);
185 // Promise fulfillment always occur on a new stack. Therefore, we will run
186 // the verification in a requestAnimationFrame.
187 window.requestAnimationFrame(function(){
188 assert.ok(
189 !isCalled, 'Promise.sleep() should not be fulfilled prematurely.');
190 clock.tick(101);
193 return promise;
196 QUnit.test('Promise.negate should fulfill iff the promise does not.',
197 function(assert) {
198 return base.Promise.negate(Promise.reject())
199 .then(function() {
200 assert.ok(true);
201 }).catch(function() {
202 assert.ok(false);
203 }).then(function() {
204 return base.Promise.negate(Promise.resolve());
205 }).then(function() {
206 assert.ok(false);
207 }).catch(function() {
208 assert.ok(true);
212 QUnit.test('generateUuid generates a UUID', function(assert) {
213 getRandomValuesStub = sinon.stub(
214 window.crypto, 'getRandomValues', function(/** Uint16Array*/ out) {
215 for (var i = 0; i < out.length; i++) {
216 out[i] = i;
219 assert.equal(base.generateUuid(), '00000001-0002-0003-0004-000500060007');
222 QUnit.module('base.Deferred');
224 QUnit.test('resolve() should fulfill the underlying promise.', function(assert){
225 /** @returns {Promise} */
226 function async() {
227 var deferred = new base.Deferred();
228 deferred.resolve('bar');
229 return deferred.promise();
232 return async().then(function(/** string */ value){
233 assert.equal(value, 'bar');
234 }, function() {
235 assert.ok(false, 'The reject handler should not be invoked.');
239 QUnit.test('reject() should fail the underlying promise.', function(assert) {
240 /** @returns {Promise} */
241 function async() {
242 var deferred = new base.Deferred();
243 deferred.reject('bar');
244 return deferred.promise();
247 return async().then(function(){
248 assert.ok(false, 'The then handler should not be invoked.');
249 }, function(value) {
250 assert.equal(value, 'bar');
255 /** @type {base.EventSourceImpl} */
256 var source = null;
257 var listener = null;
259 QUnit.module('base.EventSource', {
260 beforeEach: function() {
261 source = new base.EventSourceImpl();
262 source.defineEvents(['foo', 'bar']);
263 listener = sinon.spy();
264 source.addEventListener('foo', listener);
266 afterEach: function() {
267 source = null;
268 listener = null;
272 QUnit.test('raiseEvent() should invoke the listener', function() {
273 source.raiseEvent('foo');
274 sinon.assert.called(listener);
277 QUnit.test(
278 'raiseEvent() should invoke the listener with the correct event data',
279 function(assert) {
280 var data = {
281 field: 'foo'
283 source.raiseEvent('foo', data);
284 sinon.assert.calledWith(listener, data);
287 QUnit.test(
288 'raiseEvent() should not invoke listeners that are added during raiseEvent',
289 function(assert) {
290 source.addEventListener('foo', function() {
291 source.addEventListener('foo', function() {
292 assert.ok(false);
294 assert.ok(true);
296 source.raiseEvent('foo');
299 QUnit.test('raiseEvent() should not invoke listeners of a different event',
300 function(assert) {
301 source.raiseEvent('bar');
302 sinon.assert.notCalled(listener);
305 QUnit.test('raiseEvent() should assert when undeclared events are raised',
306 function(assert) {
307 sinon.stub(base.debug, 'assert');
308 try {
309 source.raiseEvent('undefined');
310 } catch (e) {
311 } finally {
312 sinon.assert.called(base.debug.assert);
313 $testStub(base.debug.assert).restore();
317 QUnit.test(
318 'removeEventListener() should not invoke the listener in subsequent ' +
319 'calls to |raiseEvent|',
320 function(assert) {
321 source.raiseEvent('foo');
322 sinon.assert.calledOnce(listener);
324 source.removeEventListener('foo', listener);
325 source.raiseEvent('foo');
326 sinon.assert.calledOnce(listener);
329 QUnit.test('removeEventListener() should work even if the listener ' +
330 'is removed during |raiseEvent|',
331 function(assert) {
332 var sink = {};
333 sink.listener = sinon.spy(function() {
334 source.removeEventListener('foo', sink.listener);
337 source.addEventListener('foo', sink.listener);
338 source.raiseEvent('foo');
339 sinon.assert.calledOnce(sink.listener);
341 source.raiseEvent('foo');
342 sinon.assert.calledOnce(sink.listener);
345 QUnit.test('encodeUtf8() can encode UTF8 strings', function(assert) {
346 /** @type {function(ArrayBuffer):Array} */
347 function toJsArray(arrayBuffer) {
348 var result = [];
349 var array = new Uint8Array(arrayBuffer);
350 for (var i = 0; i < array.length; ++i) {
351 result.push(array[i]);
353 return result;
356 // ASCII.
357 assert.deepEqual(toJsArray(base.encodeUtf8("ABC")), [0x41, 0x42, 0x43]);
359 // Some arbitrary characters from the basic Unicode plane.
360 assert.deepEqual(
361 toJsArray(base.encodeUtf8("挂Ѓф")),
362 [/* 挂 */ 0xE6, 0x8C, 0x82, /* Ѓ */ 0xD0, 0x83, /* ф */ 0xD1, 0x84]);
364 // Unicode surrogate pair for U+1F603.
365 assert.deepEqual(toJsArray(base.encodeUtf8("😃")),
366 [0xF0, 0x9F, 0x98, 0x83]);
369 QUnit.test('decodeUtf8() can decode UTF8 strings', function(assert) {
370 // ASCII.
371 assert.equal(base.decodeUtf8(new Uint8Array([0x41, 0x42, 0x43]).buffer),
372 "ABC");
374 // Some arbitrary characters from the basic Unicode plane.
375 assert.equal(
376 base.decodeUtf8(
377 new Uint8Array([/* 挂 */ 0xE6, 0x8C, 0x82,
378 /* Ѓ */ 0xD0, 0x83,
379 /* ф */ 0xD1, 0x84]).buffer),
380 "挂Ѓф");
382 // Unicode surrogate pair for U+1F603.
383 assert.equal(base.decodeUtf8(new Uint8Array([0xF0, 0x9F, 0x98, 0x83]).buffer),
384 "😃");
387 })();