OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * testharness-helpers contains various useful extensions to testharness.js to |
| 3 * allow them to be used across multiple tests before they have been |
| 4 * upstreamed. This file is intended to be usable from both document and worker |
| 5 * environments, so code should for example not rely on the DOM. |
| 6 */ |
| 7 |
| 8 // Returns a promise that fulfills after the provided |promise| is fulfilled. |
| 9 // The |test| succeeds only if |promise| rejects with an exception matching |
| 10 // |code|. Accepted values for |code| follow those accepted for assert_throws(). |
| 11 // The optional |description| describes the test being performed. |
| 12 // |
| 13 // E.g.: |
| 14 // assert_promise_rejects( |
| 15 // new Promise(...), // something that should throw an exception. |
| 16 // 'NotFoundError', |
| 17 // 'Should throw NotFoundError.'); |
| 18 // |
| 19 // assert_promise_rejects( |
| 20 // new Promise(...), |
| 21 // new TypeError(), |
| 22 // 'Should throw TypeError'); |
| 23 function assert_promise_rejects(promise, code, description) { |
| 24 return promise.then( |
| 25 function() { |
| 26 throw 'assert_promise_rejects: ' + description + ' Promise did not reject.
'; |
| 27 }, |
| 28 function(e) { |
| 29 if (code !== undefined) { |
| 30 assert_throws(code, function() { throw e; }, description); |
| 31 } |
| 32 }); |
| 33 } |
| 34 |
| 35 // Asserts that two objects |actual| and |expected| are weakly equal under the |
| 36 // following definition: |
| 37 // |
| 38 // |a| and |b| are weakly equal if any of the following are true: |
| 39 // 1. If |a| is not an 'object', and |a| === |b|. |
| 40 // 2. If |a| is an 'object', and all of the following are true: |
| 41 // 2.1 |a.p| is weakly equal to |b.p| for all own properties |p| of |a|. |
| 42 // 2.2 Every own property of |b| is an own property of |a|. |
| 43 // |
| 44 // This is a replacement for the the version of assert_object_equals() in |
| 45 // testharness.js. The latter doesn't handle own properties correctly. I.e. if |
| 46 // |a.p| is not an own property, it still requires that |b.p| be an own |
| 47 // property. |
| 48 // |
| 49 // Note that |actual| must not contain cyclic references. |
| 50 self.assert_object_equals = function(actual, expected, description) { |
| 51 var object_stack = []; |
| 52 |
| 53 function _is_equal(actual, expected, prefix) { |
| 54 if (typeof actual !== 'object') { |
| 55 assert_equals(actual, expected, prefix); |
| 56 return; |
| 57 } |
| 58 assert_true(typeof expected === 'object', prefix); |
| 59 assert_equals(object_stack.indexOf(actual), -1, |
| 60 prefix + ' must not contain cyclic references.'); |
| 61 |
| 62 object_stack.push(actual); |
| 63 |
| 64 Object.getOwnPropertyNames(expected).forEach(function(property) { |
| 65 assert_own_property(actual, property, prefix); |
| 66 _is_equal(actual[property], expected[property], |
| 67 prefix + '.' + property); |
| 68 }); |
| 69 Object.getOwnPropertyNames(actual).forEach(function(property) { |
| 70 assert_own_property(expected, property, prefix); |
| 71 }); |
| 72 |
| 73 object_stack.pop(); |
| 74 } |
| 75 |
| 76 function _brand(object) { |
| 77 return Object.prototype.toString.call(object).match(/^\[object (.*)\]$/)[1]; |
| 78 } |
| 79 |
| 80 _is_equal(actual, expected, |
| 81 (description ? description + ': ' : '') + _brand(expected)); |
| 82 }; |
| 83 |
| 84 // Equivalent to assert_in_array, but uses a weaker equivalence relation |
| 85 // (assert_object_equals) than '==='. |
| 86 function assert_object_in_array(actual, expected_array, description) { |
| 87 assert_true(expected_array.some(function(element) { |
| 88 try { |
| 89 assert_object_equals(actual, element); |
| 90 return true; |
| 91 } catch (e) { |
| 92 return false; |
| 93 } |
| 94 }), description); |
| 95 } |
| 96 |
| 97 // Assert that the two arrays |actual| and |expected| contain the same set of |
| 98 // elements as determined by assert_object_equals. The order is not significant. |
| 99 // |
| 100 // |expected| is assumed to not contain any duplicates as determined by |
| 101 // assert_object_equals(). |
| 102 function assert_array_equivalent(actual, expected, description) { |
| 103 assert_true(Array.isArray(actual), description); |
| 104 assert_equals(actual.length, expected.length, description); |
| 105 expected.forEach(function(expected_element) { |
| 106 // assert_in_array treats the first argument as being 'actual', and the |
| 107 // second as being 'expected array'. We are switching them around because |
| 108 // we want to be resilient against the |actual| array containing |
| 109 // duplicates. |
| 110 assert_object_in_array(expected_element, actual, description); |
| 111 }); |
| 112 } |
| 113 |
| 114 // Asserts that two arrays |actual| and |expected| contain the same set of |
| 115 // elements as determined by assert_object_equals(). The corresponding elements |
| 116 // must occupy corresponding indices in their respective arrays. |
| 117 function assert_array_objects_equals(actual, expected, description) { |
| 118 assert_true(Array.isArray(actual), description); |
| 119 assert_equals(actual.length, expected.length, description); |
| 120 actual.forEach(function(value, index) { |
| 121 assert_object_equals(value, expected[index], |
| 122 description + ' : object[' + index + ']'); |
| 123 }); |
| 124 } |
| 125 |
| 126 // Asserts that |object| that is an instance of some interface has the attribute |
| 127 // |attribute_name| following the conditions specified by WebIDL, but it's |
| 128 // acceptable that the attribute |attribute_name| is an own property of the |
| 129 // object because we're in the middle of moving the attribute to a prototype |
| 130 // chain. Once we complete the transition to prototype chains, |
| 131 // assert_will_be_idl_attribute must be replaced with assert_idl_attribute |
| 132 // defined in testharness.js. |
| 133 // |
| 134 // FIXME: Remove assert_will_be_idl_attribute once we complete the transition |
| 135 // of moving the DOM attributes to prototype chains. (http://crbug.com/43394) |
| 136 function assert_will_be_idl_attribute(object, attribute_name, description) { |
| 137 assert_true(typeof object === "object", description); |
| 138 |
| 139 assert_true("hasOwnProperty" in object, description); |
| 140 |
| 141 // Do not test if |attribute_name| is not an own property because |
| 142 // |attribute_name| is in the middle of the transition to a prototype |
| 143 // chain. (http://crbug.com/43394) |
| 144 |
| 145 assert_true(attribute_name in object, description); |
| 146 } |
| 147 |
| 148 // Stringifies a DOM object. This function stringifies not only own properties |
| 149 // but also DOM attributes which are on a prototype chain. Note that |
| 150 // JSON.stringify only stringifies own properties. |
| 151 function stringifyDOMObject(object) |
| 152 { |
| 153 function deepCopy(src) { |
| 154 if (typeof src != "object") |
| 155 return src; |
| 156 var dst = Array.isArray(src) ? [] : {}; |
| 157 for (var property in src) { |
| 158 dst[property] = deepCopy(src[property]); |
| 159 } |
| 160 return dst; |
| 161 } |
| 162 return JSON.stringify(deepCopy(object)); |
| 163 } |
OLD | NEW |