diff options
Diffstat (limited to 'testing/web-platform/tests/css/geometry')
30 files changed, 2938 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-001.html b/testing/web-platform/tests/css/geometry/DOMMatrix-001.html new file mode 100644 index 0000000000..1752c2c5ca --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-001.html @@ -0,0 +1,204 @@ +<!DOCTYPE html> +<html> +<head> + <title>Geometry Interfaces: DOMMatrix and DOMMatrixReadOnly constructors</title> + <link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com" /> + <link rel="help" href="https://drafts.fxtf.org/geometry/#DOMMatrix"> + <link rel="help" href="https://drafts.fxtf.org/geometry/#dommatrix-constructors"> + <link rel="help" href="https://drafts.fxtf.org/geometry/#dom-dommatrix-dommatrix"> + <script src="support/dommatrix-test-util.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <div id="log"></div> + <script> + var initial = { + m11: 1, m21: 0, m31: 0, m41: 0, + m12: 0, m22: 1, m32: 0, m42: 0, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + is2D: true, + isIdentity: true + }; + var scaleTranslate2D = { + m11: 2, m21: 0, m31: 0, m41: 10, + m12: 0, m22: 2, m32: 0, m42: 10, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + is2D: true, + isIdentity: false + }; + ["DOMMatrix", "DOMMatrixReadOnly"].forEach(function(constr) { + test(function() { + checkDOMMatrix(new self[constr](), initial); + }, `new ${constr}()`); + + test(function() { + checkDOMMatrix(new self[constr](undefined), initial); + }, `new ${constr}(undefined)`); + + test(function() { + checkDOMMatrix(new self[constr](new self[constr]()), initial); + }, `new ${constr}(new ${constr}())`); + + ['none', + ' none', + 'none ', + 'NONE', + 'none/**/', + '/**/none', + '', + ].forEach(function(string) { + test(function() { + checkDOMMatrix(new self[constr](string), initial); + }, `new ${constr}(${format_value(string)})`); + }); + + test(function() { + var float32Array = new Float32Array([ + 2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 1.0]); + checkDOMMatrix(new self[constr](float32Array), scaleTranslate2D, false); + }, `new ${constr}(float32Array) 16 elements`); + + test(function() { + var float32Array = new Float32Array([2.0, 0.0, 0.0, 2.0, 10.0, 10.0]); + checkDOMMatrix(new self[constr](float32Array), scaleTranslate2D); + }, `new ${constr}(float32Array) 6 elements`); + + test(function() { + var float64Array = new Float64Array([ + 2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 1.0]); + checkDOMMatrix(new self[constr](float64Array), scaleTranslate2D, false); + }, `new ${constr}(float64Array) 16 elements`); + + test(function() { + var float64Array = new Float64Array([2.0, 0.0, 0.0, 2.0, 10.0, 10.0]); + checkDOMMatrix(new self[constr](float64Array), scaleTranslate2D); + }, `new ${constr}((float64Array) 6 elements`); + + [ + [2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 1.0], + [2.0, 0.0, 0.0, 2.0, 10.0, 10.0], + ].forEach(function(sequence) { + test(function() { + checkDOMMatrix(new self[constr](sequence), scaleTranslate2D, + sequence.length == 6); + }, `new ${constr}(sequence) ${sequence.length} elements`); + }); + + { + const epsilon = 0.0000000005; + ['scale(2) translateX(5px) translateY(5px)', + 'scale(2, 2) translateX(5px) translateY(5px)', + 'scale(2)translateX(5px)translateY(5px)', + 'scale(2) translateX(calc(2 * 2.5px)) translateY(5px)', + 'scale(2) translateX(5px) translateY(5px) rotate(5deg) rotate(-5deg)', + ].forEach(function(string) { + test(function() { + checkMatrix(new self[constr](string), scaleTranslate2D, { epsilon }); + }, `new ${constr}(${format_value(string)})`); + }); + } + + ['translateX (5px)', + 'scale(2 2) translateX(5) translateY(5)', + 'scale(2, 2), translateX(5) ,translateY(5)', + 'translateX(5em)', + 'translateX(5ex)', + 'translateX(5ch)', + 'translateX(5rem)', + 'translateX(5vw)', + 'translateX(5vh)', + 'translateX(5vmin)', + 'translateX(5vmax)', + 'translateX(5%)', + 'rotate(5)', + 'rotate(5, 5, 5)', + 'rotate(5, 5px, 5px)', + 'rotate(5deg, 5px, 5px)', + ' ', + '/**/', + '\0', + ';', + 'none;', + 'null', + null, // is converted to 'null' by IDL + 'undefined', + 'inherit', + 'initial', + 'unset', + ].forEach(function(string) { + test(function() { + assert_throws_dom('SyntaxError', function() { new self[constr](string); }); + }, `new ${constr}(${format_value(string)})`); + }); + + test(function() { + var sequence = [ + 2.0, 1.0, 0.0, 0.0, + 1.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 1.0]; + checkDOMMatrix(new self[constr](sequence), { + m11: 2, m21: 1, m31: 0, m41: 10, + m12: 1, m22: 2, m32: 0, m42: 10, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + is2D: false, + isIdentity: false + }); + }, `new ${constr}(sequence)`); + + test(function() { + var matrix = new self[constr]([ + 2.0, 1.0, 0.0, 0.0, + 1.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 1.0]); + checkDOMMatrix(new self[constr](matrix), { + m11: 2, m21: 1, m31: 0, m41: 10, + m12: 1, m22: 2, m32: 0, m42: 10, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + is2D: false, + isIdentity: false + }); + }, `new ${constr}(matrix)`); + + ['scale(2, 2), translateX(5px) translateY(5px)', + ].forEach(function(string) { + test(function() { + assert_throws_dom("SyntaxError", function() { new self[constr](string); }); + }, `new ${constr}(${format_value(string)})`); + }); + + [ + [2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 2.0, 0.0], // 17 elements + [2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0], // 15 elements + [2.0, 0.0, 0.0, 2.0, 10.0], // 5 elements + [], // 0 elements + ].forEach(function(sequence) { + test(function() { + assert_throws_js(TypeError, function() { new self[constr](sequence); }); + }, `new ${constr}(sequence) ${sequence.length} elements`); + }); + }); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-002.html b/testing/web-platform/tests/css/geometry/DOMMatrix-002.html new file mode 100644 index 0000000000..c262f7822f --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-002.html @@ -0,0 +1,113 @@ +<!DOCTYPE html> +<html> +<head> + <title>Geometry Interfaces: DOMMatrixReadOnly methods do not mutate the object</title> + <link href="mailto:peter.hall@algomi.com" rel="author" title="Peter Hall"> + <link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMMatrix"> + <script src="support/dommatrix-test-util.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <p>Test DOMMatrixReadOnly methods do not mutate the object</p> + <div id="log"></div> + <script> + + function initialMatrix(){ + return DOMMatrixReadOnly.fromMatrix( + { + m11:1, m12:-0.5, m13: 0.5, m14:0, + m21:0.5, m22:2, m23: -0.5, m24:0, + m31:0, m32:0, m33: 1, m34:0, + m41:0, m42:0, m43: 0, m44:1, + is2D: false + } + ); + } + + test(function() { + var matrix = initialMatrix(); + matrix.translate(1,5,3); + checkDOMMatrix(matrix, initialMatrix()); + },"test translate() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.scale(1,5,3,0,1,3); + checkDOMMatrix(matrix, initialMatrix()); + },"test scale() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.scaleNonUniform(1,5); + checkDOMMatrix(matrix, initialMatrix()); + },"test scaleNonUniform() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.scale3d(3,2,1,1); + checkDOMMatrix(matrix, initialMatrix()); + },"test scale3d() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.rotate(Math.PI, Math.PI/2, Math.PI/6); + checkDOMMatrix(matrix, initialMatrix()); + },"test rotate() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.rotateFromVector(10,-4); + checkDOMMatrix(matrix, initialMatrix()); + },"test rotateFromVector() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.rotateAxisAngle(3,4,5, Math.PI/6); + checkDOMMatrix(matrix, initialMatrix()); + },"test rotateAxisAngle() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.skewX(20); + checkDOMMatrix(matrix, initialMatrix()); + },"test skewX() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.skewY(20); + checkDOMMatrix(matrix, initialMatrix()); + },"test skewY() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.multiply({ m11:1, m12:2, m13: 0, m14:0, + m21:-1, m22:2, m23: -1, m24:0, + m31:0, m32:0, m33: 1, m34:0, + m41:5, m42:0, m43: 2, m44:1, + is2D: false, + isIdentity:false }); + checkDOMMatrix(matrix, initialMatrix()); + },"test multiply() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.flipX(); + checkDOMMatrix(matrix, initialMatrix()); + },"test flipX() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.flipY(); + checkDOMMatrix(matrix, initialMatrix()); + },"test flipY() doesn't mutate"); + + test(function() { + var matrix = initialMatrix(); + matrix.inverse(); + checkDOMMatrix(matrix, initialMatrix()); + },"test inverse() doesn't mutate"); + + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-003.html b/testing/web-platform/tests/css/geometry/DOMMatrix-003.html new file mode 100644 index 0000000000..56f463e2ac --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-003.html @@ -0,0 +1,318 @@ +<!DOCTYPE html> +<html> +<head> + <title>Geometry Interfaces: Test DOMMatrix non-mutating methods</title> + <link href="mailto:peter.hall@algomi.com" rel="author" title="Peter Hall"> + <link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMMatrix"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <p>Test DOMMatrix non-mutating methods</p> + <div id="log"></div> + <script> + var epsilon = 0.0000000005; + + function initialMatrix(){ + return { + m11:1, m12:-0.5, m13: 0.5, m14:0, + m21:0.5, m22:2, m23: -0.5, m24:0, + m31:0, m32:0, m33: 1, m34:0, + m41:10, m42:20, m43: 10, m44:1, + is2D: false + }; + } + + function initialDOMMatrix() { + return DOMMatrixReadOnly.fromMatrix(initialMatrix()) + } + + function identity() { + return new DOMMatrix( + [1, 0, 0, 0, + 0, 1, 0 ,0, + 0, 0, 1, 0, + 0, 0, 0, 1]); + } + + function update(matrix, f) { + f(matrix); + return matrix; + } + + function deg2rad(degrees) { + return degrees * Math.PI / 180; + } + + function getRotationMatrix(x, y, z, alpha_in_degrees) { + // Vector normalizing + var nx = x; + var ny = y; + var nz = z; + var length = Math.sqrt(x * x + y * y + z * z); + if (length) { + nx = x / length; + ny = y / length; + nz = z / length; + } + + // The 3D rotation matrix is described in CSS Transforms with alpha. + // Please see: https://drafts.csswg.org/css-transforms-2/#Rotate3dDefined + var alpha_in_radians = deg2rad(alpha_in_degrees / 2); + var sc = Math.sin(alpha_in_radians) * Math.cos(alpha_in_radians); + var sq = Math.sin(alpha_in_radians) * Math.sin(alpha_in_radians); + + var m11 = 1 - 2 * (ny * ny + nz * nz) * sq; + var m12 = 2 * (nx * ny * sq + nz * sc); + var m13 = 2 * (nx * nz * sq - ny * sc); + var m14 = 0; + var m21 = 2 * (nx * ny * sq - nz * sc); + var m22 = 1 - 2 * (nx * nx + nz * nz) * sq; + var m23 = 2 * (ny * nz * sq + nx * sc); + var m24 = 0; + var m31 = 2 * (nx * nz * sq + ny * sc); + var m32 = 2 * (ny * nz * sq - nx * sc); + var m33 = 1 - 2 * (nx * nx + ny * ny) * sq; + var m34 = 0; + var m41 = 0; + var m42 = 0; + var m43 = 0; + var m44 = 1; + + return new DOMMatrix([ + m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44]); + } + + function getMatrixTransform(matrix, point) { + var x = point.x * matrix.m11 + point.y * matrix.m21 + point.z * matrix.m31 + point.w * matrix.m41; + var y = point.x * matrix.m12 + point.y * matrix.m22 + point.z * matrix.m32 + point.w * matrix.m42; + var w = point.x * matrix.m13 + point.y * matrix.m23 + point.z * matrix.m33 + point.w * matrix.m43; + var z = point.x * matrix.m14 + point.y * matrix.m24 + point.z * matrix.m34 + point.w * matrix.m44; + return new DOMPoint(x, y, w, z) + } + + test(function() { + var tx = 1; + var ty = 5; + var tz = 3; + var result = initialDOMMatrix().translate(tx, ty, tz); + var expected = update(initialMatrix(), function(m) { + m.m41 += tx * m.m11 + ty * m.m21 + tz * m.m31; + m.m42 += tx * m.m12 + ty * m.m22 + tz * m.m32; + m.m43 += tx * m.m13 + ty * m.m23 + tz * m.m33; + m.m44 += tx * m.m14 + ty * m.m24 + tz * m.m34; + }); + checkDOMMatrix(result, expected); + },"test translate()"); + + test(function() { + var sx = 2; + var sy = 5; + var sz = 3; + var result = initialDOMMatrix().scale(sx, sy, sz); + var expected = update(initialMatrix(), function(m) { + m.m11 *= sx; + m.m12 *= sx; + m.m13 *= sx; + m.m14 *= sx; + m.m21 *= sy; + m.m22 *= sy; + m.m23 *= sy; + m.m24 *= sy; + m.m31 *= sz; + m.m32 *= sz; + m.m33 *= sz; + m.m34 *= sz; + }); + checkDOMMatrix(result, expected); + },"test scale() without offsets"); + + test(function() { + var result = initialDOMMatrix().scale(2, 5, 3, 11, 7, 13); + var expected = initialDOMMatrix() + .translate(11, 7, 13) + .scale(2, 5, 3) + .translate(-11, -7, -13); + checkDOMMatrix(result, expected); + },"test scale() with offsets"); + + test(function() { + var result = new DOMMatrixReadOnly([1, 2, 3, 4, 5, 6]) + .scale(1, 1, 1, 1, 1, 1); + var expected = new DOMMatrixReadOnly([1, 2, 0, 0, 3, 4, 0, 0, 0, 0, 1, 0, 5, 6, 0, 1]); + checkDOMMatrix(result, expected); + },"test scale() with identity scale and nonzero originZ"); + + test(function() { + var result = initialDOMMatrix().scaleNonUniform(); + var expected = initialDOMMatrix() + .scale(1, 1, 1, 0, 0, 0); + checkDOMMatrix(result, expected); + },"test scaleNonUniform()"); + + test(function() { + var result = initialDOMMatrix().scaleNonUniform(6); + var expected = initialDOMMatrix() + .scale(6, 1, 1, 0, 0, 0); + checkDOMMatrix(result, expected); + },"test scaleNonUniform() with sx"); + + test(function() { + var result = initialDOMMatrix().scaleNonUniform(5, 7); + var expected = initialDOMMatrix() + .scale(5, 7, 1, 0, 0, 0); + checkDOMMatrix(result, expected); + },"test scaleNonUniform() with sx, sy"); + + test(function() { + var result = initialDOMMatrix().scale3d(7, 5, 2, 3); + var expected = initialDOMMatrix() + .translate(5, 2, 3) + .scale(7, 7, 7) + .translate(-5, -2, -3); + checkDOMMatrix(result, expected); + },"test scale3d()"); + + test(function() { + var result = initialDOMMatrix().rotate(-90); + var expected = initialDOMMatrix().multiply(getRotationMatrix(0, 0, 1, -90)); + checkDOMMatrix(result, expected); + },"test rotate() 2d"); + + test(function() { + var result = initialDOMMatrix().rotate(180, 180, 90); + var expected = initialDOMMatrix().rotate(0,0,-90); + checkDOMMatrix(result, expected); + },"test rotate()"); + + test(function() { + var result = initialDOMMatrix().rotate(90, 90, 90); + var expected = initialDOMMatrix() + .rotate(0, 0, 90) + .rotate(0, 90, 0) + .rotate(90, 0, 0); + checkDOMMatrix(result, expected); + },"test rotate() order"); + + test(function() { + var result = initialDOMMatrix().rotateFromVector(1, 1); + var expected = initialDOMMatrix().rotate(45); + checkDOMMatrix(result, expected); + },"test rotateFromVector()"); + + test(function() { + var result = initialDOMMatrix().rotateFromVector(0, 1); + var expected = initialDOMMatrix().rotate(90); + checkDOMMatrix(result, expected); + },"test rotateFromVector() with x being zero"); + + test(function() { + var result = initialDOMMatrix().rotateFromVector(1, 0); + var expected = initialDOMMatrix() + checkDOMMatrix(result, expected); + },"test rotateFromVector() with y being zero"); + + test(function() { + var result = initialDOMMatrix().rotateFromVector(0, 0); + var expected = initialDOMMatrix() + checkDOMMatrix(result, expected); + },"test rotateFromVector() with two zeros"); + + test(function() { + var result = initialDOMMatrix().rotateAxisAngle(3, 3, 3, 120); + var expected = initialDOMMatrix().multiply(getRotationMatrix(3, 3, 3, 120)); + checkDOMMatrix(result, expected); + },"test rotateAxisAngle() "); + + test(function() { + var angleDeg = 75; + var result = initialDOMMatrix().skewX(angleDeg); + var tangent = Math.tan(angleDeg * Math.PI/180); + var skew = new DOMMatrix([ + 1, 0, 0, 0, + tangent, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1]) + var expected = initialDOMMatrix().multiply(skew); + checkDOMMatrix(result, expected); + },"test skewX()"); + + test(function() { + var angleDeg = 18; + var result = initialDOMMatrix().skewY(angleDeg); + var tangent = Math.tan(angleDeg * Math.PI/180); + var skew = new DOMMatrix([ + 1, tangent, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1]) + var expected = initialDOMMatrix().multiply(skew); + checkDOMMatrix(result, expected); + },"test skewY()"); + + test(function() { + var result = initialDOMMatrix().multiply(initialDOMMatrix().inverse()); + checkDOMMatrix(result, identity()); + },"test multiply with inverse is identity"); + + test(function() { + var result = initialDOMMatrix().flipX(); + var expected = initialDOMMatrix().multiply(new DOMMatrix([-1, 0, 0, 1, 0, 0])); + checkDOMMatrix(result, expected); + },"test flipX()"); + + test(function() { + var result = initialDOMMatrix().flipY(); + var expected = initialDOMMatrix().multiply(new DOMMatrix([1, 0, 0, -1, 0, 0])); + checkDOMMatrix(result, expected); + },"test flipY()"); + + test(function() { + var point = new DOMPointReadOnly(1, 2, 3, 4); + var matrix = new DOMMatrix([1, 2, 3, 4, 5, 6]); + var result = matrix.transformPoint(point); + var expected = getMatrixTransform(matrix, point); + checkDOMPoint(result, expected); + },"test transformPoint() - 2d matrix"); + + test(function() { + var point = new DOMPointReadOnly(1, 2, 3, 4); + var matrix = new DOMMatrix([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]); + var result = matrix.transformPoint(point); + var expected = getMatrixTransform(matrix, point); + checkDOMPoint(result, expected); + },"test transformPoint() - 3d matrix"); + + function checkDOMMatrix(m, exp) { + assert_approx_equals(m.m11, exp.m11, epsilon, "Expected value for m11 is " + exp.m11); + assert_approx_equals(m.m12, exp.m12, epsilon, "Expected value for m12 is " + exp.m12); + assert_approx_equals(m.m13, exp.m13, epsilon, "Expected value for m13 is " + exp.m13); + assert_approx_equals(m.m14, exp.m14, epsilon, "Expected value for m14 is " + exp.m14); + assert_approx_equals(m.m21, exp.m21, epsilon, "Expected value for m21 is " + exp.m21); + assert_approx_equals(m.m22, exp.m22, epsilon, "Expected value for m22 is " + exp.m22); + assert_approx_equals(m.m23, exp.m23, epsilon, "Expected value for m23 is " + exp.m23); + assert_approx_equals(m.m24, exp.m24, epsilon, "Expected value for m24 is " + exp.m24); + assert_approx_equals(m.m31, exp.m31, epsilon, "Expected value for m31 is " + exp.m31); + assert_approx_equals(m.m32, exp.m32, epsilon, "Expected value for m32 is " + exp.m32); + assert_approx_equals(m.m33, exp.m33, epsilon, "Expected value for m33 is " + exp.m33); + assert_approx_equals(m.m34, exp.m34, epsilon, "Expected value for m34 is " + exp.m34); + assert_approx_equals(m.m41, exp.m41, epsilon, "Expected value for m41 is " + exp.m41); + assert_approx_equals(m.m42, exp.m42, epsilon, "Expected value for m42 is " + exp.m42); + assert_approx_equals(m.m43, exp.m43, epsilon, "Expected value for m43 is " + exp.m43); + assert_approx_equals(m.m44, exp.m44, epsilon, "Expected value for m44 is " + exp.m44); + assert_equals(m.is2D, exp.is2D, "Expected value for is2D is " + exp.is2D); + } + + function checkDOMPoint(p, exp) { + assert_equals(p.x, exp.x, "x is not matched"); + assert_equals(p.y, exp.y, "y is not matched"); + assert_equals(p.z, exp.z, "z is not matched"); + assert_equals(p.w, exp.w, "w is not matched"); + } + + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-a-f-alias.html b/testing/web-platform/tests/css/geometry/DOMMatrix-a-f-alias.html new file mode 100644 index 0000000000..ab14ec9d5c --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-a-f-alias.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<title>Geometry Interfaces: DOMMatrix and DOMMatrixReadOnly a-f alias attributes</title> +<link rel="help" href="https://drafts.fxtf.org/geometry/#DOMMatrix"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +function defineThrowingGetter(object, attribute) { + Object.defineProperty(object, attribute, { + get: () => assert_unreached(`getter for ${attribute}`) + }); +} + +function defineThrowingSetter(object, attribute) { + Object.defineProperty(object, attribute, { + set: () => assert_unreached(`setter for ${attribute}`) + }); +} + +["DOMMatrix", "DOMMatrixReadOnly"].forEach((constr) => { + [ + ["a", "m11"], + ["b", "m12"], + ["c", "m21"], + ["d", "m22"], + ["e", "m41"], + ["f", "m42"], + ].forEach(([aliasAttribute, mAttribute]) => { + test(() => { + const matrix = new self[constr]([0, 0, 0, 0, 0, 0]); + defineThrowingGetter(matrix, mAttribute); + assert_equals(matrix[aliasAttribute], 0); + }, `${constr} getting ${aliasAttribute} with throwing getter for ${mAttribute}`); + + test(() => { + const matrix = new self[constr]([0, 0, 0, 0, 0, 0]); + defineThrowingGetter(matrix, aliasAttribute); + assert_equals(matrix[mAttribute], 0); + }, `${constr} getting ${mAttribute} with throwing getter for ${aliasAttribute}`); + + if (constr === "DOMMatrix") { + test(() => { + const matrix = new self[constr]([0, 0, 0, 0, 0, 0]); + defineThrowingSetter(matrix, mAttribute); + matrix[aliasAttribute] = 1; + assert_equals(matrix[aliasAttribute], 1); + }, `${constr} setting ${aliasAttribute} with throwing setter for ${mAttribute}`); + + test(() => { + const matrix = new self[constr]([0, 0, 0, 0, 0, 0]); + defineThrowingSetter(matrix, aliasAttribute); + matrix[mAttribute] = 1; + assert_equals(matrix[mAttribute], 1); + }, `${constr} setting ${mAttribute} with throwing setter for ${aliasAttribute}`); + } + }); +}); +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-attributes.html b/testing/web-platform/tests/css/geometry/DOMMatrix-attributes.html new file mode 100644 index 0000000000..4b3db9d550 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-attributes.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<title>Geometry Interfaces: DOMMatrix attributes</title> +<link rel="help" href="https://drafts.fxtf.org/geometry/#dommatrix-attributes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const initial = { + a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, + m11: 1, m12: 0, m13: 0, m14: 0, + m21: 0, m22: 1, m23: 0, m24: 0, + m31: 0, m32: 0, m33: 1, m34: 0, + m41: 0, m42: 0, m43: 0, m44: 1, +}; + +// Attributes that always preserve is2D. +["a", "b", "c", "d", "e", "f", + "m11", "m12", "m21", "m22", "m41", "m42" ].forEach(attribute => { + test(() => { + let m = new DOMMatrix(); + assert_true(m.is2D); + assert_equals(m[attribute], initial[attribute]); + m[attribute] = 42; + assert_true(m.is2D); + assert_equals(m[attribute], 42); + }, `DOMMatrix.${attribute}`); +}); + +// Attributes that clear is2D for values other than 0 or -0. +["m13", "m14", "m23", "m24", "m31", "m32", "m34", "m43" ].forEach(attribute => { + test(() => { + let m = new DOMMatrix(); + assert_true(m.is2D); + assert_equals(m[attribute], initial[attribute]); + m[attribute] = 0; + assert_true(m.is2D, "0 preserves is2D"); + assert_equals(m[attribute], 0); + m[attribute] = -0; + assert_true(m.is2D, "-0 preserves is2D"); + assert_equals(m[attribute], -0); + m[attribute] = 42; + assert_false(m.is2D, "a value other than 0 or -0 clears is2D"); + assert_equals(m[attribute], 42); + m[attribute] = 0; + assert_false(m.is2D, "is2D can never be set to true after having been set to false"); + assert_equals(m[attribute], 0); + }, `DOMMatrix.${attribute}`); +}); + +// Attributes that clear is2D for values other than 1. +["m33", "m44" ].forEach(attribute => { + test(() => { + let m = new DOMMatrix(); + assert_true(m.is2D); + assert_equals(m[attribute], initial[attribute]); + m[attribute] = 1; + assert_true(m.is2D, "1 preserves is2D"); + assert_equals(m[attribute], 1); + m[attribute] = 42; + assert_false(m.is2D, "a value other than 1 clears is2D"); + assert_equals(m[attribute], 42); + m[attribute] = 1; + assert_false(m.is2D, "is2D can never be set to true after having been set to false"); + assert_equals(m[attribute], 1); + }, `DOMMatrix.${attribute}`); +}); +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-css-string.worker.js b/testing/web-platform/tests/css/geometry/DOMMatrix-css-string.worker.js new file mode 100644 index 0000000000..d11638b26a --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-css-string.worker.js @@ -0,0 +1,38 @@ +// https://drafts.fxtf.org/geometry/#DOMMatrix + +importScripts("/resources/testharness.js"); + +['DOMMatrix', 'DOMMatrixReadOnly'].forEach(constr => { + test(() => { + assert_true(constr in self, `${constr} should exist`); + assert_throws_js(TypeError, () => new self[constr]('matrix(1,0,0,1,0,0)') ); + }, `${constr} constructor with string argument in worker`); + + test(() => { + assert_true(constr in self, `${constr} should exist`); + assert_throws_js(TypeError, () => new self[constr]('') ); + }, `${constr} constructor with empty string argument in worker`); + + test(() => { + const matrix = new self[constr](); + assert_equals(String(matrix), `[object ${constr}]`); + }, `${constr} stringifier in worker (2d identity)`); + + test(() => { + const matrix = self[constr].fromMatrix({is2D: false}); + assert_equals(String(matrix), `[object ${constr}]`); + }, `${constr} stringifier in worker (3d identity)`); + + test(() => { + const matrix = new self[constr]([1, 0, 0, NaN, Infinity, -Infinity]); + assert_equals(String(matrix), `[object ${constr}]`); + }, `${constr} stringifier in worker (non-finite values)`); +}); + +test(() => { + assert_false('setMatrixValue' in DOMMatrix.prototype, 'on prototype'); + const matrix = new DOMMatrix(); + assert_false('setMatrixValue' in matrix, 'on instance'); +}, 'DOMMatrix setMatrixValue in worker'); + +done(); diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-invert-invertible.html b/testing/web-platform/tests/css/geometry/DOMMatrix-invert-invertible.html new file mode 100644 index 0000000000..d5bef624d2 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-invert-invertible.html @@ -0,0 +1,76 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMMatrix"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/dommatrix-test-util.js"></script> +<p>Test DOMMatrix.inverse()/invertSelf() for invertible matrices</p> +<script> +test(function() { + var m = new DOMMatrix(); + assert_true(m.isIdentity); + var m1 = m.inverse(); + assert_true(m1.isIdentity); + // Use checkMatrix() instead of checkDOMMatrix() because checkMatrix() has + // a default epsilon = Number.MIN_VALUE which can at least pass + // assert_approx_equal(0, -0, epsilon). + checkMatrix(m, m1); + m.invertSelf(); + checkMatrix(m, m1); +}, "identity"); + +test(function() { + var m = new DOMMatrix().translate(10, -20.5); + var m1 = m.inverse(); + checkMatrix(m1, new DOMMatrix().translate(-10, 20.5)); + // Check with 'new DOMMatrix()' instead of identity() because the latter is + // a 3d identity matrix. + checkMatrix(m1.multiply(m), new DOMMatrix()); + m.invertSelf(); + checkMatrix(m, m1); +}, "translate"); + +test(function() { + var m = new DOMMatrix().translate(10, -20.5, 30.5); + var m1 = m.inverse(); + checkMatrix(m1, new DOMMatrix().translate(-10, 20.5, -30.5)); + checkMatrix(m1.multiply(m), identity()); + m.invertSelf(); + checkMatrix(m, m1); +}, "translate3d"); + +test(function() { + var m = new DOMMatrix().scale(4, -0.5); + var m1 = m.inverse(); + checkMatrix(m1, new DOMMatrix().scale(0.25, -2.0)); + checkMatrix(m1.multiply(m), new DOMMatrix()); + m.invertSelf(); + checkMatrix(m, m1); +}, "scale"); + +test(function() { + var m = new DOMMatrix().scale(4, -0.5, 2); + var m1 = m.inverse(); + checkMatrix(m1, new DOMMatrix().scale(0.25, -2.0, 0.5)); + checkMatrix(m1.multiply(m), identity()); + m.invertSelf(); + checkMatrix(m, m1); +}, "scale3d"); + +test(function() { + var m = new DOMMatrix().rotateAxisAngle(0, 0, 1, -30) + .scale(10, -0.5, 2.5) + .rotateAxisAngle(0, 1, 0, 10) + .translate(10, -20.5, 30.5) + .rotateAxisAngle(1, 0, 0, 20); + var expected = new DOMMatrix().rotateAxisAngle(1, 0, 0, -20) + .translate(-10, 20.5, -30.5) + .rotateAxisAngle(0, 1, 0, -10) + .scale(0.1, -2.0, 0.4) + .rotateAxisAngle(0, 0, 1, 30); + var m1 = m.inverse(); + var epsilon = 1e-6; + checkMatrix(m1, expected, {epsilon}); + m.invertSelf(); + checkMatrix(m, expected, {epsilon}); +}, "complex"); +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-invert-non-invertible.html b/testing/web-platform/tests/css/geometry/DOMMatrix-invert-non-invertible.html new file mode 100644 index 0000000000..b3295321e0 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-invert-non-invertible.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMMatrix"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<p>Test DOMMatrix.inverse()/invertSelf() for non-invertible matrix</p> +<script> +function checkResult(m) { + assert_false(m.is2D, 'is2D'); + assert_false(m.isIdentity, 'isIdentity'); + assert_true(isNaN(m.m11), 'm11 isNaN'); + assert_true(isNaN(m.m12), 'm12 isNaN'); + assert_true(isNaN(m.m13), 'm13 isNaN'); + assert_true(isNaN(m.m14), 'm14 isNaN'); + assert_true(isNaN(m.m21), 'm21 isNaN'); + assert_true(isNaN(m.m22), 'm22 isNaN'); + assert_true(isNaN(m.m23), 'm23 isNaN'); + assert_true(isNaN(m.m24), 'm24 isNaN'); + assert_true(isNaN(m.m31), 'm31 isNaN'); + assert_true(isNaN(m.m32), 'm32 isNaN'); + assert_true(isNaN(m.m33), 'm33 isNaN'); + assert_true(isNaN(m.m34), 'm34 isNaN'); + assert_true(isNaN(m.m41), 'm41 isNaN'); + assert_true(isNaN(m.m42), 'm42 isNaN'); + assert_true(isNaN(m.m43), 'm43 isNaN'); + assert_true(isNaN(m.m44), 'm44 isNaN'); + + var f32 = m.toFloat32Array(); + assert_equals(f32.length, 16, 'toFloat32Array().length'); + for (var i = 0; i < 16; i++) + assert_true(isNaN(f32[i]), 'toFloat32Array()[' + i + '] isNaN'); + + var f64 = m.toFloat64Array(); + assert_equals(f64.length, 16, 'toFloat64Array().length'); + for (var i = 0; i < 16; i++) + assert_true(isNaN(f64[i]), 'toFloat64()[' + i + '] isNaN'); +} + +test(function() { + var m = new DOMMatrix(); + m.a = 0; + m.invertSelf(); + checkResult(m); +},"invertSelf()"); + +test(function() { + var m = new DOMMatrix(); + m.a = 0; + checkResult(m.inverse()); +},"inverse()"); +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-invert-preserves-2d.html b/testing/web-platform/tests/css/geometry/DOMMatrix-invert-preserves-2d.html new file mode 100644 index 0000000000..a4f0b58496 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-invert-preserves-2d.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<title>Test DOMMatrix.inverse()/invertSelf() keep is2D status</title> +<link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMMatrix"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +function check2D(m) { + assert_true(m.is2D); + // assert_equals() distinguish 0 and -0, so use '== 0' instead. + assert_true(m.m13 == 0); + assert_true(m.m14 == 0); + assert_true(m.m23 == 0); + assert_true(m.m24 == 0); + assert_true(m.m31 == 0); + assert_true(m.m32 == 0); + assert_equals(m.m33, 1); + assert_true(m.m34 == 0); + assert_true(m.m43 == 0); + assert_equals(m.m44, 1); +} + +test(function() { + for (var s = 0.1; s < 20; s += 0.1) { + m = new DOMMatrix().scale(s, s); + check2D(m); + check2D(m.inverse()); + m.invertSelf(); + check2D(m); + } +}, "scale"); + +test(function() { + for (var r = 0; r < 180; r += 2) { + m = new DOMMatrix().rotate(r); + check2D(m); + check2D(m.inverse()); + m.invertSelf(); + check2D(m); + } +}, "rotate"); +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-newobject.html b/testing/web-platform/tests/css/geometry/DOMMatrix-newobject.html new file mode 100644 index 0000000000..33604e3c67 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-newobject.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<title>Geometry Interfaces: DOMMatrix and DOMMatrixReadOnly [NewObject] methods</title> +<link rel="help" href="https://drafts.fxtf.org/geometry/#DOMMatrix"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +function getReturnType(method) { + switch(method) { + case "transformPoint": return "DOMPoint"; break; + case "toFloat32Array": return "Float32Array"; break; + case "toFloat64Array": return "Float64Array"; break; + default: return "DOMMatrix"; break; + } +} +["DOMMatrix", "DOMMatrixReadOnly"].forEach((constr) => { + ["translate", + "scale", + "scale3d", + "rotate", + "rotateFromVector", + "rotateAxisAngle", + "skewX", + "skewY", + "multiply", + "flipX", + "flipY", + "inverse", + "transformPoint", + "toFloat32Array", + "toFloat64Array"].forEach((method) => { + test(() => { + const matrix = new self[constr](); + const a = matrix[method](); + const b = matrix[method](); + assert_class_string(matrix, constr, 'matrix'); + assert_class_string(a, getReturnType(method), 'a'); + assert_class_string(b, getReturnType(method), 'b'); + assert_not_equals(a, b, 'a !== b'); + assert_not_equals(a, matrix, 'a !== matrix'); + assert_not_equals(b, matrix, 'b !== matrix'); + }, `${constr} ${method}`); + }); +}); +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix-stringifier.html b/testing/web-platform/tests/css/geometry/DOMMatrix-stringifier.html new file mode 100644 index 0000000000..5a39238bef --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix-stringifier.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<title>Geometry Interfaces: DOMMatrix and DOMMatrixReadOnly stringifier</title> +<link rel="help" href="https://drafts.fxtf.org/geometry/#DOMMatrix"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +["DOMMatrix", "DOMMatrixReadOnly", "WebKitCSSMatrix"].forEach(constr => { + const prefix = `${constr} stringifier:`; + + // Basic + test(() => { + const matrix = new self[constr](); + assert_equals(String(matrix), "matrix(1, 0, 0, 1, 0, 0)"); + }, `${prefix} identity (2d)`); + + test(() => { + const matrix = self[constr].fromMatrix({is2D: false}); + assert_equals(String(matrix), "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)"); + }, `${prefix} identity (3d)`); + + // Non-finites + [NaN, Infinity, -Infinity].forEach(num => { + test(() => { + const matrix = new self[constr]([1, 0, 0, 1, 0, num]); + assert_throws_dom("InvalidStateError", () => String(matrix)); + }, `${prefix} ${num} (2d)`); + + test(() => { + const matrix = new self[constr]([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, num, 0, 1]); + assert_throws_dom("InvalidStateError", () => String(matrix)); + }, `${prefix} ${num} (3d)`); + }); + + // Precision + [ + ['1/3', '0.3333333333333333'], + ['1/300000', '0.0000033333333333333333'], + ['1/300000000', '3.3333333333333334e-9'], + ['100000 + (1/3)', '100000.33333333333'], + ['Math.pow(2, 53) + 1', '9007199254740992'], + ['Math.pow(2, 53) + 2', '9007199254740994'], + ['Number.MAX_VALUE', '1.7976931348623157e+308'], + ['Number.MIN_VALUE', '5e-324'], + ].forEach(([input, expected]) => { + const num = eval(input); + test(() => { + const matrix = new self[constr]([1, 0, 0, 1, 0, num]); + assert_equals(String(matrix), `matrix(1, 0, 0, 1, 0, ${expected})`); + }, `${prefix} ${input} (2d)`); + + test(() => { + const matrix = new self[constr]([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, num, 0, 1]); + assert_equals(String(matrix), `matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, ${expected}, 0, 1)`); + }, `${prefix} ${input} (3d)`); + }); + + // Should not invoke getters for m11 etc + function defineThrowingGetters(matrix) { + Object.defineProperty(matrix, 'a', { + get: () => assert_unreached('getter for a') + }); + Object.defineProperty(matrix, 'm11', { + get: () => assert_unreached('getter for m11') + }); + } + + test(() => { + const matrix = new self[constr](); + defineThrowingGetters(matrix); + assert_equals(String(matrix), "matrix(1, 0, 0, 1, 0, 0)"); + }, `${prefix} throwing getters (2d)`); + + test(() => { + const matrix = self[constr].fromMatrix({is2D: false}); + defineThrowingGetters(matrix); + assert_equals(String(matrix), "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)"); + }, `${prefix} throwing getters (3d)`); +}); +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrix2DInit-validate-fixup.html b/testing/web-platform/tests/css/geometry/DOMMatrix2DInit-validate-fixup.html new file mode 100644 index 0000000000..a7257aa288 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrix2DInit-validate-fixup.html @@ -0,0 +1,147 @@ +<!DOCTYPE html> +<title>Geometry Interfaces: DOMMatrix2DInit validate and fixup</title> +<link rel="help" href="https://drafts.fxtf.org/geometry/#dommatrixinit-dictionary"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-context-2d-settransform"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/dommatrix-test-util.js"></script> +<canvas id=canvas hidden></canvas> +<script> +setup(() => { + window.canvas = document.getElementById('canvas'); + window.ctx = canvas.getContext('2d'); + window.ctx.fillStyle = '#000'; +}); + +function clearCanvas(ctx) { + ctx.resetTransform(); + ctx.clearRect(0, 0, window.canvas.width, window.canvas.height); +} + +function drawRectWithSetTransform(ctx, transform) { + clearCanvas(ctx); + ctx.setTransform(transform); + ctx.fillRect(20, 20, 30, 30); + return window.canvas.toDataURL(); +} + +function drawRectWithAddPathTransform(ctx, transform) { + clearCanvas(ctx); + var path = new Path2D(); + path.rect(20, 20, 30, 30); + var transformedPath = new Path2D(); + if (transform === undefined) { + transformedPath.addPath(path); + } else { + transformedPath.addPath(path, transform); + } + ctx.fill(transformedPath); + return window.canvas.toDataURL(); +} + +var emptyCanvasURL = window.canvas.toDataURL(); + +[ + {a: 1, m11: 2}, + {b: 0, m12: -1}, + {c: Infinity, m21: -Infinity}, + {d: 0, m22: NaN}, + {e: 1, m41: 1.00000001}, + {f: 0, m42: Number.MIN_VALUE}, +].forEach(dict => { + test(() => { + ctx.resetTransform(); + assert_throws_js(TypeError, () => ctx.setTransform(dict)); + }, `setTransform(${format_dict(dict)}) (invalid)`); + + test(() => { + assert_throws_js(TypeError, () => drawRectWithAddPathTransform(ctx, dict)); + }, `addPath(${format_dict(dict)}) (invalid)`); +}); + +test(() => { + ctx.resetTransform(); + ctx.setTransform(1, 2, 3, 4, 5, 6); + const matrix = ctx.getTransform(); + checkMatrix(matrix, matrix2D({m11: 1, m12: 2, m21: 3, m22: 4, m41: 5, m42: 6})); +}, `setTransform (Sanity check without dictionary)`); + +test(() => { + var ident = matrix2D({}); + var expectedResultURL = drawRectWithSetTransform(ctx, ident); + var actualResultURL = drawRectWithAddPathTransform(ctx); + assert_equals(actualResultURL, expectedResultURL); +}, `addPath (Sanity check without second parameter)`); + +[ + // Input dict that are 2D + [{}, matrix2D({})], + [{is2D: undefined}, matrix2D({})], + [{a: 1, m11: 1}, matrix2D({m11: 1})], + [{b: 0, m12: undefined}, matrix2D({m12: 0})], + [{c: 0, m21: 0}, matrix2D({m21: 0})], + [{c: 0, m21: -0}, matrix2D({m21: -0})], + [{c: -0, m21: 0}, matrix2D({m21: 0})], + [{c: -0, m21: -0}, matrix2D({m21: -0})], + [{d: Infinity, m22: Infinity}, null], // setTransform: silently ignore / addPath: silently halt + [{e: -Infinity, m41: -Infinity}, null], // setTransform: silently ignore / addPath: silently halt + [{f: NaN, m42: NaN}, null], // setTransform: silently ignore / addPath: silently halt + [{f: NaN, m42: NaN, is2D: true}, null], // setTransform: silently ignore / addPath: silently halt + [{f: 0, m42: null}, matrix2D({m42: 0})], // null is converted to 0 + [{f: -0, m42: null}, matrix2D({m42: 0})], // null is converted to 0 + [{a: 2}, matrix2D({m11: 2})], + [{b: 2}, matrix2D({m12: 2})], + [{c: 2}, matrix2D({m21: 2})], + [{d: 2}, matrix2D({m22: 2})], + [{e: 2}, matrix2D({m41: 2})], + [{f: 2}, matrix2D({m42: 2})], + [{a: -0, b: -0, c: -0, d: -0, e: -0, f: -0}, + matrix2D({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})], + [{a: -0, b: -0, c: -0, d: -0, e: -0, f: -0, is2D: true}, + matrix2D({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})], + [{m11:2}, matrix2D({m11: 2})], + [{m12:2}, matrix2D({m12: 2})], + [{m21:2}, matrix2D({m21: 2})], + [{m22:2}, matrix2D({m22: 2})], + [{m41:2}, matrix2D({m41: 2})], + [{m42:2}, matrix2D({m42: 2})], + [{m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0}, + matrix2D({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})], + [{m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0, is2D: true}, + matrix2D({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})], + [{m13: 0, is2D: true}, matrix2D({})], + [{m13: -0, is2D: true}, matrix2D({})], + [{m14: 0, is2D: true}, matrix2D({})], + [{m14: -0, is2D: true}, matrix2D({})], + [{m23: 0, is2D: true}, matrix2D({})], + [{m23: -0, is2D: true}, matrix2D({})], + [{m24: 0, is2D: true}, matrix2D({})], + [{m24: -0, is2D: true}, matrix2D({})], + [{m31: 0, is2D: true}, matrix2D({})], + [{m31: -0, is2D: true}, matrix2D({})], + [{m32: 0, is2D: true}, matrix2D({})], + [{m32: -0, is2D: true}, matrix2D({})], + [{m33: 1, is2D: true}, matrix2D({})], + [{m34: 0, is2D: true}, matrix2D({})], + [{m34: -0, is2D: true}, matrix2D({})], + [{m43: 0, is2D: true}, matrix2D({})], + [{m43: -0, is2D: true}, matrix2D({})], + [{m44: 1, is2D: true}, matrix2D({})], + [{is2D: true}, matrix2D({})], +].forEach(([dict, expected]) => { + test(() => { + ctx.resetTransform(); + ctx.setTransform(dict); + const matrix = ctx.getTransform(); + checkMatrix(matrix, expected || matrix2D({})); + }, `setTransform(${format_dict(dict)})`); + + test(() => { + var expectedResultURL = expected ? + drawRectWithSetTransform(ctx, expected) : + emptyCanvasURL; + var actualResultURL = drawRectWithAddPathTransform(ctx, dict); + assert_equals(actualResultURL, expectedResultURL); + }, `addPath(${format_dict(dict)})`); + }); +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMMatrixInit-validate-fixup.html b/testing/web-platform/tests/css/geometry/DOMMatrixInit-validate-fixup.html new file mode 100644 index 0000000000..78eaa78e21 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMMatrixInit-validate-fixup.html @@ -0,0 +1,132 @@ +<!DOCTYPE html> +<title>Geometry Interfaces: DOMMatrixInit validate and fixup</title> +<link rel="help" href="https://drafts.fxtf.org/geometry/#dommatrixinit-dictionary"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/dommatrix-test-util.js"></script> +<script> +[ + {a: 1, m11: 2}, + {b: 0, m12: -1}, + {c: Infinity, m21: -Infinity}, + {d: 0, m22: NaN}, + {e: 1, m41: 1.00000001}, + {f: 0, m42: Number.MIN_VALUE}, + {m13: 1, is2D: true}, + {m14: 1, is2D: true}, + {m23: 1, is2D: true}, + {m24: 1, is2D: true}, + {m31: 1, is2D: true}, + {m32: 1, is2D: true}, + {m33: 0, is2D: true}, + {m33: -0, is2D: true}, + {m33: -1, is2D: true}, + {m34: 1, is2D: true}, + {m43: 1, is2D: true}, + {m44: 0, is2D: true}, +].forEach(dict => { + test(() => { + assert_true('fromMatrix' in DOMMatrix, 'fromMatrix should exist'); + assert_throws_js(TypeError, () => DOMMatrix.fromMatrix(dict)); + assert_true('multiply' in DOMMatrix.prototype, 'multiply should exist'); + assert_throws_js(TypeError, () => new DOMMatrix().multiply(dict)); + assert_true('multiplySelf' in DOMMatrix.prototype, 'multiplySelf should exist'); + assert_throws_js(TypeError, () => new DOMMatrix().multiplySelf(dict)); + assert_true('preMultiplySelf' in DOMMatrix.prototype, 'preMultiplySelf should exist'); + assert_throws_js(TypeError, () => new DOMMatrix().preMultiplySelf(dict)); + }, `${format_dict(dict)} (invalid)`); +}); + +[ + [{}, matrix2D({})], + [{is2D: undefined}, matrix2D({})], // undefined means the dictionary member is not present + [{a: 1, m11: 1}, matrix2D({m11: 1})], + [{b: 0, m12: undefined}, matrix2D({m12: 0})], + [{c: 0, m21: 0}, matrix2D({m21: 0})], + [{c: 0, m21: -0}, matrix2D({m21: -0})], + [{c: -0, m21: 0}, matrix2D({m21: 0})], + [{c: -0, m21: -0}, matrix2D({m21: -0})], + [{d: Infinity, m22: Infinity}, matrix2D({m22: Infinity})], + [{e: -Infinity, m41: -Infinity}, matrix2D({m41: -Infinity})], + [{f: NaN, m42: NaN}, matrix2D({m42: NaN})], + [{f: NaN, m42: NaN, is2D: true}, matrix2D({m42: NaN})], + [{f: 0, m42: null}, matrix2D({m42: 0})], // null is converted to 0 + [{f: -0, m42: null}, matrix2D({m42: 0})], // null is converted to 0 + [{a: 2}, matrix2D({m11: 2})], + [{b: 2}, matrix2D({m12: 2})], + [{c: 2}, matrix2D({m21: 2})], + [{d: 2}, matrix2D({m22: 2})], + [{e: 2}, matrix2D({m41: 2})], + [{f: 2}, matrix2D({m42: 2})], + [{a: -0, b: -0, c: -0, d: -0, e: -0, f: -0}, + matrix2D({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})], + [{a: -0, b: -0, c: -0, d: -0, e: -0, f: -0, is2D: true}, + matrix2D({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})], + [{m11:2}, matrix2D({m11: 2})], + [{m12:2}, matrix2D({m12: 2})], + [{m21:2}, matrix2D({m21: 2})], + [{m22:2}, matrix2D({m22: 2})], + [{m41:2}, matrix2D({m41: 2})], + [{m42:2}, matrix2D({m42: 2})], + [{m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0}, + matrix2D({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})], + [{m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0, is2D: true}, + matrix2D({m11: -0, m12: -0, m21: -0, m22: -0, m41: -0, m42: -0})], + [{m13: 0, is2D: true}, matrix2D({m13: 0})], + [{m13: -0, is2D: true}, matrix2D({m13: 0})], + [{m14: 0, is2D: true}, matrix2D({m14: 0})], + [{m14: -0, is2D: true}, matrix2D({m14: 0})], + [{m23: 0, is2D: true}, matrix2D({m23: 0})], + [{m23: -0, is2D: true}, matrix2D({m23: 0})], + [{m24: 0, is2D: true}, matrix2D({m24: 0})], + [{m24: -0, is2D: true}, matrix2D({m24: 0})], + [{m31: 0, is2D: true}, matrix2D({m31: 0})], + [{m31: -0, is2D: true}, matrix2D({m31: 0})], + [{m32: 0, is2D: true}, matrix2D({m32: 0})], + [{m32: -0, is2D: true}, matrix2D({m32: 0})], + [{m33: 1, is2D: true}, matrix2D({m33: 1})], + [{m34: 0, is2D: true}, matrix2D({m34: 0})], + [{m34: -0, is2D: true}, matrix2D({m34: 0})], + [{m43: 0, is2D: true}, matrix2D({m43: 0})], + [{m43: -0, is2D: true}, matrix2D({m43: 0})], + [{m44: 1, is2D: true}, matrix2D({m44: 1})], + [{is2D: true}, matrix2D({})], +].forEach(([dict, expected]) => { + test(() => { + const matrix = DOMMatrix.fromMatrix(dict); + checkMatrix(matrix, expected); + }, `${format_dict(dict)} (2d)`); +}); + +[ + [{m13: 1, is2D: false}, matrix3D({m13: 1})], + [{m14: 1, is2D: false}, matrix3D({m14: 1})], + [{m23: 1, is2D: false}, matrix3D({m23: 1})], + [{m24: 1, is2D: false}, matrix3D({m24: 1})], + [{m31: 1, is2D: false}, matrix3D({m31: 1})], + [{m32: 1, is2D: false}, matrix3D({m32: 1})], + [{m33: 0, is2D: false}, matrix3D({m33: 0})], + [{m33: -0, is2D: false}, matrix3D({m33: -0})], + [{m33: -1, is2D: false}, matrix3D({m33: -1})], + [{m34: 1, is2D: false}, matrix3D({m34: 1})], + [{m43: 1, is2D: false}, matrix3D({m43: 1})], + [{m44: 0, is2D: false}, matrix3D({m44: 0})], + [{m13: 1}, matrix3D({m13: 1})], + [{m14: 1}, matrix3D({m14: 1})], + [{m23: 1}, matrix3D({m23: 1})], + [{m24: 1}, matrix3D({m24: 1})], + [{m31: 1}, matrix3D({m31: 1})], + [{m32: 1}, matrix3D({m32: 1})], + [{m33: 0}, matrix3D({m33: 0})], + [{m34: 1}, matrix3D({m34: 1})], + [{m43: 1}, matrix3D({m43: 1})], + [{m44: 0}, matrix3D({m44: 0})], + [{is2D: false}, matrix3D({})], + [{is2D: null}, matrix3D({})], // null is converted to false +].forEach(([dict, expected]) => { + test(() => { + const matrix = DOMMatrix.fromMatrix(dict); + checkMatrix(matrix, expected); + }, `${format_dict(dict)} (3d)`); +}); +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMPoint-001.html b/testing/web-platform/tests/css/geometry/DOMPoint-001.html new file mode 100644 index 0000000000..945f4674de --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMPoint-001.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<html> +<head> + <title>Geometry Interfaces: DOMPoint and DOMPointReadOnly interface tests</title> + <link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com" /> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#dictdef-dompointinit"> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#dom-dompoint-dompoint"> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#DOMPoint"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <p>Test DOMPoint and DOMPointReadOnly interfaces</p> + <div id="log"></div> + <script> + test(function() { + checkDOMPoint(new DOMPoint(), {x:0, y:0, z:0, w:1}); + },'testConstructor0'); + test(function() { + checkDOMPoint(new DOMPoint(1), {x:1, y:0, z:0, w:1}); + },'testConstructor1'); + test(function() { + checkDOMPoint(new DOMPoint(1, 2), {x:1, y:2, z:0, w:1}); + },'testConstructor2'); + test(function() { + checkDOMPoint(new DOMPoint(1, 2, 3), {x:1, y:2, z:3, w:1}); + },'testConstructor3'); + test(function() { + checkDOMPoint(new DOMPoint(1, 2, 3, 4), {x:1, y:2, z:3, w:4}); + },'testConstructor4'); + test(function() { + checkDOMPoint(new DOMPoint(1, 2, 3, 4, 5), {x:1, y:2, z:3, w:4}); + },'testConstructor5'); + test(function() { + checkDOMPoint(new DOMPoint({}), {x:NaN, y:0, z:0, w:1}); + },'testConstructorDictionary0'); + test(function() { + checkDOMPoint(new DOMPoint({x:1}), {x:NaN, y:0, z:0, w:1}); + },'testConstructorDictionary1'); + test(function() { + checkDOMPoint(new DOMPoint({x:1, y:2}), {x:NaN, y:0, z:0, w:1}); + },'testConstructorDictionary2'); + test(function() { + checkDOMPoint(new DOMPoint(1, undefined), {x:1, y:0, z:0, w:1}); + },'testConstructor2undefined'); + test(function() { + checkDOMPoint(new DOMPoint("a", "b"), {x:NaN, y:NaN, z:0, w:1}); + },'testConstructorUndefined1'); + test(function() { + checkDOMPoint(new DOMPoint({x:"a", y:"b"}), {x:NaN, y:0, z:0, w:1}); + },'testConstructorUndefined2'); + test(function() { + checkDOMPoint(new DOMPointReadOnly(), {x:0, y:0, z:0, w:1}); + },'DOMPointReadOnly constructor with no values'); + test(function() { + checkDOMPoint(new DOMPointReadOnly(1, 2, 3, 4), {x:1, y:2, z:3, w:4}); + },'DOMPointReadOnly constructor with 4 values'); + test(function() { + var p = new DOMPoint(0, 0, 0, 1); + p.x = undefined; + p.y = undefined; + p.z = undefined; + p.w = undefined; + checkDOMPoint(p, {x:NaN, y:NaN, z:NaN, w:NaN}); + },'testAttributesUndefined'); + test(function() { + var p = new DOMPoint(0, 0, 0, 1); + p.x = NaN; + p.y = Number.POSITIVE_INFINITY; + p.z = Number.NEGATIVE_INFINITY; + p.w = Infinity; + checkDOMPoint(p, {x:NaN, y:Infinity, z:-Infinity, w:Infinity}); + },'testAttributesNaNInfinity'); + + function checkDOMPoint(p, exp) { + assert_equals(p.x, exp.x, "Expected value for x is " + exp.x); + assert_equals(p.y, exp.y, "Expected value for y is " + exp.y); + assert_equals(p.z, exp.z, "Expected value for z is " + exp.z); + assert_equals(p.w, exp.w, "Expected value for w is " + exp.w); + } + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/geometry/DOMPoint-002.html b/testing/web-platform/tests/css/geometry/DOMPoint-002.html new file mode 100644 index 0000000000..96276d86f5 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMPoint-002.html @@ -0,0 +1,177 @@ +<!DOCTYPE html> +<html><head> + <title>Geometry Interfaces: DOMPoint and DOMPointReadOnly interface tests</title> + <link href="mailto:hs1217.lee@samsung.com" rel="author" title="Hwanseung Lee"> + <link href="https://drafts.fxtf.org/geometry-1/#DOMPoint" rel="help"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <p>Test DOMPoint and DOMPointReadOnly interfaces</p> + <div id="log"></div> + <script> + function getMatrixTransform(matrix, point) { + var x = point.x * matrix.m11 + point.y * matrix.m21 + point.z * matrix.m31 + point.w * matrix.m41; + var y = point.x * matrix.m12 + point.y * matrix.m22 + point.z * matrix.m32 + point.w * matrix.m42; + var w = point.x * matrix.m13 + point.y * matrix.m23 + point.z * matrix.m33 + point.w * matrix.m43; + var z = point.x * matrix.m14 + point.y * matrix.m24 + point.z * matrix.m34 + point.w * matrix.m44; + return new DOMPoint(x, y, w, z) + } + + test(function() { + checkDOMPoint(new DOMPoint(), {x:0, y:0, z:0, w:1}); + },'test DOMPoint Constructor no args'); + test(function() { + checkDOMPoint(new DOMPoint(1), {x:1, y:0, z:0, w:1}); + },'test DOMPoint Constructor one args'); + test(function() { + checkDOMPoint(new DOMPoint(1, 2), {x:1, y:2, z:0, w:1}); + },'test DOMPoint Constructor two args'); + test(function() { + checkDOMPoint(new DOMPoint(1, 2, 3), {x:1, y:2, z:3, w:1}); + },'test DOMPoint Constructor three args'); + test(function() { + checkDOMPoint(new DOMPoint(1, 2, 3, 4), {x:1, y:2, z:3, w:4}); + },'test DOMPoint Constructor four args'); + test(function() { + checkDOMPoint(new DOMPoint(1, 2, 3, 4, 5), {x:1, y:2, z:3, w:4}); + },'test DOMPoint Constructor more then four args'); + test(function() { + checkDOMPoint(new DOMPoint(1, undefined), {x:1, y:0, z:0, w:1}); + },'test DOMPoint Constructor with undefined'); + test(function() { + checkDOMPoint(new DOMPoint("a", "b"), {x:NaN, y:NaN, z:0, w:1}); + },'test DOMPoint Constructor with string'); + test(function() { + checkDOMPoint(new DOMPoint({}), {x:NaN, y:0, z:0, w:1}); + },'test DOMPoint Constructor with empty object'); + test(function() { + checkDOMPoint(DOMPoint.fromPoint({}), {x:0, y:0, z:0, w:1}); + },'test DOMPoint fromPoint with empty object'); + test(function() { + checkDOMPoint(DOMPoint.fromPoint({x:1}), {x:1, y:0, z:0, w:1}); + },'test DOMPoint fromPoint with x'); + test(function() { + checkDOMPoint(DOMPoint.fromPoint({x:1, y:2}), {x:1, y:2, z:0, w:1}); + },'test DOMPoint fromPoint with x, y'); + test(function() { + checkDOMPoint(DOMPoint.fromPoint({x:1, y:2, z:3}), {x:1, y:2, z:3, w:1}); + },'test DOMPoint fromPoint with x, y, z'); + test(function() { + checkDOMPoint(DOMPoint.fromPoint({x:1, y:2, z:3, w:4}), {x:1, y:2, z:3, w:4}); + },'test DOMPoint fromPoint with x, y, z, w'); + test(function() { + checkDOMPoint(DOMPoint.fromPoint({x:1, y:2, z:3, w:4, v:5}), {x:1, y:2, z:3, w:4}); + },'test DOMPoint fromPoint with x, y, z, w, v'); + test(function() { + checkDOMPoint(DOMPoint.fromPoint({x:1, z:3}), {x:1, y:0, z:3, w:1}); + },'test DOMPoint fromPoint with x, z'); + test(function() { + checkDOMPoint(DOMPoint.fromPoint({x:1, y: undefined, z:3}), {x:1, y:0, z:3, w:1}); + },'test DOMPoint fromPoint with undefined value'); + test(function() { + var point = new DOMPoint(5, 4); + var matrix = new DOMMatrix([2, 0, 0, 2, 10, 10]); + var result = point.matrixTransform(matrix); + var expected = getMatrixTransform(matrix, point); + checkDOMPoint(result, expected); + },'test DOMPoint matrixTransform'); + test(function() { + var point = new DOMPoint(42, 84); + assert_throws_js(TypeError, function() { + point.matrixTransform({ is2D: true, m33: 1.0000001 }); + }); + },'test DOMPoint matrixTransform with inconsistent input'); + test(function() { + var p = new DOMPoint(0, 0, 0, 1); + p.x = undefined; + p.y = undefined; + p.z = undefined; + p.w = undefined; + checkDOMPoint(p, {x:NaN, y:NaN, z:NaN, w:NaN}); + },'test DOMPoint Attributes undefined'); + test(function() { + var p = new DOMPoint(0, 0, 0, 1); + p.x = NaN; + p.y = Number.POSITIVE_INFINITY; + p.z = Number.NEGATIVE_INFINITY; + p.w = Infinity; + checkDOMPoint(p, {x:NaN, y:Infinity, z:-Infinity, w:Infinity}); + },'test DOMPoint Attributes NaN Infinity'); + test(function() { + checkDOMPoint(new DOMPointReadOnly(), {x:0, y:0, z:0, w:1}); + },'test DOMPointReadOnly Constructor no args'); + test(function() { + checkDOMPoint(new DOMPointReadOnly(1), {x:1, y:0, z:0, w:1}); + },'test DOMPointReadOnly Constructor one args'); + test(function() { + checkDOMPoint(new DOMPointReadOnly(1, 2), {x:1, y:2, z:0, w:1}); + },'test DOMPointReadOnly Constructor two args'); + test(function() { + checkDOMPoint(new DOMPointReadOnly(1, 2, 3), {x:1, y:2, z:3, w:1}); + },'test DOMPointReadOnly Constructor three args'); + test(function() { + checkDOMPoint(new DOMPointReadOnly(1, 2, 3, 4), {x:1, y:2, z:3, w:4}); + },'test DOMPointReadOnly Constructor four args'); + test(function() { + checkDOMPoint(new DOMPointReadOnly(1, 2, 3, 4, 5), {x:1, y:2, z:3, w:4}); + },'test DOMPointReadOnly Constructor more then four args'); + test(function() { + checkDOMPoint(new DOMPointReadOnly(1, undefined), {x:1, y:0, z:0, w:1}); + },'test DOMPointReadOnly Constructor with undefined'); + test(function() { + checkDOMPoint(new DOMPointReadOnly("a", "b"), {x:NaN, y:NaN, z:0, w:1}); + },'test DOMPointReadOnly Constructor with string'); + test(function() { + checkDOMPoint(new DOMPointReadOnly({}), {x:NaN, y:0, z:0, w:1}); + },'test DOMPointReadOnly Constructor with object'); + test(function() { + checkDOMPoint(DOMPointReadOnly.fromPoint({}), {x:0, y:0, z:0, w:1}); + },'test DOMPointReadOnly fromPoint with empty object'); + test(function() { + checkDOMPoint(DOMPointReadOnly.fromPoint({x:1}), {x:1, y:0, z:0, w:1}); + },'test DOMPointReadOnly fromPoint with x'); + test(function() { + checkDOMPoint(DOMPointReadOnly.fromPoint({x:1, y:2}), {x:1, y:2, z:0, w:1}); + },'test DOMPointReadOnly fromPoint with x, y'); + test(function() { + checkDOMPoint(DOMPointReadOnly.fromPoint({x:1, y:2, z:3}), {x:1, y:2, z:3, w:1}); + },'test DOMPointReadOnly fromPoint with x, y, z'); + test(function() { + checkDOMPoint(DOMPointReadOnly.fromPoint({x:1, y:2, z:3, w:4}), {x:1, y:2, z:3, w:4}); + },'test DOMPointReadOnly fromPoint with x, y, z, w'); + test(function() { + checkDOMPoint(DOMPointReadOnly.fromPoint({x:1, y:2, z:3, w:4, v:5}), {x:1, y:2, z:3, w:4}); + },'test DOMPointReadOnly fromPoint with x, y, z, w, v'); + test(function() { + checkDOMPoint(DOMPointReadOnly.fromPoint({x:1, z:3}), {x:1, y:0, z:3, w:1}); + },'test DOMPointReadOnly fromPoint with x, z'); + test(function() { + checkDOMPoint(DOMPointReadOnly.fromPoint({x:1, y: undefined, z:3}), {x:1, y:0, z:3, w:1}); + },'test DOMPointReadOnly fromPoint with undefined value'); + test(function() { + var point = new DOMPointReadOnly(5, 4); + var matrix = new DOMMatrix([1, 2, 3, 4, 5, 6]); + var result = point.matrixTransform(matrix); + var expected = getMatrixTransform(matrix, point); + checkDOMPoint(result, expected); + },'test DOMPointReadOnly matrixTransform'); + test(function() { + var p = new DOMPointReadOnly(0, 0, 0, 1); + p.x = undefined; + p.y = undefined; + p.z = undefined; + p.w = undefined; + checkDOMPoint(p, {x:0, y:0, z:0, w:1}); + },'test DOMPointReadOnly Attributes undefined'); + + function checkDOMPoint(p, exp) { + assert_equals(p.x, exp.x, "x is not matched"); + assert_equals(p.y, exp.y, "y is not matched"); + assert_equals(p.z, exp.z, "z is not matched"); + assert_equals(p.w, exp.w, "w is not matched"); + } + </script> + + +</body></html> diff --git a/testing/web-platform/tests/css/geometry/DOMQuad-001.html b/testing/web-platform/tests/css/geometry/DOMQuad-001.html new file mode 100644 index 0000000000..6fa765bbab --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMQuad-001.html @@ -0,0 +1,156 @@ +<!DOCTYPE html> +<html> +<head> + <title>Geometry Interfaces: DOMQuad interface tests</title> + <link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com" /> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#dom-domquad-domquad"> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#dom-domquad-p1"> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#dom-domquad-p2"> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#dom-domquad-p3"> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#dom-domquad-p4"> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#DOMQuad"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <p>Test DOMQuad interface</p> + <div id="log"></div> + <script> + var initial = { + p1: { x: 0, y: 0, z: 0, w: 1 }, + p2: { x: 0, y: 0, z: 0, w: 1 }, + p3: { x: 0, y: 0, z: 0, w: 1 }, + p4: { x: 0, y: 0, z: 0, w: 1 }, + bounds: { x: 0, y: 0, width: 0, height: 0 } + }; + + checkDOMQuad(function() { return new DOMQuad(); }, initial, 'testConstructor0'); + + test(function() { + assert_throws_js(TypeError, function() { new DOMQuad(1); }); + },'testConstructor1'); + + test(function() { + assert_throws_js(TypeError, function() { new DOMQuad(1, 2); }); + },'testConstructor2'); + + test(function() { + assert_throws_js(TypeError, function() { new DOMQuad(1, 2, 3); }); + },'testConstructor3'); + + test(function() { + assert_throws_js(TypeError, function() { new DOMQuad(1, 2, 3, 4); }); + },'testConstructor4'); + + checkDOMQuad( + function() { return DOMQuad.fromRect(new DOMRect(10, 20, 100, 200)); }, + { p1: { x: 10, y: 20, z: 0, w: 1 }, + p2: { x: 110, y: 20, z: 0, w: 1 }, + p3: { x: 110, y: 220, z: 0, w: 1 }, + p4: { x: 10, y: 220, z: 0, w: 1 }, + bounds: { x: 10, y: 20, width: 100, height: 200 } }, + 'fromRect() method on DOMQuad'); + + checkDOMQuad( + function() { return DOMQuad.fromRect(new DOMRect(10, 20, -100, -200)) }, + { p1: { x: 10, y: 20, z: 0, w: 1 }, + p2: { x: -90, y: 20, z: 0, w: 1 }, + p3: { x: -90, y: -180, z: 0, w: 1 }, + p4: { x: 10, y: -180, z: 0, w: 1 }, + bounds: { x: -90, y: -180, width: 100, height: 200 } }, + 'fromRect() method on DOMQuad with negatives'); + + checkDOMQuad( + function() { return DOMQuad.fromRect(new DOMRect(-Infinity, -Infinity, Infinity, Infinity)) }, + { p1: { x: -Infinity, y: -Infinity, z: 0, w: 1 }, + p2: { x: NaN, y: -Infinity, z: 0, w: 1 }, + p3: { x: NaN, y: NaN, z: 0, w: 1 }, + p4: { x: -Infinity, y: NaN, z: 0, w: 1 }, + bounds: { x: NaN, y: NaN, width: NaN, height: NaN } }, + 'fromRect() method on DOMQuad with Infinity'); + + checkDOMQuad(function() { return new DOMQuad(new DOMRect()); }, initial, 'testConstructor8'); + + checkDOMQuad(function() { return new DOMQuad({}); }, initial, 'testConstructor9'); + + checkDOMQuad(function() { return new DOMQuad({}, {}); }, initial, 'testConstructor10'); + + checkDOMQuad(function() { return new DOMQuad({}, {}, {}); }, initial, 'testConstructor11'); + + checkDOMQuad(function() { return new DOMQuad({}, {}, {}, {}); }, initial, 'testConstructor12'); + + checkDOMQuad(function() { return new DOMQuad(null, undefined, {}, {}); }, initial, 'testConstructor13'); + + checkDOMQuad(function() { return new DOMQuad({}, {}, {}, {}, NaN); }, initial, 'testConstructor14'); + + test(function() { + assert_throws_js(TypeError, function() { new DOMQuad({}, {}, {}, NaN); }); + },'testConstructor15'); + + checkDOMQuad(function() { + return new DOMQuad({ y: 10 }, { x: 20 }, { z: 30 }, { x: 20, y: 10, z: 20, w: 10 }); + }, + { p1: { x: 0, y: 10, z: 0, w: 1 }, + p2: { x: 20, y: 0, z: 0, w: 1 }, + p3: { x: 0, y: 0, z: 30, w: 1 }, + p4: { x: 20, y: 10, z: 20, w: 10 }, + bounds: { x: 0, y: 0, width: 20, height: 10 } }, + 'testConstructor16'); + + checkDOMQuad(function() { + // p1 to p4 are readonly attributes. + var q = new DOMQuad({}, {}, {}, {}); + q.p1 = new DOMPoint(2, 2); + q.p2 = new DOMPoint(2, 2); + q.p3 = new DOMPoint(2, 2); + q.p4 = new DOMPoint(2, 2); + return q; + }, initial, 'p1Top4Attributes0'); + + checkDOMQuad(function() { + var q = new DOMQuad({}, {}, {}, {}); + q.p1.x = 2; + q.p2.x = 2; + q.p3.x = 2; + q.p4.x = 2; + return q; + }, + { p1: { x: 2, y: 0, z: 0, w: 1 }, + p2: { x: 2, y: 0, z: 0, w: 1 }, + p3: { x: 2, y: 0, z: 0, w: 1 }, + p4: { x: 2, y: 0, z: 0, w: 1 }, + bounds: { x: 2, y: 0, width: 0, height: 0 } }, + 'p1Top4Attributes1'); + + function checkDOMQuad(createQuad, exp, name) { + test(function() { + var q = createQuad(); + assert_equals(q.p1.x, exp.p1.x, "Expected value for p1.x is " + exp.p1.x); + assert_equals(q.p1.y, exp.p1.y, "Expected value for p1.y is " + exp.p1.y); + assert_equals(q.p1.z, exp.p1.z, "Expected value for p1.z is " + exp.p1.z); + assert_equals(q.p1.w, exp.p1.w, "Expected value for p1.w is " + exp.p1.w); + assert_equals(q.p2.x, exp.p2.x, "Expected value for p2.x is " + exp.p2.x); + assert_equals(q.p2.y, exp.p2.y, "Expected value for p2.y is " + exp.p2.y); + assert_equals(q.p2.z, exp.p2.z, "Expected value for p2.z is " + exp.p2.z); + assert_equals(q.p2.w, exp.p2.w, "Expected value for p2.w is " + exp.p2.w); + assert_equals(q.p3.x, exp.p3.x, "Expected value for p3.x is " + exp.p3.x); + assert_equals(q.p3.y, exp.p3.y, "Expected value for p3.y is " + exp.p3.y); + assert_equals(q.p3.z, exp.p3.z, "Expected value for p3.z is " + exp.p3.z); + assert_equals(q.p3.w, exp.p3.w, "Expected value for p3.w is " + exp.p3.w); + assert_equals(q.p4.x, exp.p4.x, "Expected value for p4.x is " + exp.p4.x); + assert_equals(q.p4.y, exp.p4.y, "Expected value for p4.y is " + exp.p4.y); + assert_equals(q.p4.z, exp.p4.z, "Expected value for p4.z is " + exp.p4.z); + assert_equals(q.p4.w, exp.p4.w, "Expected value for p4.w is " + exp.p4.w); + }, name + ": points"); + + test(function() { + var q = createQuad(); + assert_equals(q.getBounds().x, exp.bounds.x, "Expected value for getBounds().x is " + exp.bounds.x); + assert_equals(q.getBounds().y, exp.bounds.y, "Expected value for getBounds().y is " + exp.bounds.y); + assert_equals(q.getBounds().width, exp.bounds.width, "Expected value for getBounds().width is " + exp.bounds.width); + assert_equals(q.getBounds().height, exp.bounds.height, "Expected value for getBounds().height is " + exp.bounds.height); + }, name + ": bounds"); + } + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/geometry/DOMQuad-002.html b/testing/web-platform/tests/css/geometry/DOMQuad-002.html new file mode 100644 index 0000000000..5734be1f29 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMQuad-002.html @@ -0,0 +1,173 @@ +<!DOCTYPE html> +<html> +<head> + <title>Geometry Interfaces: DOMQuad interface tests</title> + <link rel="author" title="Hwanseung Lee" href="mailto:hs1217.lee@samsung.com" /> + <link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMQuad"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <p>Test DOMQuad interface</p> + <div id="log"></div> + <script> + + function init() { + var initial = { + p1: { x: 0, y: 0, z: 0, w: 1 }, + p2: { x: 0, y: 0, z: 0, w: 1 }, + p3: { x: 0, y: 0, z: 0, w: 1 }, + p4: { x: 0, y: 0, z: 0, w: 1 } + }; + return initial; + } + + test(function() { + checkDOMQuad(new DOMQuad(), init()); + },'test Constructor no args'); + + test(function() { + checkDOMQuad(new DOMQuad(new DOMPoint()), init()); + },'test Constructor with one init DOMPoint arg'); + + test(function() { + checkDOMQuad(new DOMQuad(new DOMPoint(), new DOMPoint()), init()); + },'test Constructor with two init DOMPoint args'); + + test(function() { + checkDOMQuad(new DOMQuad(new DOMPoint(), new DOMPoint(), new DOMPoint()), init()); + },'test Constructor with three init DOMPoint args'); + + test(function() { + checkDOMQuad(new DOMQuad(new DOMPoint(), new DOMPoint(), new DOMPoint(), new DOMPoint()), init()); + },'test Constructor with four init DOMPoint args'); + + test(function() { + var exp = init(); + exp.p1 = { x: 1, y: 2, z: 3, w: 4 }; + checkDOMQuad(new DOMQuad(new DOMPoint(1, 2, 3, 4)), exp); + },'test Constructor with one DOMPoint arg'); + + test(function() { + var exp = init(); + exp.p1 = { x: 1, y: 2, z: 3, w: 4 }; + exp.p2 = { x: 5, y: 6, z: 7, w: 8 }; + checkDOMQuad(new DOMQuad(new DOMPoint(1, 2, 3, 4), new DOMPoint(5, 6, 7, 8)), exp); + },'test Constructor with two DOMPoint args'); + + test(function() { + var exp = init(); + exp.p1 = { x: 1, y: 2, z: 3, w: 4 }; + exp.p2 = { x: 5, y: 6, z: 7, w: 8 }; + exp.p3 = { x: 9, y: 10, z: 11, w: 12 }; + checkDOMQuad(new DOMQuad(new DOMPoint(1, 2, 3, 4), new DOMPoint(5, 6, 7, 8), new DOMPoint(9, 10, 11, 12)), exp); + },'test Constructor with three DOMPoint args'); + + test(function() { + var exp = init(); + exp.p1 = { x: 1, y: 2, z: 3, w: 4 }; + exp.p2 = { x: 5, y: 6, z: 7, w: 8 }; + exp.p3 = { x: 9, y: 10, z: 11, w: 12 }; + exp.p4 = { x: 13, y: 14, z: 15, w: 16 }; + checkDOMQuad(new DOMQuad(new DOMPoint(1, 2, 3, 4), new DOMPoint(5, 6, 7, 8), new DOMPoint(9, 10, 11, 12), new DOMPoint(13, 14, 15, 16)), exp); + },'test Constructor with four DOMPoint args'); + + test(function() { + assert_throws_js(TypeError, function() { new DOMQuad(1, 2, 3, 4); }); + },'test Constructor with invaild integer args'); + + test(function() { + assert_throws_js(TypeError, function() { new DOMQuad("1", "2", "3", "4"); }); + },'test Constructor with invaild string args'); + + test(function() { + assert_throws_js(TypeError, function() { new DOMQuad({}, {}, {}, NaN); }); + },'test Constructor with NaN'); + + test(function() { + var domQuad = DOMQuad.fromRect(new DOMRect(10, 20, 100, 200)); + var expQuad = init(); + expQuad.p1 = { x: 10, y: 20, z: 0, w: 1 }; + expQuad.p2 = { x: 110, y: 20, z: 0, w: 1 }; + expQuad.p3 = { x: 110, y: 220, z: 0, w: 1 }; + expQuad.p4 = { x: 10, y: 220, z: 0, w: 1 }; + checkDOMQuad(domQuad, expQuad); + },'test fromRect'); + + test(function() { + var domQuad = DOMQuad.fromRect(new DOMRect(-Infinity, -Infinity, Infinity, Infinity)); + var expQuad = init(); + expQuad.p1 = { x: -Infinity, y: -Infinity, z: 0, w: 1 }; + expQuad.p2 = { x: NaN, y: -Infinity, z: 0, w: 1 }; + expQuad.p3 = { x: NaN, y: NaN, z: 0, w: 1 }; + expQuad.p4 = { x: -Infinity, y: NaN, z: 0, w: 1 }; + checkDOMQuad(domQuad, expQuad); + },'test fromRect with Infinity'); + + test(function() { + var domQuad = DOMQuad.fromQuad( + new DOMQuad( + new DOMPoint(1, 2, 3, 4), + new DOMPoint(5, 6, 7, 8), + new DOMPoint(9, 10, 11, 12), + new DOMPoint(13, 14, 15, 16))); + var exp = init(); + exp.p1 = { x: 1, y: 2, z: 3, w: 4 }; + exp.p2 = { x: 5, y: 6, z: 7, w: 8 }; + exp.p3 = { x: 9, y: 10, z: 11, w: 12 }; + exp.p4 = { x: 13, y: 14, z: 15, w: 16 }; + checkDOMQuad(domQuad, exp); + },'test fromQuad'); + + test(function() { + var domQuad = new DOMQuad(); + domQuad.p1 = new DOMPoint(1, 2, 3, 4); + domQuad.p2 = new DOMPoint(1, 2, 3, 4); + domQuad.p3 = new DOMPoint(1, 2, 3, 4); + domQuad.p4 = new DOMPoint(1, 2, 3, 4); + checkDOMQuad(domQuad, init()); + },'test p1, p2, p3, p4 are readonly'); + + test(function() { + var domQuad = DOMQuad.fromQuad( + new DOMQuad( + new DOMPoint(10, 20, 0, 1), + new DOMPoint(110, 20, 0, 1), + new DOMPoint(110, 220, 0, 1), + new DOMPoint(10, 220, 10, 1))); + var expBound = new DOMRect(10, 20, 100, 200); + checkDOMRect(domQuad.getBounds(), expBound); + },'test getBounds'); + + function checkDOMQuad(actual, exp) { + assert_equals(actual.p1.x, exp.p1.x, "p1.x is not matched"); + assert_equals(actual.p1.y, exp.p1.y, "p1.y is not matched"); + assert_equals(actual.p1.z, exp.p1.z, "p1.z is not matched"); + assert_equals(actual.p1.w, exp.p1.w, "p1.w is not matched"); + assert_equals(actual.p2.x, exp.p2.x, "p2.x is not matched"); + assert_equals(actual.p2.y, exp.p2.y, "p2.y is not matched"); + assert_equals(actual.p2.z, exp.p2.z, "p2.z is not matched"); + assert_equals(actual.p2.w, exp.p2.w, "p2.w is not matched"); + assert_equals(actual.p3.x, exp.p3.x, "p3.x is not matched"); + assert_equals(actual.p3.y, exp.p3.y, "p3.y is not matched"); + assert_equals(actual.p3.z, exp.p3.z, "p3.z is not matched"); + assert_equals(actual.p3.w, exp.p3.w, "p3.w is not matched"); + assert_equals(actual.p4.x, exp.p4.x, "p4.x is not matched"); + assert_equals(actual.p4.y, exp.p4.y, "p4.y is not matched"); + assert_equals(actual.p4.z, exp.p4.z, "p4.z is not matched"); + assert_equals(actual.p4.w, exp.p4.w, "p4.w is not matched"); + } + + function checkDOMRect(actual, exp) { + assert_equals(actual.x, exp.x, "x is not matched"); + assert_equals(actual.y, exp.y, "y is not matched"); + assert_equals(actual.width, exp.width, "width is not matched"); + assert_equals(actual.height, exp.height, "height is not matched"); + assert_equals(actual.top, exp.top, "top is not matched"); + assert_equals(actual.left, exp.left, "left is not matched"); + assert_equals(actual.bottom, exp.bottom, "bottom is not matched"); + assert_equals(actual.right, exp.right, "right is not matched"); + } + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/geometry/DOMQuad-nan.html b/testing/web-platform/tests/css/geometry/DOMQuad-nan.html new file mode 100644 index 0000000000..8d93d5ecfa --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMQuad-nan.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>DOMRect's handling of NaN in top/bottom/left/right</title> +<link rel=help href="https://drafts.fxtf.org/geometry/#dom-domrectreadonly-domrect-top"> +<link rel=help href="https://drafts.fxtf.org/geometry/#dom-domrectreadonly-domrect-bottom"> +<link rel=help href="https://drafts.fxtf.org/geometry/#dom-domrectreadonly-domrect-left"> +<link rel=help href="https://drafts.fxtf.org/geometry/#dom-domrectreadonly-domrect-right"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +"use strict"; + +for (const i of [1, 2, 3, 4]) { + for (const comp of ["x", "y"]) { + test(() => { + const args = [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }]; + args[i - 1][comp] = NaN; + const quad = new DOMQuad(...args); + const bounds = quad.getBounds(); + if (comp === "x") { + assert_equals(bounds.x, NaN, "x coordinate"); + assert_equals(bounds.y, 0, "y coordinate"); + assert_equals(bounds.width, NaN, "width"); + assert_equals(bounds.height, 0, "height"); + } else { + assert_equals(bounds.x, 0, "x coordinate"); + assert_equals(bounds.y, NaN, "y coordinate"); + assert_equals(bounds.width, 0, "width"); + assert_equals(bounds.height, NaN, "height"); + } + }, `Setting DOMQuad's p${i}.${comp} to NaN`); + } +} +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMRect-001.html b/testing/web-platform/tests/css/geometry/DOMRect-001.html new file mode 100644 index 0000000000..3055d8d26b --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMRect-001.html @@ -0,0 +1,161 @@ +<!DOCTYPE html> +<html> +<head> + <title>Geometry Interfaces: DOMRect and DOMRectReadOnly interface tests</title> + <link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com" /> + <link rel="help" href="https://www.w3.org/TR/geometry-1/#DOMRect"> + <link rel="help" href="http://www.w3.org/TR/geometry-1/#dom-domrectreadonly-domrect-x"> + <link rel="help" href="http://www.w3.org/TR/geometry-1/#dom-domrectreadonly-domrect-y"> + <link rel="help" href="http://www.w3.org/TR/geometry-1/#dom-domrectreadonly-domrect-width"> + <link rel="help" href="http://www.w3.org/TR/geometry-1/#dom-domrectreadonly-domrect-height"> + <link rel="help" href="http://www.w3.org/TR/geometry-1/#dom-domrectreadonly-domrect-top"> + <link rel="help" href="http://www.w3.org/TR/geometry-1/#dom-domrectreadonly-domrect-left"> + <link rel="help" href="http://www.w3.org/TR/geometry-1/#dom-domrectreadonly-domrect-right"> + <link rel="help" href="http://www.w3.org/TR/geometry-1/#dom-domrectreadonly-domrect-bottom"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <p>Test DOMRect and DOMRectReadOnly interfaces</p> + <div id="log"></div> + <script> + testConstructor(DOMRect); + testConstructor(DOMRectReadOnly); + test(function() { + var r = new DOMRect(); + r.top = 5; + assert_equals(r.top, 0, "Expected value for top is 0"); + r.right = 5; + assert_equals(r.right, 0, "Expected value for right is 0"); + r.bottom = 5; + assert_equals(r.bottom, 0, "Expected value for bottom is 0"); + r.left = 5; + assert_equals(r.left, 0, "Expected value for left is 0"); + },'testSetReadOnlyAttributes'); + test(function() { + var r = new DOMRect(); + r.x = 5; + assert_equals(r.x, 5, "Expected value for x is 5"); + assert_equals(r.left, 5, "Expected value for left is 5"); + assert_equals(r.right, 5, "Expected value for right is 5"); + r.y = 5; + assert_equals(r.y, 5, "Expected value for y is 5"); + assert_equals(r.top, 5, "Expected value for top is 5"); + assert_equals(r.bottom, 5, "Expected value for bottom is 5"); + r.width = 5; + assert_equals(r.width, 5, "Expected value for width is 5"); + assert_equals(r.left, 5, "Expected value for left is 5"); + assert_equals(r.right, 10, "Expected value for right is 10"); + r.height = 5; + assert_equals(r.height, 5, "Expected value for height is 5"); + assert_equals(r.top, 5, "Expected value for top is 5"); + assert_equals(r.bottom, 10, "Expected value for bottom is 10"); + },'testSetAttributes'); + test(function() { + var r = new DOMRectReadOnly(); + r.top = 5; + assert_equals(r.top, 0, "Expected value for top is 0"); + assert_equals(r.y, 0, "Expected value for y is 0"); + assert_equals(r.bottom, 0, "Expected value for bottom is 0"); + r.right = 5; + assert_equals(r.right, 0, "Expected value for right is 0"); + assert_equals(r.x, 0, "Expected value for x is 0"); + assert_equals(r.left, 0, "Expected value for left is 0"); + r.bottom = 5; + assert_equals(r.bottom, 0, "Expected value for bottom is 0"); + assert_equals(r.y, 0, "Expected value for y is 0"); + assert_equals(r.top, 0, "Expected value for top is 0"); + r.left = 5; + assert_equals(r.left, 0, "Expected value for left is 0"); + assert_equals(r.x, 0, "Expected value for x is 0"); + assert_equals(r.right, 0, "Expected value for right is 0"); + },'testReadOnlySetReadOnlyAttributes'); + test(function() { + var r = new DOMRectReadOnly(); + r.x = 0; + assert_equals(r.x, 0, "Expected value for x is 0"); + assert_equals(r.left, 0, "Expected value for left is 0"); + assert_equals(r.right, 0, "Expected value for right is 0"); + r.y = 0; + assert_equals(r.y, 0, "Expected value for y is 0"); + assert_equals(r.top, 0, "Expected value for top is 0"); + assert_equals(r.bottom, 0, "Expected value for bottom is 0"); + r.width = 0; + assert_equals(r.width, 0, "Expected value for width is 0"); + assert_equals(r.x, 0, "Expected value for x is 0"); + assert_equals(r.right, 0, "Expected value for right is 0"); + r.height = 0; + assert_equals(r.height, 0, "Expected value for height is 0"); + assert_equals(r.y, 0, "Expected value for y is 0"); + assert_equals(r.bottom, 0, "Expected value for bottom is 0"); + },'testReadOnlySetAttributes'); + + function testConstructor(constructor) { + var prefix = constructor === DOMRect ? 'testConstructor' : 'testReadOnlyConstructor'; + test(function() { + checkDOMRect(new constructor(), + { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 }); + }, prefix + '0'); + test(function() { + checkDOMRect(new constructor(1), + { x: 1, y: 0, width: 0, height: 0, top: 0, right: 1, bottom: 0, left: 1 }); + }, prefix + '1'); + test(function() { + checkDOMRect(new constructor(1, 2), + { x: 1, y: 2, width: 0, height: 0, top: 2, right: 1, bottom: 2, left: 1 }); + }, prefix + '2'); + test(function() { + checkDOMRect(new constructor(1, 2, 3), + { x: 1, y: 2, width: 3, height: 0, top: 2, right: 4, bottom: 2, left: 1 }); + }, prefix + '3'); + test(function() { + checkDOMRect(new constructor(1, 2, 3, 4), + { x: 1, y: 2, width: 3, height: 4, top: 2, right: 4, bottom: 6, left: 1 }); + }, prefix + '4'); + test(function() { + checkDOMRect(new constructor(1, 2, 3, 4, 5), + { x: 1, y: 2, width: 3, height: 4, top: 2, right: 4, bottom: 6, left: 1 }); + }, prefix + '5'); + test(function() { + checkDOMRect(new constructor(2, 2, -4, 4), + { x: 2, y: 2, width: -4, height: 4, top: 2, right: 2, bottom: 6, left: -2 }); + }, prefix + 'NegativeWidth'); + test(function() { + checkDOMRect(new constructor(2, 2, 4, -4), + { x: 2, y: 2, width: 4, height: -4, top: -2, right: 6, bottom: 2, left: 2 }); + }, prefix + 'NegativeHeight'); + test(function() { + checkDOMRect(new constructor(2, 2, -4, -4), + { x: 2, y: 2, width: -4, height: -4, top: -2, right: 2, bottom: 2, left: -2 }); + }, prefix + 'NegativeWidthHeight'); + test(function() { + checkDOMRect(new constructor(0, 0, undefined, 4), + { x: 0, y: 0, width: 0, height: 4, top: 0, right: 0, bottom: 4, left: 0 }); + }, prefix + 'Undefined1'); + test(function() { + checkDOMRect(new constructor(NaN, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY, null), + { x: NaN, y: -Infinity, width: Infinity, height: 0, top: -Infinity, right: NaN, bottom: -Infinity, left: NaN }); + }, prefix + 'Undefined2'); + test(function() { + checkDOMRect(new constructor("1", "2", "3", "4"), + { x: 1, y: 2, width: 3, height: 4, top: 2, right: 4, bottom: 6, left: 1 }); + }, prefix + 'String1'); + test(function() { + checkDOMRect(new constructor("a", "b", "c", "d"), + { x: NaN, y: NaN, width: NaN, height: NaN, top: NaN, right: NaN, bottom: NaN, left: NaN }); + }, prefix + 'String2'); + } + + function checkDOMRect(r, exp) { + assert_equals(r.x, exp.x, "Expected value for x is " + exp.x); + assert_equals(r.y, exp.y, "Expected value for y is " + exp.y); + assert_equals(r.width, exp.width, "Expected value for width is " + exp.width); + assert_equals(r.height, exp.height, "Expected value for height is " + exp.height); + assert_equals(r.top, exp.top, "Expected value for top is " + exp.top); + assert_equals(r.left, exp.left, "Expected value for left is " + exp.left); + assert_equals(r.bottom, exp.bottom, "Expected value for bottom is " + exp.bottom); + assert_equals(r.right, exp.right, "Expected value for right is " + exp.right); + } + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/geometry/DOMRect-002.html b/testing/web-platform/tests/css/geometry/DOMRect-002.html new file mode 100644 index 0000000000..a5f0f88428 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMRect-002.html @@ -0,0 +1,171 @@ +<!DOCTYPE html> +<html> +<head> + <title>Geometry Interfaces: DOMRect and DOMRectReadOnly interface tests</title> + <link rel="author" title="Hwanseung Lee" href="mailto:hs1217.lee@samsung.com" /> + <link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMRect"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <div id="log"></div> + <script> + testConstructor("DOMRect"); + testConstructor("DOMRectReadOnly"); + test(function() { + var r = new DOMRect(); + r.top = 5; + assert_equals(r.top, 0, "top"); + r.right = 5; + assert_equals(r.right, 0, "right"); + r.bottom = 5; + assert_equals(r.bottom, 0, "bottom"); + r.left = 5; + assert_equals(r.left, 0, "left"); + }, 'DOMRect: set top/right/bottom/left'); + + test(function() { + var r = new DOMRect(); + r.x = 5; + assert_equals(r.x, 5, "Expected value for x is 5"); + assert_equals(r.left, 5, "Expected value for left is 5"); + assert_equals(r.right, 5, "Expected value for right is 5"); + r.y = 5; + assert_equals(r.y, 5, "Expected value for y is 5"); + assert_equals(r.top, 5, "Expected value for top is 5"); + assert_equals(r.bottom, 5, "Expected value for bottom is 5"); + r.width = 5; + assert_equals(r.width, 5, "Expected value for width is 5"); + assert_equals(r.left, 5, "Expected value for left is 5"); + assert_equals(r.right, 10, "Expected value for right is 10"); + r.height = 5; + assert_equals(r.height, 5, "Expected value for height is 5"); + assert_equals(r.top, 5, "Expected value for top is 5"); + assert_equals(r.bottom, 10, "Expected value for bottom is 10"); + }, 'DOMRect: set x/y/width/height'); + + test(function() { + var r = new DOMRectReadOnly(); + r.top = 5; + assert_equals(r.top, 0, "top after setting top"); + assert_equals(r.y, 0, "y after setting top"); + assert_equals(r.bottom, 0, "bottom after setting top"); + r.right = 5; + assert_equals(r.right, 0, "right after setting right"); + assert_equals(r.x, 0, "x after setting right"); + assert_equals(r.left, 0, "left after setting right"); + r.bottom = 5; + assert_equals(r.bottom, 0, "bottom after setting bottom"); + assert_equals(r.y, 0, "y after setting bottom"); + assert_equals(r.top, 0, "top after setting bottom"); + r.left = 5; + assert_equals(r.left, 0, "left after setting left"); + assert_equals(r.x, 0, "x after setting left"); + assert_equals(r.right, 0, "right after setting left"); + }, 'DOMRectReadOnly: set top/right/bottom/left'); + + test(function() { + var r = new DOMRectReadOnly(); + r.x = 5; + assert_equals(r.x, 0, "x after setting x"); + assert_equals(r.left, 0, "left after setting x"); + assert_equals(r.right, 0, "right after setting x"); + r.y = 5; + assert_equals(r.y, 0, "y after setting y"); + assert_equals(r.top, 0, "top after setting y"); + assert_equals(r.bottom, 0, "bottom after setting y"); + r.width = 5; + assert_equals(r.width, 0, "width after setting width"); + assert_equals(r.x, 0, "x after setting width"); + assert_equals(r.right, 0, "right after setting width"); + r.height = 5; + assert_equals(r.height, 0, "height after setting height"); + assert_equals(r.y, 0, "y after setting height"); + assert_equals(r.bottom, 0, "bottom after setting height"); + }, 'DOMRectReadOnly: set x/y/width/height'); + + test(function() { + var actual = DOMRect.fromRect({x: 1, y: 2, width: 3, height: 4}); + var expected = new DOMRect(1, 2, 3, 4); + checkDOMRect(actual, expected); + assert_true(actual instanceof DOMRectReadOnly, "actual instanceof DOMRectReadOnly"); + assert_true(actual instanceof DOMRect, "actual instanceof DOMRect"); + }, 'DOMRect.fromRect'); + + test(function() { + var actual = DOMRectReadOnly.fromRect({x: 1, y: 2, width: 3, height: 4}); + var expected = new DOMRectReadOnly(1, 2, 3, 4); + checkDOMRect(actual, expected); + assert_true(actual instanceof DOMRectReadOnly, "actual instanceof DOMRectReadOnly"); + assert_false(actual instanceof DOMRect, "actual instanceof DOMRect"); + }, 'DOMRectReadOnly.fromRect'); + + function testConstructor(constructorString) { + var constructor = self[constructorString]; + test(function() { + checkDOMRect(new constructor(), + { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 }); + }, constructorString + ' constructor without parameter'); + test(function() { + checkDOMRect(new constructor(1), + { x: 1, y: 0, width: 0, height: 0, top: 0, right: 1, bottom: 0, left: 1 }); + }, constructorString + ' constructor with one parameter'); + test(function() { + checkDOMRect(new constructor(1, 2), + { x: 1, y: 2, width: 0, height: 0, top: 2, right: 1, bottom: 2, left: 1 }); + }, constructorString + ' constructor with two parameters'); + test(function() { + checkDOMRect(new constructor(1, 2, 3), + { x: 1, y: 2, width: 3, height: 0, top: 2, right: 4, bottom: 2, left: 1 }); + }, constructorString + ' constructor with three parameters'); + test(function() { + checkDOMRect(new constructor(1, 2, 3, 4), + { x: 1, y: 2, width: 3, height: 4, top: 2, right: 4, bottom: 6, left: 1 }); + }, constructorString + ' constructor with four parameters'); + test(function() { + checkDOMRect(new constructor(1, 2, 3, 4, 5), + { x: 1, y: 2, width: 3, height: 4, top: 2, right: 4, bottom: 6, left: 1 }); + }, constructorString + ' constructor with five parameters'); + test(function() { + checkDOMRect(new constructor(2, 2, -4, 4), + { x: 2, y: 2, width: -4, height: 4, top: 2, right: 2, bottom: 6, left: -2 }); + }, constructorString + ' constructor with negative width'); + test(function() { + checkDOMRect(new constructor(2, 2, 4, -4), + { x: 2, y: 2, width: 4, height: -4, top: -2, right: 6, bottom: 2, left: 2 }); + }, constructorString + ' constructor with negative height'); + test(function() { + checkDOMRect(new constructor(2, 2, -4, -4), + { x: 2, y: 2, width: -4, height: -4, top: -2, right: 2, bottom: 2, left: -2 }); + }, constructorString + ' constructor with negative width and height'); + test(function() { + checkDOMRect(new constructor(0, 0, undefined, 4), + { x: 0, y: 0, width: 0, height: 4, top: 0, right: 0, bottom: 4, left: 0 }); + }, constructorString + ' constructor with undefined'); + test(function() { + checkDOMRect(new constructor(NaN, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY, null), + { x: NaN, y: -Infinity, width: Infinity, height: 0, top: -Infinity, right: NaN, bottom: -Infinity, left: NaN }); + }, constructorString + ' constructor with NaN and infinity and null'); + test(function() { + checkDOMRect(new constructor("1", "2", "3", "4"), + { x: 1, y: 2, width: 3, height: 4, top: 2, right: 4, bottom: 6, left: 1 }); + }, constructorString + ' constructor with number string'); + test(function() { + checkDOMRect(new constructor("a", "b", "c", "d"), + { x: NaN, y: NaN, width: NaN, height: NaN, top: NaN, right: NaN, bottom: NaN, left: NaN }); + }, constructorString + ' constructor with character string'); + } + + function checkDOMRect(r, exp) { + assert_equals(r.x, exp.x, "x"); + assert_equals(r.y, exp.y, "y"); + assert_equals(r.width, exp.width, "width"); + assert_equals(r.height, exp.height, "height"); + assert_equals(r.top, exp.top, "top"); + assert_equals(r.left, exp.left, "left"); + assert_equals(r.bottom, exp.bottom, "bottom"); + assert_equals(r.right, exp.right, "right"); + } + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/geometry/DOMRect-nan.html b/testing/web-platform/tests/css/geometry/DOMRect-nan.html new file mode 100644 index 0000000000..4a7cde5d33 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMRect-nan.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>DOMQuad's handling of NaN in getBounds()</title> +<link rel=help href="https://drafts.fxtf.org/geometry/#dom-domquad-getbounds"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +"use strict"; + +const testCases = [ + { + name: "x coordinate is NaN", + idx: 0, + exp: { + x: NaN, + y: 0, + width: 0, + height: 0, + top: 0, + bottom: 0, + left: NaN, + right: NaN + } + }, + { + name: "y coordinate is NaN", + idx: 1, + exp: { + x: 0, + y: NaN, + width: 0, + height: 0, + top: NaN, + bottom: NaN, + left: 0, + right: 0 + } + }, + { + name: "width is NaN", + idx: 2, + exp: { + x: 0, + y: 0, + width: NaN, + height: 0, + top: 0, + bottom: 0, + left: NaN, + right: NaN + } + }, + { + name: "height is NaN", + idx: 3, + exp: { + x: 0, + y: 0, + width: 0, + height: NaN, + top: NaN, + bottom: NaN, + left: 0, + right: 0 + } + }, +]; + +for (const Rect of [DOMRect, DOMRectReadOnly]) { + for (const testCase of testCases) { + test(() => { + const args = [0, 0, 0, 0]; + args[testCase.idx] = NaN; + const rect = new Rect(...args); + assert_object_equals(rect.toJSON(), testCase.exp); + }, `${Rect.name}'s ${testCase.name}`); + } +} +</script> diff --git a/testing/web-platform/tests/css/geometry/DOMRectList.html b/testing/web-platform/tests/css/geometry/DOMRectList.html new file mode 100644 index 0000000000..e389c33fa6 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/DOMRectList.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<title>Geometry interfaces: DOMRectList</title> +<link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMRectList"> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div id=x>x</div> +<script> +setup(() => { + window.domRectList = document.getElementById('x').getClientRects(); +}); + +test(() => { + assert_true('DOMRectList' in window); +}, 'DOMRectList is exposed'); + +test(() => { + assert_false(domRectList instanceof Array); +}, 'DOMRectList is not [LegacyArrayClass]'); + +test(() => { + assert_equals(domRectList.length, 1); +}, 'DOMRectList length'); + +test(() => { + assert_equals(domRectList[-1], undefined, 'domRectList[-1]'); + assert_class_string(domRectList[0], 'DOMRect', 'domRectList[0]'); + assert_equals(domRectList[1], undefined, 'domRectList[1]'); +}, 'DOMRectList indexed getter'); + +test(() => { + assert_equals(domRectList.item(-1), null, 'domRectList.item(-1)'); + assert_class_string(domRectList.item(0), 'DOMRect', 'domRectList.item(0)'); + assert_equals(domRectList.item(1), null, 'domRectList.item(1)'); + assert_equals(domRectList.item(0), domRectList[0], 'domRectList.item(0) should equal domRectList[0]'); +}, 'DOMRectList item()'); +</script> diff --git a/testing/web-platform/tests/css/geometry/META.yml b/testing/web-platform/tests/css/geometry/META.yml new file mode 100644 index 0000000000..98a2ae9860 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/META.yml @@ -0,0 +1,4 @@ +spec: https://drafts.fxtf.org/geometry/ +suggested_reviewers: + - peterjoel + - dirkschulze diff --git a/testing/web-platform/tests/css/geometry/WebKitCSSMatrix.html b/testing/web-platform/tests/css/geometry/WebKitCSSMatrix.html new file mode 100644 index 0000000000..7c28a5c7fb --- /dev/null +++ b/testing/web-platform/tests/css/geometry/WebKitCSSMatrix.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>Geometry Interfaces: WebKitCSSMatrix</title> +<link rel="help" href="https://drafts.fxtf.org/geometry/#DOMMatrix"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +test(() => { + assert_true('WebKitCSSMatrix' in self, 'WebKitCSSMatrix should exist'); + assert_true('DOMMatrix' in self, 'DOMMatrix should exist'); + assert_equals(WebKitCSSMatrix, DOMMatrix, 'interface object'); + assert_equals(WebKitCSSMatrix.prototype, DOMMatrix.prototype, 'prototype'); +}, 'Equivalence test'); + +['WebKitCSSMatrix', 'DOMMatrix'].forEach(interf => { + test(() => { + const desc = Object.getOwnPropertyDescriptor(self, interf); + assert_equals(desc.value, self[interf], 'value'); + assert_true(desc.writable, 'writable'); + assert_true(desc.configurable, 'configurable'); + assert_false(desc.enumerable, 'enumerable'); + assert_equals(desc.get, undefined, 'get'); + assert_equals(desc.set, undefined, 'set'); + }, `Property descriptor for ${interf}`); +}); +</script> diff --git a/testing/web-platform/tests/css/geometry/WebKitCSSMatrix.worker.js b/testing/web-platform/tests/css/geometry/WebKitCSSMatrix.worker.js new file mode 100644 index 0000000000..71e2ecd395 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/WebKitCSSMatrix.worker.js @@ -0,0 +1,9 @@ +// https://drafts.fxtf.org/geometry/#DOMMatrix + +importScripts('/resources/testharness.js'); + +test(() => { + assert_false('WebKitCSSMatrix' in self); +}, 'WebKitCSSMatrix in worker'); + +done(); diff --git a/testing/web-platform/tests/css/geometry/historical.html b/testing/web-platform/tests/css/geometry/historical.html new file mode 100644 index 0000000000..ddc3c777a0 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/historical.html @@ -0,0 +1,91 @@ +<!doctype html> +<title>Historical Geometry APIs</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<link rel=help href="https://drafts.fxtf.org/geometry/#changes"> +<script> +// Removed members +[ + // https://github.com/w3c/fxtf-drafts/commit/99e3212469026b2f2f50926a41912d110a1741b7 + ['DOMMatrix', 'scaleNonUniformSelf'], + // https://github.com/w3c/fxtf-drafts/commit/86da3dc961d442f9d8dc7ab59065a9804e109286 + ['DOMMatrix', 'multiplyBy'], + ['DOMMatrix', 'preMultiplyBy'], + ['DOMMatrix', 'translateBy'], + ['DOMMatrix', 'scaleBy'], + ['DOMMatrix', 'scale3dBy'], + ['DOMMatrix', 'scaleNonUniformBy'], + ['DOMMatrix', 'rotateBy'], + ['DOMMatrix', 'rotateFromVectorBy'], + ['DOMMatrix', 'rotateAxisAngleBy'], + ['DOMMatrix', 'skewXBy'], + ['DOMMatrix', 'skewYBy'], + // https://github.com/w3c/fxtf-drafts/commit/555a8c0beb1b7b809ccebd861a0352df31530b56 + ['DOMQuad', 'bounds'], +].forEach(([interf, member]) => { + test(() => { + assert_true(interf in self, `${interf} should exist`); + assert_false(member in self[interf].prototype, 'on prototype'); + const instance = new self[interf](); + assert_false(member in instance, 'on instance'); + }, `${interf} ${member} must be nuked`); +}); + +// Removed static methods +// https://github.com/w3c/fxtf-drafts/commit/3c43462bcc857bb830f8af04532cdf33c5a634aa +['DOMMatrix', 'DOMMatrixReadOnly'].forEach(interf => { + test(() => { + assert_true(interf in self, `${interf} should exist`); + assert_false('fromString' in self[interf], 'on interface object'); + }, `${interf} fromString static member must be nuked`); +}); + +// Optional arguments +[ + // https://github.com/w3c/fxtf-drafts/commit/99e3212469026b2f2f50926a41912d110a1741b7 + ['DOMMatrixReadOnly', 'scale'], + ['DOMMatrix', 'scaleSelf'], + // https://github.com/w3c/fxtf-drafts/commit/8493a9c3d94da91ead5db6e05b51319494f5855f + ['DOMMatrixReadOnly', 'translate'], + ['DOMMatrixReadOnly', 'scale3d'], + ['DOMMatrixReadOnly', 'rotateFromVector'], + ['DOMMatrixReadOnly', 'rotateAxisAngle'], + ['DOMMatrixReadOnly', 'skewX'], + ['DOMMatrixReadOnly', 'skewY'], + ['DOMMatrix', 'translateSelf'], + ['DOMMatrix', 'scale3dSelf'], + ['DOMMatrix', 'rotateFromVectorSelf'], + ['DOMMatrix', 'rotateAxisAngleSelf'], + ['DOMMatrix', 'skewXSelf'], + ['DOMMatrix', 'skewYSelf'], + // https://github.com/w3c/fxtf-drafts/commit/62b9cb9d5be4982d2a9cbf314e3a59efb8a68dd6 + ['DOMPointReadOnly', 'matrixTransform'], + ['DOMMatrixReadOnly', 'multiply'], + ['DOMMatrix', 'multiplySelf'], + ['DOMMatrix', 'preMultiplySelf'], +].forEach(([interf, member]) => { + test(() => { + assert_equals(self[interf].prototype[member].length, 0, 'on prototype'); + const instance = new self[interf](); + assert_equals(instance[member].length, 0, 'on instance'); + }, `${interf} ${member} number of required arguments`); +}); + +// Renamed interfaces +[ + // https://github.com/w3c/fxtf-drafts/commit/9031c94c8536cec7f7007c18d7be037a793e5ed5 + 'CSSMatrix', + // https://github.com/w3c/csswg-drafts/commit/8d01810fe403bc935c24ee5a29101cac9b958c8c + 'DOMMatrixImmutable', + // https://github.com/w3c/csswg-drafts/commit/6e05c3ee01528daba6dc0776f342beae577cefa9 + 'ClientRect', + 'ClientRectList', + // Non-standard + 'WebKitPoint', + 'MSCSSMatrix', +].forEach(interf => { + test(() => { + assert_false(interf in self); + }, `${interf} must be nuked`); +}); +</script> diff --git a/testing/web-platform/tests/css/geometry/idlharness.any.js b/testing/web-platform/tests/css/geometry/idlharness.any.js new file mode 100644 index 0000000000..5c9170b8a6 --- /dev/null +++ b/testing/web-platform/tests/css/geometry/idlharness.any.js @@ -0,0 +1,32 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// https://drafts.fxtf.org/geometry/#DOMPoint +// https://drafts.fxtf.org/geometry/#DOMRect +// https://drafts.fxtf.org/geometry/#DOMQuad +// https://drafts.fxtf.org/geometry/#DOMMatrix + +"use strict"; + +idl_test( + ["geometry"], + [], + idlArray => { + const domRectListList = []; + if ("document" in self) { + domRectListList.push(document.getElementById('log').getClientRects()); + } + idlArray.add_objects({ + DOMPointReadOnly: ["new DOMPointReadOnly()"], + DOMPoint: ["new DOMPoint()"], + DOMRectReadOnly: ["new DOMRectReadOnly()"], + DOMRect: ["new DOMRect()"], + DOMRectList: domRectListList, + DOMQuad: ["new DOMQuad()"], + DOMMatrixReadOnly: ["new DOMMatrixReadOnly()", "DOMMatrixReadOnly.fromMatrix({is2D: false})"], + DOMMatrix: ["new DOMMatrix()", "DOMMatrix.fromMatrix({is2D: false})"] + }); + idlArray.prevent_multiple_testing("DOMMatrixReadOnly"); + idlArray.prevent_multiple_testing("DOMMatrix"); + } +); diff --git a/testing/web-platform/tests/css/geometry/spec-examples.html b/testing/web-platform/tests/css/geometry/spec-examples.html new file mode 100644 index 0000000000..61efa2a89b --- /dev/null +++ b/testing/web-platform/tests/css/geometry/spec-examples.html @@ -0,0 +1,92 @@ +<!doctype html> +<title>Geometry APIs spec examples</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<link rel=help href="https://drafts.fxtf.org/geometry/"> +<script> +test(() => { + var point = new DOMPoint(5, 4); + var matrix = new DOMMatrix([2, 0, 0, 2, 10, 10]); + var transformedPoint = point.matrixTransform(matrix); + // The point variable is set to a new DOMPoint object with x coordinate initialized to 5 and y + // coordinate initialized to 4. + assert_equals(point.x, 5, 'point.x'); + assert_equals(point.y, 4, 'point.y'); + assert_equals(point.z, 0, 'point.z'); + assert_equals(point.w, 1, 'point.w'); + // This new DOMPoint is now scaled and the translated by matrix. This resulting transformedPoint + // has the x coordinate 20 and y coordinate 18. + assert_equals(transformedPoint.x, 20, 'transformedPoint.x'); + assert_equals(transformedPoint.y, 18, 'transformedPoint.x'); + assert_equals(transformedPoint.z, 0, 'transformedPoint.z'); + assert_equals(transformedPoint.w, 1, 'transformedPoint.w'); +}, 'matrixTransform'); + +test(() => { + var point = new DOMPoint(2, 0); + var quad1 = new DOMQuad(point, {x: 12, y: 0}, {x: 12, y: 10}, {x: 2, y: 10}); + // The attribute values of the resulting DOMQuad quad1 above are also equivalent to the attribute + // values of the following DOMQuad quad2: + var rect = new DOMRect(2, 0, 10, 10); + var quad2 = DOMQuad.fromRect(rect); + for (var p of ['p1', 'p2', 'p3', 'p4']) { + for (var attr of ['x', 'y', 'z', 'w']) { + assert_equals(quad2[p][attr], quad1[p][attr], `${p}.${attr}`); + } + } +}, 'DOMQuad'); + +test(() => { + var quad = new DOMQuad({x: 40, y: 25}, {x: 180, y: 8}, {x: 210, y: 150}, {x: 10, y: 180}); + // <circle cx="40" cy="25" r="3" fill="rgb(204, 51, 51)"/> + assert_equals(quad.p1.x, 40, 'p1.x'); + assert_equals(quad.p1.y, 25, 'p1.y'); + // <circle cx="180" cy="8" r="3" fill="rgb(204, 51, 51)"/> + assert_equals(quad.p2.x, 180, 'p2.x'); + assert_equals(quad.p2.y, 8, 'p2.y'); + // <circle cx="210" cy="150" r="3" fill="rgb(204, 51, 51)"/> + assert_equals(quad.p3.x, 210, 'p3.x'); + assert_equals(quad.p3.y, 150, 'p3.y'); + // <circle cx="10" cy="180" r="3" fill="rgb(204, 51, 51)"/> + assert_equals(quad.p4.x, 10, 'p4.x'); + assert_equals(quad.p4.y, 180, 'p4.y'); + var bounds = quad.getBounds(); + // <rect x="10" y="8" width="200" height="172" fill="none" stroke="black" stroke-dasharray="3 2"/> + assert_equals(bounds.x, 10, 'bounds.x'); + assert_equals(bounds.y, 8, 'bounds.x'); + assert_equals(bounds.width, 200, 'bounds.width'); + assert_equals(bounds.height, 172, 'bounds.height'); +}, 'DOMQuad irregular'); + +test(() => { + // In this example, a matrix is created and several 2D transformation methods are called: + var matrix = new DOMMatrix(); + matrix.scaleSelf(2); + matrix.translateSelf(20,20); + assert_equals(matrix.toString(), "matrix(2, 0, 0, 2, 40, 40)"); +}, 'DOMMatrix 2D transformation'); + +test(() => { + // In the following example, a matrix is created and several 3D transformation methods are called: + var matrix = new DOMMatrix(); + matrix.scale3dSelf(2); + assert_equals(matrix.toString(), "matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1)"); +}, 'DOMMatrix 3D transformation'); + +test(() => { + // This example will throw an exception because there are non-finite values in the matrix. + var matrix = new DOMMatrix([NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]); + assert_throws_dom("InvalidStateError", () => { var string = matrix + " Batman!"; }); +}, 'DOMMatrix NaN'); + +test(() => { + var matrix = new DOMMatrix(); + matrix.translateSelf(20, 20); + matrix.scaleSelf(2); + matrix.translateSelf(-20, -20); + // is equivalent to: + var matrix2 = new DOMMatrix(); + matrix2.translateSelf(20, 20).scaleSelf(2).translateSelf(-20, -20); + assert_equals(matrix.toString(), matrix2.toString()); +}, 'DOMMatrix mutable'); +</script> diff --git a/testing/web-platform/tests/css/geometry/structured-serialization.html b/testing/web-platform/tests/css/geometry/structured-serialization.html new file mode 100644 index 0000000000..5c3e5dd93b --- /dev/null +++ b/testing/web-platform/tests/css/geometry/structured-serialization.html @@ -0,0 +1,165 @@ +<!DOCTYPE html> +<title>Geometry Interfaces: Serialize and deserialize</title> +<link rel="help" href="https://drafts.fxtf.org/geometry/#structured-serialization"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +function clone(obj) { + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); + channel.port2.onmessage = e => resolve(e.data); + channel.port1.postMessage(obj); + }); +} +function defineThrowingGetters(object, attrs) { + for (let attr of attrs) { + Object.defineProperty(object, attr, { + get: () => assert_unreached(`getter for ${attr}`) + }); + } +} + +[ + ["DOMPointReadOnly", "x", "y", "z", "w"], + ["DOMPoint", "x", "y", "z", "w"], + ["DOMRectReadOnly", "x", "y", "width", "height"], + ["DOMRect", "x", "y", "width", "height"], + ["DOMQuad", "p1", "p2", "p3", "p4"], + ["DOMMatrixReadOnly", "a", "b", "c", "d", "e", "f", "m11", "m12", "m13", "m14", "m21", "m22", "m23", "m24", "m31", "m32", "m33", "m34", "m41", "m42", "m43", "m44", "is2D"], + ["DOMMatrix", "a", "b", "c", "d", "e", "f", "m11", "m12", "m13", "m14", "m21", "m22", "m23", "m24", "m31", "m32", "m33", "m34", "m41", "m42", "m43", "m44", "is2D"], +].forEach(([constr, ...attrs]) => { + const prefix = `${constr} clone:`; + + promise_test(t => { + const object = new self[constr](); + return clone(object).then(other => { + assert_not_equals(object, other); + assert_class_string(other, constr); + for (let attr of attrs) { + if (constr === "DOMQuad") { + assert_not_equals(other[attr], object[attr], attr); + assert_class_string(other[attr], "DOMPoint", attr); + assert_equals(other[attr].x, object.p1.x, `${attr}.x`); + assert_equals(other[attr].y, object.p1.y, `${attr}.y`); + assert_equals(other[attr].z, object.p1.z, `${attr}.z`); + assert_equals(other[attr].w, object.p1.w, `${attr}.w`); + } else { + assert_equals(other[attr], object[attr], attr); + } + } + t.done(); + }); + }, `${prefix} basic`); + + promise_test(t => { + const object = new self[constr](); + object.foo = "bar"; + return clone(object).then(other => { + assert_false("foo" in other, 'foo should not exist in other'); + t.done(); + }); + }, `${prefix} custom property`); + + promise_test(t => { + const object = new self[constr](); + // The custom throwing getter on object should not be copied to other. + defineThrowingGetters(object, attrs); + return clone(object).then(other => { + for (let attr of attrs) { + // This should call the standard getter, and therefore not throw. + // If this were to call the throwing getter defined on object, the test would fail. + other[attr]; + } + t.done(); + }); + }, `${prefix} throwing getters`); + + // More specific tests for each type + switch(constr) { + case "DOMPointReadOnly": + case "DOMPoint": + case "DOMRectReadOnly": + case "DOMRect": + promise_test(t => { + const object = new self[constr](1, -0, Infinity, NaN); + return clone(object).then(other => { + for (let attr of attrs) { + assert_equals(other[attr], object[attr], attr); + } + t.done(); + }); + }, `${prefix} non-initial values`); + break; + case "DOMQuad": + promise_test(t => { + const object = new self[constr]({x:1, y:2, z:3, w:4}, + {x:-0, y:-0, z:-0, w:-0}, + {x:Infinity, y:Infinity, z:Infinity, w:Infinity}, + {x:NaN, y:NaN, z:NaN, w:NaN}); + return clone(object).then(other => { + for (let attr of attrs) { + assert_equals(other[attr].x, object[attr].x, `${attr}.x`); + assert_equals(other[attr].y, object[attr].y, `${attr}.y`); + assert_equals(other[attr].z, object[attr].z, `${attr}.z`); + assert_equals(other[attr].w, object[attr].w, `${attr}.w`); + } + t.done(); + }); + }, `${prefix} non-initial values`); + break; + case "DOMMatrixReadOnly": + case "DOMMatrix": + promise_test(t => { + const object = new self[constr]([1, -0, Infinity, NaN, 5, 6]); + object.m13 = -0; + object.m14 = -0; + object.m23 = -0; + object.m24 = -0; + object.m31 = -0; + object.m32 = -0; + object.m34 = -0; + object.m43 = -0; + assert_true(object.is2D, 'is2D after setting m13 etc to -0'); + return clone(object).then(other => { + for (let attr of attrs) { + if (attr === 'm13' || + attr === 'm14' || + attr === 'm23' || + attr === 'm24' || + attr === 'm31' || + attr === 'm32' || + attr === 'm34' || + attr === 'm43') { + assert_equals(other[attr], 0, attr); + } else { + assert_equals(other[attr], object[attr], attr); + } + } + t.done(); + }); + }, `${prefix} non-initial values (2d)`); + + promise_test(t => { + const object = new self[constr]([11, -0, Infinity, NaN, + 21, 22, 23, 24, + 31, 32, 33, 34, + 41, 42, 43, 44]); + return clone(object).then(other => { + for (let attr of attrs) { + assert_equals(other[attr], object[attr], attr); + } + t.done(); + }); + }, `${prefix} non-initial values (3d)`); + break; + default: + throw new Error(`Test bug: ${constr} has no test for non-initial values`); + } +}); + +promise_test((t) => { + const object = document.getElementById('log').getClientRects(); + return promise_rejects_dom(t, "DataCloneError", clone(object)); +}, 'DOMRectList clone');0 +</script> diff --git a/testing/web-platform/tests/css/geometry/support/dommatrix-test-util.js b/testing/web-platform/tests/css/geometry/support/dommatrix-test-util.js new file mode 100644 index 0000000000..40c336ea8c --- /dev/null +++ b/testing/web-platform/tests/css/geometry/support/dommatrix-test-util.js @@ -0,0 +1,85 @@ +// This formats dict as a string suitable as test name. +// format_value() is provided by testharness.js, +// which also preserves sign for -0. +function format_dict(dict) { + const props = []; + for (let prop in dict) { + props.push(`${prop}: ${format_value(dict[prop])}`); + } + return `{${props.join(', ')}}`; +} + +// Create a normal JS object with the expected properties +// from a dict with only m11..m44 specified (not a..f). +function matrix3D(dict) { + const matrix = {m11: 1, m12: 0, m13: 0, m14: 0, + m21: 0, m22: 1, m23: 0, m24: 0, + m31: 0, m32: 0, m33: 1, m34: 0, + m41: 0, m42: 0, m43: 0, m44: 1} + matrix.is2D = false; + for (let member in dict) { + matrix[member] = dict[member]; + } + matrix.a = matrix.m11; + matrix.b = matrix.m12; + matrix.c = matrix.m21; + matrix.d = matrix.m22; + matrix.e = matrix.m41; + matrix.f = matrix.m42; + return matrix; +} + +function matrix2D(dict) { + const matrix = matrix3D(dict); + matrix.is2D = true; + return matrix; +} + +function checkMatrix(actual, expected, { epsilon = Number.MIN_VALUE } = {}) { + for (let member in expected) { + if (epsilon && typeof expected[member] === "number") { + assert_approx_equals(actual[member], expected[member], epsilon, member); + } else { + assert_equals(actual[member], expected[member], member); + } + } +} + +// checkMatrix and checkDOMMatrix should probably be merged... +function checkDOMMatrix(m, exp, is2D) { + if (is2D === undefined) { + is2D = exp.is2D; + } + assert_equals(m.m11, exp.m11, "Expected value for m11 is " + exp.m11); + assert_equals(m.m12, exp.m12, "Expected value for m12 is " + exp.m12); + assert_equals(m.m13, exp.m13, "Expected value for m13 is " + exp.m13); + assert_equals(m.m14, exp.m14, "Expected value for m14 is " + exp.m14); + assert_equals(m.m21, exp.m21, "Expected value for m21 is " + exp.m21); + assert_equals(m.m22, exp.m22, "Expected value for m22 is " + exp.m22); + assert_equals(m.m23, exp.m23, "Expected value for m23 is " + exp.m23); + assert_equals(m.m24, exp.m24, "Expected value for m24 is " + exp.m24); + assert_equals(m.m31, exp.m31, "Expected value for m31 is " + exp.m31); + assert_equals(m.m32, exp.m32, "Expected value for m32 is " + exp.m32); + assert_equals(m.m33, exp.m33, "Expected value for m33 is " + exp.m33); + assert_equals(m.m34, exp.m34, "Expected value for m34 is " + exp.m34); + assert_equals(m.m41, exp.m41, "Expected value for m41 is " + exp.m41); + assert_equals(m.m42, exp.m42, "Expected value for m42 is " + exp.m42); + assert_equals(m.m43, exp.m43, "Expected value for m43 is " + exp.m43); + assert_equals(m.m44, exp.m44, "Expected value for m44 is " + exp.m44); + assert_equals(m.is2D, is2D, "Expected value for is2D is " + is2D); + assert_equals(m.isIdentity, exp.isIdentity, "Expected value for isIdentity is " + exp.isIdentity); +} + + +function identity() { + return new DOMMatrix( + [1, 0, 0, 0, + 0, 1, 0 ,0, + 0, 0, 1, 0, + 0, 0, 0, 1]); +} + +function update(matrix, f) { + f(matrix); + return matrix; +} |