Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / dom / bindings / test / test_observablearray.html
blob56e35eeca5a94743c7c06e16463bd56d6a64a34f
1 <!-- Any copyright is dedicated to the Public Domain.
2 - http://creativecommons.org/publicdomain/zero/1.0/ -->
3 <!DOCTYPE HTML>
4 <html>
5 <head>
6 <title>Test Observable Array Type</title>
7 <script src="/tests/SimpleTest/SimpleTest.js"></script>
8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
9 </head>
10 <body>
11 <script>
12 /* global TestInterfaceObservableArray */
14 add_task(async function init() {
15 await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]});
16 });
18 add_task(function testObservableArray_length() {
19 let setCallbackCount = 0;
20 let deleteCallbackCount = 0;
21 let deleteCallbackTests = null;
23 let m = new TestInterfaceObservableArray({
24 setBooleanCallback() {
25 setCallbackCount++;
27 deleteBooleanCallback(value, index) {
28 deleteCallbackCount++;
29 if (typeof deleteCallbackTests === 'function') {
30 deleteCallbackTests(value, index);
33 });
34 m.observableArrayBoolean = [true, true, true, true, true];
36 let b = m.observableArrayBoolean;
37 ok(Array.isArray(b), "observable array should be an array type");
38 is(b.length, 5, "length of observable array should be 5");
41 // [length, shouldThrow, expectedResult]
42 ["invalid", true, false],
43 [b.length + 1, false, false],
44 [b.length, false, true],
45 [b.length - 1, false, true],
46 [0, false, true],
47 ].forEach(function([length, shouldThrow, expectedResult]) {
48 // Initialize
49 let oldValues = b.slice();
50 let oldLen = b.length;
51 let shouldSuccess = !shouldThrow && expectedResult;
52 setCallbackCount = 0;
53 deleteCallbackCount = 0;
54 deleteCallbackTests = null;
55 if (shouldSuccess) {
56 let deleteCallbackIndex = b.length - 1;
57 deleteCallbackTests = function(_value, _index) {
58 info(`delete callback for ${_index}`);
59 is(_value, oldValues[deleteCallbackIndex], "deleteCallbackTests: test value argument");
60 is(_index, deleteCallbackIndex, "deleteCallbackTests: test index argument");
61 deleteCallbackIndex--;
65 // Test
66 info(`setting length to ${length}`);
67 try {
68 b.length = length;
69 ok(!shouldThrow, `setting length should throw`);
70 } catch(e) {
71 ok(shouldThrow, `setting length throws ${e}`);
73 is(setCallbackCount, 0, "setCallback should not be called");
74 is(deleteCallbackCount, shouldSuccess ? (oldLen - length) : 0, "deleteCallback count");
75 isDeeply(b, shouldSuccess ? oldValues.slice(0, length) : oldValues, "property values");
76 is(b.length, shouldSuccess ? length : oldLen, `length of observable array`);
77 });
78 });
80 add_task(function testObservableArray_length_callback_throw() {
81 let setCallbackCount = 0;
82 let deleteCallbackCount = 0;
84 let m = new TestInterfaceObservableArray({
85 setBooleanCallback() {
86 setCallbackCount++;
88 deleteBooleanCallback(value) {
89 deleteCallbackCount++;
90 if (value) {
91 throw new Error("deleteBooleanCallback");
94 });
95 m.observableArrayBoolean = [true, true, false, false, false];
97 let b = m.observableArrayBoolean;
98 ok(Array.isArray(b), "observable array should be an array type");
99 is(b.length, 5, "length of observable array should be 5");
101 // Initialize
102 setCallbackCount = 0;
103 deleteCallbackCount = 0;
105 // Test
106 info(`setting length to 0`);
107 try {
108 b.length = 0;
109 ok(false, `setting length should throw`);
110 } catch(e) {
111 ok(true, `setting length throws ${e}`);
113 is(setCallbackCount, 0, "setCallback should not be called");
114 is(deleteCallbackCount, 4, "deleteCallback should be called");
115 isDeeply(b, [true, true], "property values");
116 is(b.length, 2, `length of observable array`);
119 add_task(function testObservableArray_setter() {
120 let setCallbackCount = 0;
121 let deleteCallbackCount = 0;
122 let setCallbackTests = null;
123 let deleteCallbackTests = null;
125 let m = new TestInterfaceObservableArray({
126 setBooleanCallback(value, index) {
127 setCallbackCount++;
128 if (typeof setCallbackTests === 'function') {
129 setCallbackTests(value, index);
132 deleteBooleanCallback(value, index) {
133 deleteCallbackCount++;
134 if (typeof deleteCallbackTests === 'function') {
135 deleteCallbackTests(value, index);
140 let b = m.observableArrayBoolean;
141 ok(Array.isArray(b), "observable array should be an array type");
142 is(b.length, 0, "length of observable array should be 0");
145 // [values, shouldThrow]
146 ["invalid", true],
147 [[1,[],{},"invalid"], false],
148 [[0,NaN,null,undefined,""], false],
149 [[true,true], false],
150 [[false,false,false], false],
151 ].forEach(function([values, shouldThrow]) {
152 // Initialize
153 let oldValues = b.slice();
154 let oldLen = b.length;
155 setCallbackCount = 0;
156 deleteCallbackCount = 0;
157 setCallbackTests = null;
158 deleteCallbackTests = null;
159 if (!shouldThrow) {
160 let setCallbackIndex = 0;
161 setCallbackTests = function(_value, _index) {
162 info(`set callback for ${_index}`);
163 is(_value, !!values[setCallbackIndex], "setCallbackTests: test value argument");
164 is(_index, setCallbackIndex, "setCallbackTests: test index argument");
165 setCallbackIndex++;
168 let deleteCallbackIndex = b.length - 1;
169 deleteCallbackTests = function(_value, _index) {
170 info(`delete callback for ${_index}`);
171 is(_value, oldValues[deleteCallbackIndex], "deleteCallbackTests: test value argument");
172 is(_index, deleteCallbackIndex, "deleteCallbackTests: test index argument");
173 deleteCallbackIndex--;
177 // Test
178 info(`setting value to ${JSON.stringify(values)}`);
179 try {
180 m.observableArrayBoolean = values;
181 ok(!shouldThrow, `setting value should not throw`);
182 } catch(e) {
183 ok(shouldThrow, `setting value throws ${e}`);
185 is(setCallbackCount, shouldThrow ? 0 : values.length, "setCallback count");
186 is(deleteCallbackCount, oldLen, "deleteCallback should be called");
187 isDeeply(b, shouldThrow ? [] : values.map(v => !!v), "property values");
188 is(b.length, shouldThrow ? 0 : values.length, `length of observable array`);
192 add_task(function testObservableArray_setter_invalid_item() {
193 let setCallbackCount = 0;
194 let deleteCallbackCount = 0;
195 let setCallbackTests = null;
196 let deleteCallbackTests = null;
198 let m = new TestInterfaceObservableArray({
199 setInterfaceCallback(value, index) {
200 setCallbackCount++;
201 if (typeof setCallbackTests === 'function') {
202 setCallbackTests(value, index);
205 deleteInterfaceCallback(value, index) {
206 deleteCallbackCount++;
207 if (typeof deleteCallbackTests === 'function') {
208 deleteCallbackTests(value, index);
213 let b = m.observableArrayInterface;
214 ok(Array.isArray(b), "observable array should be an array type");
215 is(b.length, 0, "length of observable array should be 0");
218 // [values, shouldThrow]
219 [[m,m,m,m], false],
220 [["invalid"], true],
221 [[m,m], false],
222 [[m,"invalid"], true],
223 [[m,m,m], false],
224 ].forEach(function([values, shouldThrow]) {
225 // Initialize
226 let oldValues = b.slice();
227 let oldLen = b.length;
228 let setCallbackIndex = 0;
229 setCallbackTests = function(_value, _index) {
230 info(`set callback for ${_index}`);
231 is(_value, values[setCallbackIndex], "setCallbackTests: test value argument");
232 is(_index, setCallbackIndex, "setCallbackTests: test index argument");
233 setCallbackIndex++;
235 let deleteCallbackIndex = b.length - 1;
236 deleteCallbackTests = function(_value, _index) {
237 info(`delete callback for ${_index}`);
238 is(_value, oldValues[deleteCallbackIndex], "deleteCallbackTests: test value argument");
239 is(_index, deleteCallbackIndex, "deleteCallbackTests: test index argument");
240 deleteCallbackIndex--;
242 setCallbackCount = 0;
243 deleteCallbackCount = 0;
245 // Test
246 info(`setting value to ${values}`);
247 try {
248 m.observableArrayInterface = values;
249 ok(!shouldThrow, `setting value should not throw`);
250 } catch(e) {
251 ok(shouldThrow, `setting value throws ${e}`);
253 is(setCallbackCount, shouldThrow ? 0 : values.length, "setCallback count");
254 is(deleteCallbackCount, shouldThrow ? 0 : oldLen, "deleteCallback should be called");
255 isDeeply(b, shouldThrow ? oldValues : values, "property values");
256 is(b.length, shouldThrow ? oldLen : values.length, `length of observable array`);
260 add_task(function testObservableArray_setter_callback_throw() {
261 let setCallbackCount = 0;
262 let deleteCallbackCount = 0;
264 let m = new TestInterfaceObservableArray({
265 setBooleanCallback(value, index) {
266 setCallbackCount++;
267 if (index >= 3) {
268 throw new Error("setBooleanCallback");
271 deleteBooleanCallback(value) {
272 deleteCallbackCount++;
273 if (value) {
274 throw new Error("deleteBooleanCallback");
278 m.observableArrayBoolean = [false, false, false];
280 let b = m.observableArrayBoolean;
281 ok(Array.isArray(b), "observable array should be an array type");
282 is(b.length, 3, "length of observable array should be 3");
285 // [values, shouldThrow, expectedLength, expectedSetCbCount, expectedDeleteCbCount]
286 [[false,false], false, 2, 2, 3],
287 [[false,true,false,false], true, 3, 4, 2],
288 [[false,false,true], true, 2, 0, 2],
289 ].forEach(function([values, shouldThrow, expectedLength, expectedSetCbCount,
290 expectedDeleteCbCount]) {
291 // Initialize
292 setCallbackCount = 0;
293 deleteCallbackCount = 0;
295 // Test
296 info(`setting value to ${values}`);
297 try {
298 m.observableArrayBoolean = values;
299 ok(!shouldThrow, `setting value should not throw`);
300 } catch(e) {
301 ok(shouldThrow, `setting length throws ${e}`);
303 is(setCallbackCount, expectedSetCbCount, "setCallback should be called");
304 is(deleteCallbackCount, expectedDeleteCbCount, "deleteCallback should be called");
305 is(b.length, expectedLength, `length of observable array`);
309 add_task(function testObservableArray_indexed_setter() {
310 let setCallbackCount = 0;
311 let deleteCallbackCount = 0;
312 let setCallbackTests = null;
313 let deleteCallbackTests = null;
315 let m = new TestInterfaceObservableArray({
316 setBooleanCallback(value, index) {
317 setCallbackCount++;
318 if (typeof setCallbackTests === 'function') {
319 setCallbackTests(value, index);
322 deleteBooleanCallback(value, index) {
323 deleteCallbackCount++;
324 if (typeof deleteCallbackTests === 'function') {
325 deleteCallbackTests(value, index);
330 let b = m.observableArrayBoolean;
331 ok(Array.isArray(b), "observable array should be an array type");
332 is(b.length, 0, "length of observable array should be 0");
335 // [index, value, expectedResult]
336 [b.length + 1, false, false],
337 [b.length, false, true],
338 [b.length + 1, false, true],
339 [b.length + 1, true, true],
340 ].forEach(function([index, value, expectedResult]) {
341 // Initialize
342 let oldValue = b[index];
343 let oldLen = b.length;
344 setCallbackCount = 0;
345 deleteCallbackCount = 0;
346 setCallbackTests = function(_value, _index) {
347 info(`set callback for ${_index}`);
348 is(_value, value, "setCallbackTests: test value argument");
349 is(_index, index, "setCallbackTests: test index argument");
351 deleteCallbackTests = function(_value, _index) {
352 info(`delete callback for ${_index}`);
353 is(_value, oldValue, "deleteCallbackTests: test value argument");
354 is(_index, index, "deleteCallbackTests: test index argument");
357 // Test
358 info(`setting value of property ${index} to ${value}`);
359 try {
360 b[index] = value;
361 ok(true, `setting value should not throw`);
362 } catch(e) {
363 ok(false, `setting value throws ${e}`);
365 is(setCallbackCount, expectedResult ? 1 : 0, "setCallback should be called");
366 is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback should be called");
367 is(b[index], expectedResult ? value : oldValue, `property value`);
368 is(b.length, expectedResult ? Math.max(oldLen, index + 1) : oldLen, `length of observable array`);
372 add_task(function testObservableArray_indexed_setter_invalid() {
373 let setCallbackCount = 0;
374 let deleteCallbackCount = 0;
375 let setCallbackTests = null;
376 let deleteCallbackTests = null;
378 let m = new TestInterfaceObservableArray({
379 setInterfaceCallback(value, index) {
380 setCallbackCount++;
381 if (typeof setCallbackTests === 'function') {
382 setCallbackTests(value, index);
385 deleteInterfaceCallback(value, index) {
386 deleteCallbackCount++;
387 if (typeof deleteCallbackTests === 'function') {
388 deleteCallbackTests(value, index);
393 let b = m.observableArrayInterface;
394 ok(Array.isArray(b), "observable array should be an array type");
395 is(b.length, 0, "length of observable array should be 0");
398 // [index, value, shouldThrow]
399 [b.length, "invalid", true],
400 [b.length, m, false],
401 [b.length + 1, m, false],
402 [b.length + 1, "invalid", true],
403 ].forEach(function([index, value, shouldThrow]) {
404 // Initialize
405 let oldValue = b[index];
406 let oldLen = b.length;
407 setCallbackCount = 0;
408 deleteCallbackCount = 0;
409 setCallbackTests = function(_value, _index) {
410 info(`set callback for ${_index}`);
411 is(_value, value, "setCallbackTests: test value argument");
412 is(_index, index, "setCallbackTests: test index argument");
414 deleteCallbackTests = function(_value, _index) {
415 info(`delete callback for ${_index}`);
416 is(_value, oldValue, "deleteCallbackTests: test value argument");
417 is(_index, index, "deleteCallbackTests: test index argument");
420 // Test
421 info(`setting value of property ${index} to ${value}`);
422 try {
423 b[index] = value;
424 ok(!shouldThrow, `setting value should not throw`);
425 } catch(e) {
426 ok(shouldThrow, `setting value throws ${e}`);
428 is(setCallbackCount, shouldThrow ? 0 : 1, "setCallback count");
429 is(deleteCallbackCount, ((oldLen > index) && !shouldThrow) ? 1 : 0, "deleteCallback count");
430 is(b[index], shouldThrow ? oldValue : value, `property value`);
431 is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), `length of observable array`);
435 add_task(function testObservableArray_indexed_setter_callback_throw() {
436 let setCallbackCount = 0;
437 let deleteCallbackCount = 0;
439 let m = new TestInterfaceObservableArray({
440 setBooleanCallback(value) {
441 setCallbackCount++;
442 if (value) {
443 throw new Error("setBooleanCallback");
446 deleteBooleanCallback(value, index) {
447 deleteCallbackCount++;
448 if (index < 2) {
449 throw new Error("deleteBooleanCallback");
453 m.observableArrayBoolean = [false, false, false];
455 let b = m.observableArrayBoolean;
456 ok(Array.isArray(b), "observable array should be an array type");
457 is(b.length, 3, "length of observable array should be 3");
460 // [index, value, shouldThrow]
461 [b.length, true, true],
462 [b.length, false, false],
463 [b.length, true, true],
464 [0, false, true],
465 [0, true, true]
466 ].forEach(function([index, value, shouldThrow]) {
467 // Initialize
468 let oldValue = b[index];
469 let oldLen = b.length;
470 setCallbackCount = 0;
471 deleteCallbackCount = 0;
473 // Test
474 info(`setting value of property ${index} to ${value}`);
475 try {
476 b[index] = value;
477 ok(!shouldThrow, `setting value should not throw`);
478 } catch(e) {
479 ok(shouldThrow, `setting value throws ${e}`);
481 is(setCallbackCount, (shouldThrow && index < 2) ? 0 : 1, "setCallback should be called");
482 is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback should be called");
483 is(b[index], shouldThrow ? oldValue : value, "property value");
484 is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), `length of observable array`);
488 add_task(function testObservableArray_object() {
489 let setCallbackCount = 0;
490 let deleteCallbackCount = 0;
491 let callbackIndex = 0;
493 let values = [
494 {property1: false, property2: "property2"},
495 {property1: [], property2: 2},
498 let m = new TestInterfaceObservableArray({
499 setObjectCallback(value, index) {
500 setCallbackCount++;
501 is(index, callbackIndex++, "setCallbackTests: test index argument");
502 isDeeply(values[index], value, "setCallbackTests: test value argument");
504 deleteObjectCallback() {
505 deleteCallbackCount++;
509 m.observableArrayObject = values;
511 let b = m.observableArrayObject;
512 ok(Array.isArray(b), "observable array should be an array type");
513 is(b.length, 2, "length of observable array should be 2");
514 is(setCallbackCount, values.length, "setCallback should be called");
515 is(deleteCallbackCount, 0, "deleteCallback should not be called");
517 for(let i = 0; i < values.length; i++) {
518 isDeeply(values[i], b[i], `check index ${i}`);
522 add_task(function testObservableArray_xrays() {
523 let m = new TestInterfaceObservableArray({
524 setObjectCallback() {
525 ok(false, "Shouldn't reach setObjectCallback");
527 deleteObjectCallback() {
528 ok(false, "Shouldn't reach deleteObjectCallback");
532 let wrapper = SpecialPowers.wrap(m);
533 ok(SpecialPowers.Cu.isXrayWrapper(wrapper), "Should be a wrapper");
534 let observableArray = wrapper.observableArrayBoolean;
535 ok(!!observableArray, "Should not throw");
536 is("length" in observableArray, false, "Should be opaque");
538 try {
539 wrapper.observableArrayBoolean = [true, false, false];
540 ok(false, "Expected to throw, for now");
541 } catch (ex) {}
544 </script>
545 </body>
546 </html>