Skip to content

Commit

Permalink
Test outside of IDL conversions for CanvasFilter
Browse files Browse the repository at this point in the history
From the discussion here (whatwg/html#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 <[email protected]>
Reviewed-by: Domenic Denicola <[email protected]>
Commit-Queue: Aaron Krajeski <[email protected]>
Cr-Commit-Position: refs/heads/main@{#951163}
NOKEYCHECK=True
GitOrigin-RevId: ba6cbce4987586600aa98a2b2289c55faa2cdfc3
  • Loading branch information
mysteryDate authored and copybara-github committed Dec 13, 2021
1 parent ba23a01 commit 3ea1c36
Show file tree
Hide file tree
Showing 11 changed files with 233 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,13 @@ ComponentTransferFunction GetComponentTransferFunction(
const StringView& key,
const Dictionary& filter,
ExceptionState& exception_state) {
ComponentTransferFunction result;
// An earlier stage threw an error
if (exception_state.HadException())
return result;
Dictionary transfer_dict;
filter.Get(key, transfer_dict);

ComponentTransferFunction result;
result.slope =
transfer_dict.Get<IDLDouble>("slope", exception_state).value_or(1);
result.intercept =
Expand All @@ -136,11 +139,6 @@ ComponentTransferFunction GetComponentTransferFunction(
result.offset =
transfer_dict.Get<IDLDouble>("offset", exception_state).value_or(0);

absl::optional<Vector<float>> table_values =
transfer_dict.Get<IDLSequence<IDLFloat>>("tableValues", exception_state);
if (table_values)
result.table_values.AppendVector(table_values.value());

String type = transfer_dict.Get<IDLString>("type", exception_state)
.value_or("identity");
if (type == "identity")
Expand All @@ -154,6 +152,11 @@ ComponentTransferFunction GetComponentTransferFunction(
else if (type == "discrete")
result.type = FECOMPONENTTRANSFER_TYPE_DISCRETE;

absl::optional<Vector<float>> table_values =
transfer_dict.Get<IDLSequence<IDLFloat>>("tableValues", exception_state);
if (table_values)
result.table_values.AppendVector(table_values.value());

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ <h1>2d.filter.canvasFilterObject.blur.exceptions</h1>
_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: {}}); });


});
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ <h1>2d.filter.canvasFilterObject.blur.exceptions</h1>
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();

});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ var offscreenCanvas = new OffscreenCanvas(100, 50);
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();

});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 3ea1c36

Please sign in to comment.