diff options
Diffstat (limited to '')
-rw-r--r-- | dom/bindings/test/test_observablearray_helper.html | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/dom/bindings/test/test_observablearray_helper.html b/dom/bindings/test/test_observablearray_helper.html new file mode 100644 index 0000000000..d2b4897cac --- /dev/null +++ b/dom/bindings/test/test_observablearray_helper.html @@ -0,0 +1,376 @@ +<!-- Any copyright is dedicated to the Public Domain. +- http://creativecommons.org/publicdomain/zero/1.0/ --> +<!DOCTYPE HTML> +<html> +<head> +<title>Test Helpers of Observable Array Type</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<script> +/* global TestInterfaceObservableArray */ + +add_task(async function init() { + await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}); +}); + +add_task(function testObservableArray_helper_elementAt() { + let m = new TestInterfaceObservableArray(); + + [ + // [values, property, helper] + [[true, false], "observableArrayBoolean", m.booleanElementAtInternal.bind(m)], + [[new TestInterfaceObservableArray(), new TestInterfaceObservableArray()], + "observableArrayInterface", m.interfaceElementAtInternal.bind(m)], + [[{property: "test"}, {property: 2}], "observableArrayObject", + m.objectElementAtInternal.bind(m)], + ].forEach(function([values, property, helper]) { + m[property] = values; + + let t = m[property]; + ok(Array.isArray(t), "observable array should be an array type"); + is(t.length, values.length, "length of observable array"); + + for (let i = 0; i < values.length; i++) { + isDeeply(values[i], helper(i), `check index ${i}`); + } + + SimpleTest.doesThrow(() => { + helper(values.length); + }, `getting element outside the range should throw`); + }); +}); + +add_task(function testObservableArray_helper_replaceElementAt() { + let setCallbackCount = 0; + let deleteCallbackCount = 0; + let setCallbackTests = null; + let deleteCallbackTests = null; + + let m = new TestInterfaceObservableArray({ + setBooleanCallback(value, index) { + setCallbackCount++; + if (typeof setCallbackTests === 'function') { + setCallbackTests(value, index); + } + }, + deleteBooleanCallback(value, index) { + deleteCallbackCount++; + if (typeof deleteCallbackTests === 'function') { + deleteCallbackTests(value, index); + } + }, + }); + + let b = m.observableArrayBoolean; + ok(Array.isArray(b), "observable array should be an array type"); + is(b.length, 0, "length of observable array should be 0"); + + [ + // [index, value, shouldThrow] + [b.length + 1, false, true], + [b.length, false, false], + [b.length + 1, false, false], + [b.length + 1, true, false], + ].forEach(function([index, value, shouldThrow]) { + // Initialize + let oldValue = b[index]; + let oldLen = b.length; + setCallbackCount = 0; + deleteCallbackCount = 0; + setCallbackTests = function(_value, _index) { + info(`set callback for ${_index}`); + is(_value, value, "setCallbackTests: test value argument"); + is(_index, index, "setCallbackTests: test index argument"); + }; + deleteCallbackTests = function(_value, _index) { + info(`delete callback for ${_index}`); + is(_value, oldValue, "deleteCallbackTests: test value argument"); + is(_index, index, "deleteCallbackTests: test index argument"); + }; + + // Test + info(`setting value of property ${index} to ${value}`); + try { + m.booleanReplaceElementAtInternal(index, value); + ok(!shouldThrow, `setting value should not throw`); + } catch(e) { + ok(shouldThrow, `setting value throws ${e}`); + } + is(setCallbackCount, shouldThrow ? 0 : 1, "setCallback count"); + is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback count"); + is(b[index], shouldThrow ? oldValue : value, `property value`); + is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), `length of observable array`); + }); +}); + +add_task(function testObservableArray_helper_replaceElementAt_callback_throw() { + let setCallbackCount = 0; + let deleteCallbackCount = 0; + + let m = new TestInterfaceObservableArray({ + setBooleanCallback(value, index) { + setCallbackCount++; + if (value) { + throw new Error("setBooleanCallback"); + } + }, + deleteBooleanCallback(value, index) { + deleteCallbackCount++; + if (index < 2) { + throw new Error("deleteBooleanCallback"); + } + }, + }); + m.observableArrayBoolean = [false, false, false]; + + let b = m.observableArrayBoolean; + ok(Array.isArray(b), "observable array should be an array type"); + is(b.length, 3, "length of observable array should be 3"); + + [ + // [index, value, shouldThrow] + [b.length, true, true], + [b.length, false, false], + [b.length, true, true], + [0, false, true], + [0, true, true] + ].forEach(function([index, value, shouldThrow]) { + // Initialize + let oldValue = b[index]; + let oldLen = b.length; + setCallbackCount = 0; + deleteCallbackCount = 0; + + // Test + info(`setting value of property ${index} to ${value}`); + try { + m.booleanReplaceElementAtInternal(index, value); + ok(!shouldThrow, `setting value should not throw`); + } catch(e) { + ok(shouldThrow, `setting value throws ${e}`); + } + is(setCallbackCount, (shouldThrow && index < 2) ? 0 : 1, "setCallback count"); + is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback count"); + is(b[index], shouldThrow ? oldValue : value, "property value"); + is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), `length of observable array`); + }); +}); + +add_task(function testObservableArray_helper_appendElement() { + let setCallbackCount = 0; + let deleteCallbackCount = 0; + let setCallbackTests = null; + + let m = new TestInterfaceObservableArray({ + setBooleanCallback(value, index) { + setCallbackCount++; + if (typeof setCallbackTests === 'function') { + setCallbackTests(value, index); + } + }, + deleteBooleanCallback(value, index) { + deleteCallbackCount++; + }, + }); + + let b = m.observableArrayBoolean; + ok(Array.isArray(b), "observable array should be an array type"); + is(b.length, 0, "length of observable array should be 0"); + + [true, false, true, false].forEach(function(value) { + // Initialize + let oldLen = b.length; + let index = oldLen; + setCallbackCount = 0; + deleteCallbackCount = 0; + setCallbackTests = function(_value, _index) { + info(`set callback for ${_index}`); + is(_value, value, "setCallbackTests: test value argument"); + is(_index, index, "setCallbackTests: test index argument"); + }; + + // Test + info(`append ${value}`); + try { + m.booleanAppendElementInternal(value); + ok(true, `appending value should not throw`); + } catch(e) { + ok(false, `appending value throws ${e}`); + } + is(setCallbackCount, 1, "setCallback should be called"); + is(deleteCallbackCount, 0, "deleteCallback should not be called"); + is(b[index], value, `property value`); + is(b.length, oldLen + 1, `length of observable array`); + }); +}); + +add_task(function testObservableArray_helper_appendElement_callback_throw() { + let setCallbackCount = 0; + let deleteCallbackCount = 0; + + let m = new TestInterfaceObservableArray({ + setBooleanCallback(value, index) { + setCallbackCount++; + if (value) { + throw new Error("setBooleanCallback"); + } + }, + deleteBooleanCallback(value, index) { + deleteCallbackCount++; + }, + }); + m.observableArrayBoolean = [false, false, false]; + + let b = m.observableArrayBoolean; + ok(Array.isArray(b), "observable array should be an array type"); + is(b.length, 3, "length of observable array should be 3"); + + [true, false, true, false].forEach(function(value) { + // Initialize + let oldLen = b.length; + let index = oldLen; + let oldValue = b[index]; + let shouldThrow = value; + setCallbackCount = 0; + deleteCallbackCount = 0; + + // Test + info(`append ${value}`); + try { + m.booleanAppendElementInternal(value); + ok(!shouldThrow, `appending value should not throw`); + } catch(e) { + ok(shouldThrow, `appending value throws ${e}`); + } + is(setCallbackCount, 1, "setCallback should be called"); + is(deleteCallbackCount, 0, "deleteCallback should not be called"); + is(b[index], shouldThrow ? oldValue : value, "property value"); + is(b.length, shouldThrow ? oldLen : oldLen + 1, `length of observable array`); + }); +}); + +add_task(function testObservableArray_helper_removeLastElement() { + let setCallbackCount = 0; + let deleteCallbackCount = 0; + let deleteCallbackTests = null; + + let m = new TestInterfaceObservableArray({ + setBooleanCallback(value, index) { + setCallbackCount++; + }, + deleteBooleanCallback(value, index) { + deleteCallbackCount++; + if (typeof deleteCallbackTests === 'function') { + deleteCallbackTests(value, index); + } + }, + }); + m.observableArrayBoolean = [true, false, true, false]; + + let b = m.observableArrayBoolean; + ok(Array.isArray(b), "observable array should be an array type"); + is(b.length, 4, "length of observable array should be 4"); + + let oldValues = b.slice(); + while (oldValues.length) { + // Initialize + let oldValue = oldValues.pop(); + let index = oldValues.length; + setCallbackCount = 0; + deleteCallbackCount = 0; + deleteCallbackTests = function(_value, _index) { + info(`delete callback for ${_index}`); + is(_value, oldValue, "deleteCallbackTests: test value argument"); + is(_index, index, "deleteCallbackTests: test index argument"); + }; + + // Test + info(`remove last element`); + try { + m.booleanRemoveLastElementInternal(); + ok(true, `removing last element should not throw`); + } catch(e) { + ok(false, `removing last element throws ${e}`); + } + is(setCallbackCount, 0, "setCallback should not be called"); + is(deleteCallbackCount, 1, "deleteCallback should be called"); + isDeeply(b, oldValues, `property value`); + is(b.length, oldValues.length, `length of observable array`); + } + + // test when array is empty + setCallbackCount = 0; + deleteCallbackCount = 0; + SimpleTest.doesThrow(() => { + m.booleanRemoveLastElementInternal(); + }, `removing last element should throw when array is empty`); + is(setCallbackCount, 0, "setCallback should not be called"); + is(deleteCallbackCount, 0, "deleteCallback should not be called"); + is(b.length, 0, `length of observable array`); +}); + +add_task(function testObservableArray_helper_removeLastElement_callback_throw() { + let setCallbackCount = 0; + let deleteCallbackCount = 0; + + let m = new TestInterfaceObservableArray({ + setBooleanCallback(value, index) { + setCallbackCount++; + }, + deleteBooleanCallback(value, index) { + deleteCallbackCount++; + if (value) { + throw new Error("deleteBooleanCallback"); + } + }, + }); + m.observableArrayBoolean = [false, true, false, false]; + + let b = m.observableArrayBoolean; + ok(Array.isArray(b), "observable array should be an array type"); + is(b.length, 4, "length of observable array should be 4"); + + let shouldThrow = false; + while (!shouldThrow && b.length) { + // Initialize + let oldValues = b.slice(); + let oldLen = b.length; + shouldThrow = oldValues[oldLen - 1]; + setCallbackCount = 0; + deleteCallbackCount = 0; + + // Test + info(`remove last element`); + try { + m.booleanRemoveLastElementInternal(); + ok(!shouldThrow, `removing last element should not throw`); + } catch(e) { + ok(shouldThrow, `removing last element throws ${e}`); + } + is(setCallbackCount, 0, "setCallback should not be called"); + is(deleteCallbackCount, 1, "deleteCallback should be called"); + isDeeply(b, shouldThrow ? oldValues : oldValues.slice(0, oldLen - 1), `property value`); + is(b.length, shouldThrow ? oldLen : oldLen - 1, `length of observable array`); + } +}); + +add_task(function testObservableArray_helper_length() { + let m = new TestInterfaceObservableArray(); + let b = m.observableArrayBoolean; + ok(Array.isArray(b), "observable array should be an array type"); + is(b.length, 0, "length of observable array"); + + [ + [false, true, false, true], + [true, false], + [false, true, false], + ].forEach(function(values) { + m.observableArrayBoolean = values; + is(b.length, m.booleanLengthInternal(), "length helper function"); + }); +}); +</script> +</body> +</html> |