UNPKG

fugafacere

Version:

A pure-JS implementation of the W3C's Canvas-2D Context API that can run on top of either Expo Graphics or a browser WebGL context.

352 lines (310 loc) 11.4 kB
const DOMException = require("domexception"); export function _assert(t, expression, description) { return assert_true(t, expression, description); } export function assert_true(t, actual, description) { t.expect(actual).toBe(true); } export function assert_false(t, actual, description) { t.expect(actual).toBe(false); } function same_value(x, y) { if (y !== y) { //NaN case return x !== x; } if (x === 0 && y === 0) { //Distinguish +0 and -0 return 1/x === 1/y; } return x === y; } export function assert_equals(t, actual, expected, description) { /* * Test if two primitives are equal or two objects * are the same object */ if (typeof actual != typeof expected) { throw new Error("expected equality but got conflicting types (" + typeof actual + " vs " + typeof expected + ")"); } t.expect(same_value(actual, expected)).toBe(true); } export function assert_not_equals(t, actual, expected, description) { /* * Test if two primitives are unequal or two objects * are different objects */ t.expect(!same_value(actual, expected)).toBe(true); } export function assert_in_array(t, actual, expected, description) { t.expect(expected).toContain(actual); } export function assert_object_equals(t, actual, expected, description) { //This needs to be improved a great deal function check_equal(actual, expected, stack) { stack.push(actual); var p; for (p in actual) { t.expect(expected.hasOwnProperty(p)).toBe(true); if (typeof actual[p] === "object" && actual[p] !== null) { if (stack.indexOf(actual[p]) === -1) { check_equal(actual[p], expected[p], stack); } } else { t.expect(same_value(actual[p], expected[p])).toBe(true); } } for (p in expected) { t.expect(actual.hasOwnProperty(p)).toBe(true); } stack.pop(); } check_equal(actual, expected, []); } export function assert_array_equals(t, actual, expected, description) { t.expect(typeof actual === "object" && actual !== null && "length" in actual).toBe(true); t.expect(actual.length).toBe(expected.length); for (var i = 0; i < actual.length; i++) { t.expect(actual.hasOwnProperty(i)).toBe(expected.hasOwnProperty(i)); t.expect(same_value(expected[i], actual[i])).toBe(true); } } export function assert_array_approx_equals(t, actual, expected, epsilon, description) { /* * Test if two primitive arrays are equal withing +/- epsilon */ t.expect(actual.length).toBe(expected.length); for (var i = 0; i < actual.length; i++) { t.expect(actual.hasOwnProperty(i)).toBe(expected.hasOwnProperty(i)); t.expect(typeof actual[i]).toBe("number"); t.expect(Math.abs(actual[i] - expected[i]) <= epsilon).toBe(true); } } export function assert_approx_equals(t, actual, expected, epsilon, description) { /* * Test if two primitive numbers are equal withing +/- epsilon */ t.expect(typeof actual).toBe("number"); t.expect(Math.abs(actual - expected) <= epsilon).toBe(true); } export function assert_less_than(t, actual, expected, description) { /* * Test if a primitive number is less than another */ t.expect(typeof actual).toBe("number"); t.expect(actual).toBeLessThan(expected); } export function assert_greater_than(t, actual, expected, description) { /* * Test if a primitive number is greater than another */ t.expect(typeof actual).toBe("number"); t.expect(actual).toBeGreaterThan(expected); } export function assert_between_exclusive(t, actual, lower, upper, description) { /* * Test if a primitive number is between two others */ t.expect(typeof actual).toBe("number"); t.expect(actual).toBeGreaterThan(lower); t.expect(actual).toBeLessThan(upper); } export function assert_less_than_equal(t, actual, expected, description) { /* * Test if a primitive number is less than or equal to another */ t.expect(typeof actual).toBe("number"); t.expect(actual <= expected).toBe(true); } export function assert_greater_than_equal(t, actual, expected, description) { /* * Test if a primitive number is greater than or equal to another */ t.expect(typeof actual).toBe("number"); t.expect(actual >= expected).toBe(true); } export function assert_between_inclusive(t, actual, lower, upper, description) { /* * Test if a primitive number is between to two others or equal to either of them */ t.expect(typeof actual).toBe("number"); t.expect(actual >= lower && actual <= upper).toBe(true); } export function assert_regexp_match(t, actual, expected, description) { /* * Test if a string (actual) matches a regexp (expected) */ t.expect(expected.test(actual)).toBe(true); } export function assert_class_string(t, object, class_string, description) { assert_equals(t, {}.toString.call(object), "[object " + class_string + "]", description); } export function assert_exists(t, object, property_name, description) { t.expect(object.hasOwnProperty(property_name)).toBe(true); } export function assert_own_property(t, object, property_name, description) { t.expect(object.hasOwnProperty(property_name)).toBe(true); } export function assert_not_exists(t, object, property_name, description) { t.expect(!object.hasOwnProperty(property_name)).toBe(true); } export function assert_inherits(object, property_name, description) { t.expect(typeof object === "object" || typeof object === "function").toBe(true); t.expect("hasOwnProperty" in object).toBe(true); t.expect(!object.hasOwnProperty(property_name)).toBe(true); t.expect(property_name in object).toBe(true); } export function assert_idl_attribute(object, property_name, description) { t.expect(typeof object === "object" || typeof object === "function").toBe(true); t.expect("hasOwnProperty" in object).toBe(true); t.expect(!object.hasOwnProperty(property_name)).toBe(true); t.expect(property_name in object).toBe(true); } export function assert_readonly(t, object, property_name, description) { var result = false; var initial_value = object[property_name]; try { //Note that this can have side effects in the case where //the property has PutForwards object[property_name] = initial_value + "a"; //XXX use some other value here? result = same_value(object[property_name], initial_value); } finally { object[property_name] = initial_value; } t.expect(result).toBe(true); } export function assert_throws(t, code, func, description) { try { func.call(this); t.expect(false).toBe(true); } catch (e) { t.expect(typeof e).toBe("object"); t.expect(e !== null).toBe(true); if (code === null) { throw new Error('Test bug: need to pass exception to assert_throws()'); } if (typeof code === "object") { t.expect("name" in e && e.name == code.name).toBe(true); return; } var code_name_map = {} code_name_map["INDEX_SIZE_ERR"] = 'IndexSizeError'; code_name_map["HIERARCHY_REQUEST_ERR"] = 'HierarchyRequestError'; code_name_map["WRONG_DOCUMENT_ERR"] = 'WrongDocumentError'; code_name_map["INVALID_CHARACTER_ERR"] = 'InvalidCharacterError'; code_name_map["NO_MODIFICATION_ALLOWED_ERR"] = 'NoModificationAllowedError'; code_name_map["NOT_FOUND_ERR"] = 'NotFoundError'; code_name_map["NOT_SUPPORTED_ERR"] = 'NotSupportedError'; code_name_map["INUSE_ATTRIBUTE_ERR"] = 'InUseAttributeError'; code_name_map["INVALID_STATE_ERR"] = 'InvalidStateError'; code_name_map["SYNTAX_ERR"] = 'SyntaxError'; code_name_map["INVALID_MODIFICATION_ERR"] = 'InvalidModificationError'; code_name_map["NAMESPACE_ERR"] = 'NamespaceError'; code_name_map["INVALID_ACCESS_ERR"] = 'InvalidAccessError'; code_name_map["TYPE_MISMATCH_ERR"] = 'TypeMismatchError'; code_name_map["SECURITY_ERR"] = 'SecurityError'; code_name_map["NETWORK_ERR"] = 'NetworkError'; code_name_map["ABORT_ERR"] = 'AbortError'; code_name_map["URL_MISMATCH_ERR"] = 'URLMismatchError'; code_name_map["QUOTA_EXCEEDED_ERR"] = 'QuotaExceededError'; code_name_map["TIMEOUT_ERR"] = 'TimeoutError'; code_name_map["INVALID_NODE_TYPE_ERR"] = 'InvalidNodeTypeError'; code_name_map["DATA_CLONE_ERR"] = 'DataCloneError'; var name = code in code_name_map ? code_name_map[code] : code; var name_code_map = { 'IndexSizeError': 1, 'HierarchyRequestError': 3, 'WrongDocumentError': 4, 'InvalidCharacterError': 5, 'NoModificationAllowedError': 7, 'NotFoundError': 8, 'NotSupportedError': 9, 'InUseAttributeError': 10, 'InvalidStateError': 11, 'SyntaxError': 12, 'InvalidModificationError': 13, 'NamespaceError': 14, 'InvalidAccessError': 15, 'TypeMismatchError': 17, 'SecurityError': 18, 'NetworkError': 19, 'AbortError': 20, 'URLMismatchError': 21, 'QuotaExceededError': 22, 'TimeoutError': 23, 'InvalidNodeTypeError': 24, 'DataCloneError': 25, 'EncodingError': 0, 'NotReadableError': 0, 'UnknownError': 0, 'ConstraintError': 0, 'DataError': 0, 'TransactionInactiveError': 0, 'ReadOnlyError': 0, 'VersionError': 0, 'OperationError': 0, 'NotAllowedError': 0 }; if (!(name in name_code_map)) { throw new Error('Test bug: unrecognized DOMException code "' + code + '" passed to assert_throws()'); } var required_props = { code: name_code_map[name] }; if (required_props.code === 0 || ("name" in e && e.name !== e.name.toUpperCase() && e.name !== "DOMException")) { // New style exception: also test the name property. required_props.name = name; } //We'd like to test that e instanceof the appropriate interface, //but we can't, because we don't know what window it was created //in. It might be an instanceof the appropriate interface on some //unknown other window. TODO: Work around this somehow? for (var prop in required_props) { t.expect(prop in e && e[prop] == required_props[prop]).toBe(true); } } } export function assert_unreached(t, description) { t.expect(false).toBe(true); } export function assert_any(t, assert_func, actual, expected_array) { var args = [].slice.call(arguments, 3); var errors = []; var passed = false; forEach(expected_array, function(expected) { try { assert_func.apply(this, [actual, expected].concat(args)); passed = true; } catch (e) { errors.push(e.message); } }); if (!passed) { t.expect(false).toBe(true); } }