summaryrefslogtreecommitdiffstats
path: root/dom/bindings/test/test_observablearray_helper.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/bindings/test/test_observablearray_helper.html376
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>