Test outside of IDL conversions for CanvasFilter
From the discussion here (https://github.com/whatwg/html/pull/6763) we
need to explicitly test all possible types of inputs for filter
attributes.
Bug: 1201359
Change-Id: I5ef5905298a17310e4eb54c3c01ab8d6b7973737
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3320960
Reviewed-by: Yi Xu <yiyix@chromium.org>
Reviewed-by: Domenic Denicola <domenic@chromium.org>
Commit-Queue: Aaron Krajeski <aaronhk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#951163}
diff --git a/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.html b/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.html
index 22dac93..e0c9393 100644
--- a/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.html
+++ b/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.html
@@ -20,8 +20,11 @@
_addTest(function(canvas, ctx) {
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur"}); });
-assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined}); });
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}}); });
});
diff --git a/html/canvas/element/manual/filters/idl-conversions/canvas-filter-boolean-conversion-expected.html b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-boolean-conversion-expected.html
new file mode 100644
index 0000000..f79cdd1
--- /dev/null
+++ b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-boolean-conversion-expected.html
@@ -0,0 +1,30 @@
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // preserveAlpha for convolveMatrix is the only boolean so far implemented
+ function drawWithConvolveFilter(x, y, preserveAlphaValue) {
+ ctx.filter = new CanvasFilter({
+ filter: "convolveMatrix",
+ kernelMatrix: [[1, 0], [0, 1]],
+ preserveAlpha: preserveAlphaValue,
+ });
+ ctx.fillRect(x, y, 30, 30);
+ }
+
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ let x = 10;
+ let y = 10;
+ for (var i = 0; i < 6; i++) {
+ drawWithConvolveFilter(x, y, true);
+ x += 40;
+ }
+ y = 50;
+ x = 10;
+ for (var i = 0; i < 5; i++) {
+ drawWithConvolveFilter(x, y, false);
+ x += 40;
+ }
+</script>
diff --git a/html/canvas/element/manual/filters/idl-conversions/canvas-filter-boolean-conversion.html b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-boolean-conversion.html
new file mode 100644
index 0000000..16c40e4
--- /dev/null
+++ b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-boolean-conversion.html
@@ -0,0 +1,58 @@
+<head>
+ <link rel="match" href="canvas-filter-boolean-conversion-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ // Test the built-in ECMAScript types Undefined, Null, Boolean, String, Number, and Object
+ // as input to the CanvasFilter resolver when a bool is the intended result.
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // preserveAlpha for convolveMatrix is the only boolean so far implemented
+ function drawWithConvolveFilter(x, y, preserveAlphaValue) {
+ ctx.filter = new CanvasFilter({
+ filter: "convolveMatrix",
+ kernelMatrix: [[1, 0], [0, 1]],
+ preserveAlpha: preserveAlphaValue,
+ });
+ ctx.fillRect(x, y, 30, 30);
+ }
+
+ const trueTestCases = [
+ true,
+ { valueOf() { return false; }},
+ "foo",
+ 1,
+ {},
+ []
+ ];
+
+ const falseTestCases = [
+ false,
+ "",
+ 0,
+ null,
+ undefined,
+ ];
+
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ let x = 10;
+ let y = 10;
+ for (tc of trueTestCases) {
+ drawWithConvolveFilter(x, y, tc);
+ x += 40;
+ }
+ y = 50;
+ x = 10;
+ for (tc of falseTestCases) {
+ drawWithConvolveFilter(x, y, tc);
+ x += 40;
+ }
+
+ ctx.filter = new CanvasFilter({
+ filter: "componentTransfer",
+ funcR: {type: "discrete", tableValues: 0.5},
+ });
+ ctx.fillRect(10, 10, 100, 100);
+</script>
diff --git a/html/canvas/element/manual/filters/idl-conversions/canvas-filter-long-conversion-expected.html b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-long-conversion-expected.html
new file mode 100644
index 0000000..8b4262e
--- /dev/null
+++ b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-long-conversion-expected.html
@@ -0,0 +1,26 @@
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var ctx = document.getElementById('canvas').getContext('2d');
+ // Null and False both evaluate to zero
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
+ ctx.fillRect(10, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
+ ctx.fillRect(50, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
+ ctx.fillRect(90, 10, 30, 30);
+ // True evaluates to one
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 1});
+ ctx.fillRect(130, 10, 30, 30);
+ // String, Number and Object should all work
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(10, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(50, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(90, 50, 30, 30);
+ // Valid sequence
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(130, 50, 30, 30);
+</script>
diff --git a/html/canvas/element/manual/filters/idl-conversions/canvas-filter-long-conversion.html b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-long-conversion.html
new file mode 100644
index 0000000..c742633
--- /dev/null
+++ b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-long-conversion.html
@@ -0,0 +1,35 @@
+<head>
+ <link rel="match" href="canvas-filter-long-conversion-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ // Test the built-in ECMAScript types Undefined, Null, Boolean, String, Number, and Object
+ // as input to the CanvasFilter resolver when a long is the intended result.
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // Null, False and [] evaluate to zero
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: null});
+ ctx.fillRect(10, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: false});
+ ctx.fillRect(50, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: []});
+ ctx.fillRect(90, 10, 30, 30);
+ // True evaluates to one
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: true});
+ ctx.fillRect(130, 10, 30, 30);
+ // String, Number and Object should all work
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "5"});
+ ctx.fillRect(10, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(50, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: { valueOf() { return 5; }}});
+ ctx.fillRect(90, 50, 30, 30);
+ // Valid sequence
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [5]});
+ ctx.fillRect(130, 50, 30, 30);
+
+ // Undefined and other inputs that throw exceptions are tested in:
+ // html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.html
+</script>
diff --git a/html/canvas/element/manual/filters/idl-conversions/canvas-filter-sequence-conversion.html b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-sequence-conversion.html
new file mode 100644
index 0000000..7774f3a
--- /dev/null
+++ b/html/canvas/element/manual/filters/idl-conversions/canvas-filter-sequence-conversion.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>Canvas test: canvas-filter-sequence-conversion</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>canvas-filter-sequence-conversion</h1>
+<p class="desc">Test converting types into sequences</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test pixels on CanvasFilter() various inputs to tableValues (which is a sequence)");
+_addTest(function(canvas, ctx) {
+
+ // Inputs to parameters that are expecting sequence<long>. Results are either the value of the
+ // red pixel drawing using the resultant filter or that we expect this input to throw an error.
+ const testCases = [
+ {input: [], result: 0},
+ {input: [0.5], result: 127},
+ {input: ["0.5"], result: 127},
+ {input: 1, result: "throws"},
+ {input: {}, result: "throws"},
+ {input: false, result: "throws"},
+ {input: true, result: "throws"},
+ {input: NaN, result: "throws"},
+ {input: { valueOf() { return [1]; }}, result: "throws"},
+ ];
+
+ // A simple filter that just overrides the red channel if successful.
+ function makeFilter(value) {
+ return new CanvasFilter({
+ filter: "componentTransfer",
+ funcR: {type: "table", tableValues: value}
+ });
+ }
+
+ for (const tc of testCases) {
+ if (tc.result === "throws") {
+ assert_throws_js(TypeError, function(){ makeFilter(tc.input) });
+ } else {
+ ctx.reset();
+ ctx.filter = makeFilter(tc.input);
+ ctx.fillRect(0, 0, 100, 100);
+ _assertPixelApprox(canvas, 5, 5, tc.result,0,0,255, "5,5", `${tc.result},0,0,255`, 2);
+ }
+ }
+ t.done();
+});
+</script>
diff --git a/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.html b/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.html
index c047903..d3a03dc 100644
--- a/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.html
+++ b/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.html
@@ -21,8 +21,11 @@
var ctx = offscreenCanvas.getContext('2d');
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur"}); });
-assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined}); });
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}}); });
t.done();
});
diff --git a/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.worker.js b/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.worker.js
index 1f44c00..29f743d 100644
--- a/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.worker.js
+++ b/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.worker.js
@@ -17,8 +17,11 @@
var ctx = offscreenCanvas.getContext('2d');
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur"}); });
-assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined}); });
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN}); });
+assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}}); });
t.done();
});
diff --git a/html/canvas/tools/yaml/element/filters.yaml b/html/canvas/tools/yaml/element/filters.yaml
index 420af37..57cbebc 100644
--- a/html/canvas/tools/yaml/element/filters.yaml
+++ b/html/canvas/tools/yaml/element/filters.yaml
@@ -61,8 +61,11 @@
desc: Test exceptions on CanvasFilter() blur.object
code: |
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur"});
- @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined});
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}});
- name: 2d.filter.canvasFilterObject.colorMatrix
desc: Test the functionality of ColorMatrix filters in CanvasFilter objects
diff --git a/html/canvas/tools/yaml/offscreen/filters.yaml b/html/canvas/tools/yaml/offscreen/filters.yaml
index e715c95..f9cf1cb 100644
--- a/html/canvas/tools/yaml/offscreen/filters.yaml
+++ b/html/canvas/tools/yaml/offscreen/filters.yaml
@@ -28,8 +28,11 @@
desc: Test exceptions on CanvasFilter() blur.object
code: |
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur"});
- @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined});
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN});
+ @assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}});
t.done();
- name: 2d.filter.canvasFilterObject.colorMatrix