Refactor canvas item unit tests
authorCharles Yin <charles.yin@nokia.com>
Thu, 3 May 2012 05:21:08 +0000 (15:21 +1000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 4 May 2012 00:39:23 +0000 (02:39 +0200)
Change-Id: I99ba84889ce360d2def27834f15af43c2bdf29bc
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
21 files changed:
tests/auto/quick/qquickcanvasitem/data/CanvasComponent.qml [new file with mode: 0644]
tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml [new file with mode: 0644]
tests/auto/quick/qquickcanvasitem/data/testhelper.js [deleted file]
tests/auto/quick/qquickcanvasitem/data/tst_arc.qml
tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml
tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
tests/auto/quick/qquickcanvasitem/data/tst_composite.qml
tests/auto/quick/qquickcanvasitem/data/tst_drawimage.qml [deleted file]
tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml
tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml
tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml
tests/auto/quick/qquickcanvasitem/data/tst_image.qml [new file with mode: 0644]
tests/auto/quick/qquickcanvasitem/data/tst_line.qml
tests/auto/quick/qquickcanvasitem/data/tst_path.qml
tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml
tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml
tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml
tests/auto/quick/qquickcanvasitem/data/tst_state.qml
tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml
tests/auto/quick/qquickcanvasitem/data/tst_text.qml
tests/auto/quick/qquickcanvasitem/data/tst_transform.qml

diff --git a/tests/auto/quick/qquickcanvasitem/data/CanvasComponent.qml b/tests/auto/quick/qquickcanvasitem/data/CanvasComponent.qml
new file mode 100644 (file)
index 0000000..12c1c89
--- /dev/null
@@ -0,0 +1,31 @@
+import QtQuick 2.0
+import QtTest 1.0
+
+Component {
+        id:canvas
+        Canvas {
+            id:c
+             width:100;height:100
+             smooth:false //this line is needed for some tests (smooth painting can change the colors and alpha channel values)
+             onPaint :{} //this line is needed for some tests (make sure onPaint handler always called
+             property alias paintCount:spyPaint.count
+             property alias paintedCount:spyPainted.count
+             property alias canvasSizeChangedCount:spyCanvasSizeChanged.count
+             property alias tileSizeChangedCount:spyTileSizeChanged.count
+             property alias renderStrategyChangedCount:spyRenderStrategyChanged.count
+             property alias canvasWindowChangedCount:spyCanvasWindowChanged.count
+             property alias renderTargetChangedCount:spyRenderTargetChanged.count
+             property alias imageLoadedCount:spyImageLoaded.count
+             property alias availableChangedCount:spyAvailableChanged.count
+
+             SignalSpy {id: spyPaint;target:c;signalName: "paint"}
+             SignalSpy {id: spyPainted;target:c;signalName: "painted"}
+             SignalSpy {id: spyCanvasSizeChanged;target:c;signalName: "canvasSizeChanged"}
+             SignalSpy {id: spyTileSizeChanged;target:c;signalName: "tileSizeChanged"}
+             SignalSpy {id: spyRenderStrategyChanged;target:c;signalName: "renderStrategyChanged"}
+             SignalSpy {id: spyCanvasWindowChanged;target:c;signalName: "canvasWindowChanged"}
+             SignalSpy {id: spyRenderTargetChanged;target:c;signalName: "renderTargetChanged"}
+             SignalSpy {id: spyImageLoaded;target:c;signalName: "imageLoaded"}
+             SignalSpy {id: spyAvailableChanged;target:c;signalName: "availableChanged"}
+        }
+}
\ No newline at end of file
diff --git a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
new file mode 100644 (file)
index 0000000..4aae317
--- /dev/null
@@ -0,0 +1,46 @@
+import QtQuick 2.0
+import QtTest 1.0
+
+TestCase {
+  id:testCase
+  when:windowShown
+  width:100
+  height:100
+  property Component component:CanvasComponent{}
+  function cleanupTestCase() {
+    wait(100) //wait for a short while to make sure no leaked textures
+  }
+  function testData(type) {
+    if (type === "2d")
+      return [
+             { tag:"image threaded", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Threaded}}
+             //TODO: Enable the followings later
+             //{ tag:"image cooperative", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Cooperative}},
+             //{ tag:"image immediate", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Immediate}},
+             //{ tag:"fbo cooperative", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Cooperative}},
+             //{ tag:"fbo immediate", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Immediate}},
+             //{ tag:"fbo threaded", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Threaded}}
+           ];
+     return [];
+  }
+
+  function createCanvasObject(data) {
+    return component.createObject(testCase, data.properties);
+  }
+
+  function comparePixel(ctx,x,y,r,g,b,a, d)
+  {
+    var c = ctx.getImageData(x,y,1,1).data;
+    if (d === undefined)
+      d = 0;
+    r = Math.round(r);
+    g = Math.round(g);
+    b = Math.round(b);
+    a = Math.round(a);
+
+    var notSame = Math.abs(c[0]-r)>d || Math.abs(c[1]-g)>d || Math.abs(c[2]-b)>d || Math.abs(c[3]-a)>d;
+    if (notSame)
+      qtest_fail('Pixel compare fail:\nactual  :[' + c[0]+','+c[1]+','+c[2]+','+c[3] + ']\nexpected:['+r+','+g+','+b+','+a+'] +/- '+d, 1);
+  }
+
+}
\ No newline at end of file
diff --git a/tests/auto/quick/qquickcanvasitem/data/testhelper.js b/tests/auto/quick/qquickcanvasitem/data/testhelper.js
deleted file mode 100644 (file)
index bac0210..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-function comparePixel(ctx,x,y,r,g,b,a, d)
-{
-   var c = ctx.getImageData(x,y,1,1).data;
-   if (d === undefined)
-      d = 0;
-   r = Math.round(r);
-   g = Math.round(g);
-   b = Math.round(b);
-   a = Math.round(a);
-
-   if (Math.abs(c[0]-r)>d || Math.abs(c[1]-g)>d || Math.abs(c[2]-b)>d || Math.abs(c[3]-a)>d) {
-      console.log('Pixel compare fail:\nactual  :[' + c[0]+','+c[1]+','+c[2]+','+c[3] + ']\nexpected:['+r+','+g+','+b+','+a+'] +/- '+d);
-      return false;
-   }
-   return true;
-}
-
-
index 10bc37e..33fffd4 100644 (file)
@@ -1,13 +1,11 @@
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   smooth: false
-   TestCase {
-       name: "arc"; when: windowShown
-       function test_angle_1() {
+
+CanvasTestCase {
+   id:testCase
+   name: "arc"
+   function init_data() { return testData("2d"); }
+       function test_angle_1(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -18,9 +16,11 @@ Canvas {
            ctx.moveTo(100, 0);
            ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true);
            ctx.fill();
-           verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+           comparePixel(ctx,50,25, 0,255,0,255);
+           canvas.destroy();
         }
-       function test_angle_2() {
+       function test_angle_2(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -31,9 +31,11 @@ Canvas {
            ctx.moveTo(100, 0);
            ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true);
            ctx.fill();
-           verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+           comparePixel(ctx,50,25, 0,255,0,255);
+           canvas.destroy();
         }
-       function test_angle_3() {
+       function test_angle_3(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -45,10 +47,12 @@ Canvas {
            ctx.fill();
            /*FIXME: from: http://www.w3.org/TR/2dcontext/#dom-context-2d-arc
            If the anticlockwise argument is omitted or false and endAngle-startAngle is equal to or greater than 2π, or, if the anticlockwise argument is true and startAngle-endAngle is equal to or greater than 2π, then the arc is the whole circumference of this circle.
-           //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+           //comparePixel(ctx,50,25, 0,255,0,255);
            */
+           canvas.destroy();
         }
-       function test_angle_4() {
+       function test_angle_4(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -59,12 +63,14 @@ Canvas {
            ctx.moveTo(50, 25);
            ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false);
            ctx.fill();
-           verify(Helper.comparePixel(ctx,1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,98,48, 0,255,0,255));
+           comparePixel(ctx,1,1, 0,255,0,255);
+           comparePixel(ctx,98,1, 0,255,0,255);
+           comparePixel(ctx,1,48, 0,255,0,255);
+           comparePixel(ctx,98,48, 0,255,0,255);
+           canvas.destroy();
         }
-       function test_angle_5() {
+       function test_angle_5(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -77,11 +83,13 @@ Canvas {
            ctx.fill();
            /*FIXME: from: http://www.w3.org/TR/2dcontext/#dom-context-2d-arc
            If the anticlockwise argument is omitted or false and endAngle-startAngle is equal to or greater than 2π, or, if the anticlockwise argument is true and startAngle-endAngle is equal to or greater than 2π, then the arc is the whole circumference of this circle.
-           //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+           //comparePixel(ctx,50,25, 0,255,0,255);
            */
+           canvas.destroy();
         }
 
-       function test_angle_6() {
+       function test_angle_6(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -93,13 +101,15 @@ Canvas {
            ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true);
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx,1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,98,48, 0,255,0,255));
+           comparePixel(ctx,1,1, 0,255,0,255);
+           comparePixel(ctx,98,1, 0,255,0,255);
+           comparePixel(ctx,1,48, 0,255,0,255);
+           comparePixel(ctx,98,48, 0,255,0,255);
+           canvas.destroy();
         }
 
-       function test_empty() {
+       function test_empty(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -110,9 +120,11 @@ Canvas {
            ctx.beginPath();
            ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+           comparePixel(ctx,50,25, 0,255,0,255);
+           canvas.destroy();
         }
-       function test_nonempty() {
+       function test_nonempty(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -124,9 +136,11 @@ Canvas {
            ctx.moveTo(0, 25);
            ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+           comparePixel(ctx,50,25, 0,255,0,255);
+           canvas.destroy();
         }
-       function test_nonfinite() {
+       function test_nonfinite(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -179,10 +193,12 @@ Canvas {
            ctx.lineTo(0, 50);
            ctx.fillStyle = '#0f0';
            ctx.fill();
-           verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,90,45, 0,255,0,255));
+           comparePixel(ctx,50,25, 0,255,0,255);
+           comparePixel(ctx,90,45, 0,255,0,255);
+           canvas.destroy();
        }
-       function test_end() {
+       function test_end(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -195,9 +211,11 @@ Canvas {
            ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true);
            ctx.lineTo(100, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+           comparePixel(ctx,50,25, 0,255,0,255);
+           canvas.destroy();
         }
-       function test_negative() {
+       function test_negative(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -211,9 +229,11 @@ Canvas {
                verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.arc(0, 0, -1, 0, 0, true)");
            }
 
+           canvas.destroy();
        }
 
-       function test_scale_1() {
+       function test_scale_1(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -236,18 +256,20 @@ Canvas {
            ctx.arc(25, 125, 24, 0, 2*Math.PI, false);
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+           comparePixel(ctx, 0,0, 0,255,0,255);
+           comparePixel(ctx, 50,0, 0,255,0,255);
+           comparePixel(ctx, 99,0, 0,255,0,255);
+           comparePixel(ctx, 0,25, 0,255,0,255);
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 99,25, 0,255,0,255);
+           comparePixel(ctx, 0,49, 0,255,0,255);
+           comparePixel(ctx, 50,49, 0,255,0,255);
+           comparePixel(ctx, 99,49, 0,255,0,255);
+           canvas.destroy();
        }
 
-       function test_scale_2() {
+       function test_scale_2(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -260,18 +282,20 @@ Canvas {
            ctx.arc(0, 0, 0.6, 0, Math.PI/2, false);
            ctx.stroke();
 
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 50,1, 0,255,0,255);
+           comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,25, 0,255,0,255);
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 98,25, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 50,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
+           canvas.destroy();
        }
 
-       function test_selfintersect_1() {
+       function test_selfintersect_1(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -285,11 +309,13 @@ Canvas {
            ctx.beginPath();
            ctx.arc(0, 0, 25, 0, -Math.PI/2, true);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy();
        }
 
-       function test_selfintersect_2() {
+       function test_selfintersect_2(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -303,15 +329,17 @@ Canvas {
            ctx.beginPath();
            ctx.arc(100, 0, 25, 0, -Math.PI/2, true);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 97,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 97,2, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 97,3, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 2,48, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 90,10, 0,255,0,255);
+           comparePixel(ctx, 97,1, 0,255,0,255);
+           comparePixel(ctx, 97,2, 0,255,0,255);
+           comparePixel(ctx, 97,3, 0,255,0,255);
+           comparePixel(ctx, 2,48, 0,255,0,255);
+           canvas.destroy();
        }
 
-       function test_shape_1() {
+       function test_shape_1(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -322,15 +350,17 @@ Canvas {
            ctx.beginPath();
            ctx.arc(50, 50, 50, 0, Math.PI, false);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 20,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 20,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
+           canvas.destroy();
        }
 
-       function test_shape_2() {
+       function test_shape_2(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -341,14 +371,16 @@ Canvas {
            ctx.beginPath();
            ctx.arc(50, 50, 50, 0, Math.PI, true);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 20,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 20,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
+           canvas.destroy();
        }
-       function test_shape_3() {
+       function test_shape_3(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -359,14 +391,16 @@ Canvas {
            ctx.beginPath();
            ctx.arc(0, 50, 50, 0, -Math.PI/2, false);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
+           canvas.destroy();
        }
 
-       function test_shape_4() {
+       function test_shape_4(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -377,14 +411,16 @@ Canvas {
            ctx.beginPath();
            ctx.arc(-50, 50, 100, 0, -Math.PI/2, true);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
+           canvas.destroy();
        }
 
-       function test_shape_5() {
+       function test_shape_5(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -395,14 +431,16 @@ Canvas {
            ctx.beginPath();
            ctx.arc(300, 0, 100, 0, 5*Math.PI, false);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
+           canvas.destroy();
        }
 
-       function test_twopie() {
+       function test_twopie(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -413,7 +451,7 @@ Canvas {
            ctx.beginPath();
            ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+           comparePixel(ctx, 50,20, 0,255,0,255);
            ctx.reset();
 
            ctx.fillStyle = '#f00';
@@ -423,7 +461,7 @@ Canvas {
            ctx.beginPath();
            ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+           comparePixel(ctx, 50,20, 0,255,0,255);
            ctx.reset();
 
            ctx.fillStyle = '#f00';
@@ -434,7 +472,7 @@ Canvas {
            ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true);
            ctx.stroke();
            //FIXME:still different behavior from browsers, > 2pi span issue
-           //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+           //comparePixel(ctx, 50,20, 0,255,0,255);
            ctx.reset();
 
            ctx.fillStyle = '#f00';
@@ -444,10 +482,12 @@ Canvas {
            ctx.beginPath();
            ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+           comparePixel(ctx, 50,20, 0,255,0,255);
+           canvas.destroy();
        }
 
-       function test_zero() {
+       function test_zero(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -458,7 +498,7 @@ Canvas {
            ctx.beginPath();
            ctx.arc(50, 25, 50, 0, 0, true);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+           comparePixel(ctx, 50,20, 0,255,0,255);
            ctx.reset();
 
            ctx.fillStyle = '#0f0';
@@ -468,7 +508,7 @@ Canvas {
            ctx.beginPath();
            ctx.arc(50, 25, 50, 0, 0, false);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+           comparePixel(ctx, 50,20, 0,255,0,255);
            ctx.reset();
 
            ctx.fillStyle = '#f00'
@@ -479,8 +519,7 @@ Canvas {
            ctx.moveTo(0, 25);
            ctx.arc(200, 25, 0, 0, Math.PI, true);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy();
        }
-   }
-}
+}
\ No newline at end of file
index 188d538..d901715 100644 (file)
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   smooth: false
-   TestCase {
-       name: "arcTo"; when: windowShown
-       function test_coincide() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.lineWidth = 50;
-
-           ctx.strokeStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(0, 25);
-           ctx.arcTo(0, 25, 50, 1000, 1);
-           ctx.lineTo(100, 25);
-           ctx.stroke();
-
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(50, 25);
-           ctx.arcTo(50, 25, 100, 25, 1);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.lineWidth = 50;
-           ctx.strokeStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(0, 25);
-           ctx.arcTo(100, 25, 100, 25, 1);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-       }
-       function test_collinear() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.lineWidth = 50;
-
-           ctx.strokeStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(0, 25);
-           ctx.arcTo(100, 25, 200, 25, 1);
-           ctx.stroke();
-
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(-100, 25);
-           ctx.arcTo(0, 25, 100, 25, 1);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.lineWidth = 50;
-
-           ctx.strokeStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(0, 25);
-           ctx.arcTo(100, 25, 10, 25, 1);
-           ctx.stroke();
-
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(100, 25);
-           ctx.arcTo(200, 25, 110, 25, 1);
-           ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.lineWidth = 50;
-
-           ctx.strokeStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(0, 25);
-           ctx.arcTo(100, 25, -100, 25, 1);
-           ctx.stroke();
-
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(100, 25);
-           ctx.arcTo(200, 25, 0, 25, 1);
-           ctx.stroke();
-
-           ctx.beginPath();
-           ctx.moveTo(-100, 25);
-           ctx.arcTo(0, 25, -200, 25, 1);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-       }
-       function test_subpath() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.lineWidth = 50;
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.arcTo(100, 50, 200, 50, 0.1);
-           ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.lineWidth = 50;
-           ctx.strokeStyle = '#0f0';
-           ctx.beginPath();
-           ctx.arcTo(0, 25, 50, 250, 0.1);
-           ctx.lineTo(100, 25);
-           ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-       }
 
-       function test_negative() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           try { var err = false;
-             ctx.arcTo(0, 0, 0, 0, -1);
-           } catch (e) {
-               if (e.code != DOMException.INDEX_SIZE_ERR)
-                   fail("expectes INDEX_SIZE_ERR, got: "+e.message);
-               err = true;
-           }
-           finally {
-               verify(err, "should throw INDEX_SIZE_ERR: ctx.arcTo(0, 0, 0, 0, -1)");
-           }
-       }
-
-       function test_nonfinite() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.moveTo(0, 0);
-           ctx.lineTo(100, 0);
-           ctx.arcTo(Infinity, 50, 0, 50, 0);
-           ctx.arcTo(-Infinity, 50, 0, 50, 0);
-           ctx.arcTo(NaN, 50, 0, 50, 0);
-           ctx.arcTo(0, Infinity, 0, 50, 0);
-           ctx.arcTo(0, -Infinity, 0, 50, 0);
-           ctx.arcTo(0, NaN, 0, 50, 0);
-           ctx.arcTo(0, 50, Infinity, 50, 0);
-           ctx.arcTo(0, 50, -Infinity, 50, 0);
-           ctx.arcTo(0, 50, NaN, 50, 0);
-           ctx.arcTo(0, 50, 0, Infinity, 0);
-           ctx.arcTo(0, 50, 0, -Infinity, 0);
-           ctx.arcTo(0, 50, 0, NaN, 0);
-           ctx.arcTo(0, 50, 0, 50, Infinity);
-           ctx.arcTo(0, 50, 0, 50, -Infinity);
-           ctx.arcTo(0, 50, 0, 50, NaN);
-           ctx.arcTo(Infinity, Infinity, 0, 50, 0);
-           ctx.arcTo(Infinity, Infinity, Infinity, 50, 0);
-           ctx.arcTo(Infinity, Infinity, Infinity, Infinity, 0);
-           ctx.arcTo(Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.arcTo(Infinity, Infinity, Infinity, 50, Infinity);
-           ctx.arcTo(Infinity, Infinity, 0, Infinity, 0);
-           ctx.arcTo(Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.arcTo(Infinity, Infinity, 0, 50, Infinity);
-           ctx.arcTo(Infinity, 50, Infinity, 50, 0);
-           ctx.arcTo(Infinity, 50, Infinity, Infinity, 0);
-           ctx.arcTo(Infinity, 50, Infinity, Infinity, Infinity);
-           ctx.arcTo(Infinity, 50, Infinity, 50, Infinity);
-           ctx.arcTo(Infinity, 50, 0, Infinity, 0);
-           ctx.arcTo(Infinity, 50, 0, Infinity, Infinity);
-           ctx.arcTo(Infinity, 50, 0, 50, Infinity);
-           ctx.arcTo(0, Infinity, Infinity, 50, 0);
-           ctx.arcTo(0, Infinity, Infinity, Infinity, 0);
-           ctx.arcTo(0, Infinity, Infinity, Infinity, Infinity);
-           ctx.arcTo(0, Infinity, Infinity, 50, Infinity);
-           ctx.arcTo(0, Infinity, 0, Infinity, 0);
-           ctx.arcTo(0, Infinity, 0, Infinity, Infinity);
-           ctx.arcTo(0, Infinity, 0, 50, Infinity);
-           ctx.arcTo(0, 50, Infinity, Infinity, 0);
-           ctx.arcTo(0, 50, Infinity, Infinity, Infinity);
-           ctx.arcTo(0, 50, Infinity, 50, Infinity);
-           ctx.arcTo(0, 50, 0, Infinity, Infinity);
-           ctx.lineTo(100, 50);
-           ctx.lineTo(0, 50);
-           ctx.fillStyle = '#0f0';
-           ctx.fill();
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  90,45, 0,255,0,255));
+CanvasTestCase {
+    id:testCase
+    name: "arcTo"
+    function init_data() { return testData("2d"); }
+
+   function test_coincide(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.lineWidth = 50;
+
+       ctx.strokeStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(0, 25);
+       ctx.arcTo(0, 25, 50, 1000, 1);
+       ctx.lineTo(100, 25);
+       ctx.stroke();
+
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(50, 25);
+       ctx.arcTo(50, 25, 100, 25, 1);
+       ctx.stroke();
+
+       comparePixel(ctx, 50,1, 0,255,0,255);
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       comparePixel(ctx, 50,48, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.lineWidth = 50;
+       ctx.strokeStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(0, 25);
+       ctx.arcTo(100, 25, 100, 25, 1);
+       ctx.stroke();
+
+       comparePixel(ctx, 50,25, 0,255,0,255);
+   }
+   function test_collinear(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.lineWidth = 50;
+
+       ctx.strokeStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(0, 25);
+       ctx.arcTo(100, 25, 200, 25, 1);
+       ctx.stroke();
+
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(-100, 25);
+       ctx.arcTo(0, 25, 100, 25, 1);
+       ctx.stroke();
+
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.lineWidth = 50;
+
+       ctx.strokeStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(0, 25);
+       ctx.arcTo(100, 25, 10, 25, 1);
+       ctx.stroke();
+
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(100, 25);
+       ctx.arcTo(200, 25, 110, 25, 1);
+       ctx.stroke();
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.lineWidth = 50;
+
+       ctx.strokeStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(0, 25);
+       ctx.arcTo(100, 25, -100, 25, 1);
+       ctx.stroke();
+
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(100, 25);
+       ctx.arcTo(200, 25, 0, 25, 1);
+       ctx.stroke();
+
+       ctx.beginPath();
+       ctx.moveTo(-100, 25);
+       ctx.arcTo(0, 25, -200, 25, 1);
+       ctx.stroke();
+
+       comparePixel(ctx, 50,25, 0,255,0,255);
+   }
+   function test_subpath(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.lineWidth = 50;
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.arcTo(100, 50, 200, 50, 0.1);
+       ctx.stroke();
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.lineWidth = 50;
+       ctx.strokeStyle = '#0f0';
+       ctx.beginPath();
+       ctx.arcTo(0, 25, 50, 250, 0.1);
+       ctx.lineTo(100, 25);
+       ctx.stroke();
+       comparePixel(ctx, 50,25, 0,255,0,255);
+   }
 
+   function test_negative(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       try { var err = false;
+         ctx.arcTo(0, 0, 0, 0, -1);
+       } catch (e) {
+           if (e.code != DOMException.INDEX_SIZE_ERR)
+               fail("expectes INDEX_SIZE_ERR, got: "+e.message);
+           err = true;
        }
-       function test_scale() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.fillStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(0, 50);
-           ctx.translate(100, 0);
-           ctx.scale(0.1, 1);
-           ctx.arcTo(50, 50, 50, 0, 50);
-           ctx.lineTo(-1000, 0);
-           ctx.fill();
-
-           //FIXME
-           //verify(Helper.comparePixel(ctx,  0,0, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  50,0, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  99,0, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  0,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  99,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  0,49, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  50,49, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  99,49, 0,255,0,255));
+       finally {
+           verify(err, "should throw INDEX_SIZE_ERR: ctx.arcTo(0, 0, 0, 0, -1)");
        }
+   }
 
-       function test_shape() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           var tol = 1.5; // tolerance to avoid antialiasing artifacts
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.strokeStyle = '#f00';
-           ctx.lineWidth = 10;
-           ctx.beginPath();
-           ctx.moveTo(10, 25);
-           ctx.arcTo(75, 25, 75, 60, 20);
-           ctx.stroke();
-
-           ctx.fillStyle = '#0f0';
-           ctx.beginPath();
-           ctx.rect(10, 20, 45, 10);
-           ctx.moveTo(80, 45);
-           ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true);
-           ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false);
-           ctx.fill();
-
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  55,19, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  55,20, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  55,21, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  64,22, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  65,21, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  72,28, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  73,27, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  78,36, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  79,35, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  80,44, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  80,45, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  80,46, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  65,45, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.fillStyle = '#f00';
-           ctx.beginPath();
-           ctx.rect(10, 20, 45, 10);
-           ctx.moveTo(80, 45);
-           ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true);
-           ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false);
-           ctx.fill();
-
-           ctx.strokeStyle = '#0f0';
-           ctx.lineWidth = 10;
-           ctx.beginPath();
-           ctx.moveTo(10, 25);
-           ctx.arcTo(75, 25, 75, 60, 20);
-           ctx.stroke();
-
-           //verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  55,19, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  55,20, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  55,21, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  64,22, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  65,21, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  72,28, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  73,27, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  78,36, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  79,35, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  80,44, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  80,45, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  80,46, 0,255,0,255));
-           ctx.reset();
-
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.strokeStyle = '#f00';
-           ctx.lineWidth = 50;
-           ctx.beginPath();
-           ctx.moveTo(-100, -100);
-           ctx.arcTo(-100, 25, 200, 25, 10);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx,  1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  98,48, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.strokeStyle = '#0f0';
-           ctx.lineWidth = 50;
-           ctx.beginPath();
-           ctx.moveTo(0, 25);
-           ctx.arcTo(200, 25, 200, 50, 10);
-           ctx.stroke();
-
-           //FIXME
-           //verify(Helper.comparePixel(ctx,  1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx,  98,48, 0,255,0,255));
-       }
+   function test_nonfinite(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.moveTo(0, 0);
+       ctx.lineTo(100, 0);
+       ctx.arcTo(Infinity, 50, 0, 50, 0);
+       ctx.arcTo(-Infinity, 50, 0, 50, 0);
+       ctx.arcTo(NaN, 50, 0, 50, 0);
+       ctx.arcTo(0, Infinity, 0, 50, 0);
+       ctx.arcTo(0, -Infinity, 0, 50, 0);
+       ctx.arcTo(0, NaN, 0, 50, 0);
+       ctx.arcTo(0, 50, Infinity, 50, 0);
+       ctx.arcTo(0, 50, -Infinity, 50, 0);
+       ctx.arcTo(0, 50, NaN, 50, 0);
+       ctx.arcTo(0, 50, 0, Infinity, 0);
+       ctx.arcTo(0, 50, 0, -Infinity, 0);
+       ctx.arcTo(0, 50, 0, NaN, 0);
+       ctx.arcTo(0, 50, 0, 50, Infinity);
+       ctx.arcTo(0, 50, 0, 50, -Infinity);
+       ctx.arcTo(0, 50, 0, 50, NaN);
+       ctx.arcTo(Infinity, Infinity, 0, 50, 0);
+       ctx.arcTo(Infinity, Infinity, Infinity, 50, 0);
+       ctx.arcTo(Infinity, Infinity, Infinity, Infinity, 0);
+       ctx.arcTo(Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.arcTo(Infinity, Infinity, Infinity, 50, Infinity);
+       ctx.arcTo(Infinity, Infinity, 0, Infinity, 0);
+       ctx.arcTo(Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.arcTo(Infinity, Infinity, 0, 50, Infinity);
+       ctx.arcTo(Infinity, 50, Infinity, 50, 0);
+       ctx.arcTo(Infinity, 50, Infinity, Infinity, 0);
+       ctx.arcTo(Infinity, 50, Infinity, Infinity, Infinity);
+       ctx.arcTo(Infinity, 50, Infinity, 50, Infinity);
+       ctx.arcTo(Infinity, 50, 0, Infinity, 0);
+       ctx.arcTo(Infinity, 50, 0, Infinity, Infinity);
+       ctx.arcTo(Infinity, 50, 0, 50, Infinity);
+       ctx.arcTo(0, Infinity, Infinity, 50, 0);
+       ctx.arcTo(0, Infinity, Infinity, Infinity, 0);
+       ctx.arcTo(0, Infinity, Infinity, Infinity, Infinity);
+       ctx.arcTo(0, Infinity, Infinity, 50, Infinity);
+       ctx.arcTo(0, Infinity, 0, Infinity, 0);
+       ctx.arcTo(0, Infinity, 0, Infinity, Infinity);
+       ctx.arcTo(0, Infinity, 0, 50, Infinity);
+       ctx.arcTo(0, 50, Infinity, Infinity, 0);
+       ctx.arcTo(0, 50, Infinity, Infinity, Infinity);
+       ctx.arcTo(0, 50, Infinity, 50, Infinity);
+       ctx.arcTo(0, 50, 0, Infinity, Infinity);
+       ctx.lineTo(100, 50);
+       ctx.lineTo(0, 50);
+       ctx.fillStyle = '#0f0';
+       ctx.fill();
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       comparePixel(ctx,  90,45, 0,255,0,255);
 
-       function test_transform() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.fillStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(0, 50);
-           ctx.translate(100, 0);
-           ctx.arcTo(50, 50, 50, 0, 50);
-           ctx.lineTo(-100, 0);
-           ctx.fill();
-
-           verify(Helper.comparePixel(ctx,  0,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  50,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  99,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  0,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  99,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  0,49, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  50,49, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  99,49, 0,255,0,255));
-        }
-       function test_zero() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.lineWidth = 50;
-
-           ctx.strokeStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(0, 25);
-           ctx.arcTo(100, 25, 100, 100, 0);
-           ctx.stroke();
-
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(0, -25);
-           ctx.arcTo(50, -25, 50, 50, 0);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.lineWidth = 50;
-
-           ctx.strokeStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(0, 25);
-           ctx.arcTo(100, 25, -100, 25, 0);
-           ctx.stroke();
-
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(100, 25);
-           ctx.arcTo(200, 25, 50, 25, 0);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
+   }
+   function test_scale(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.fillStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(0, 50);
+       ctx.translate(100, 0);
+       ctx.scale(0.1, 1);
+       ctx.arcTo(50, 50, 50, 0, 50);
+       ctx.lineTo(-1000, 0);
+       ctx.fill();
+
+       //FIXME
+       //comparePixel(ctx,  0,0, 0,255,0,255);
+       //comparePixel(ctx,  50,0, 0,255,0,255);
+       //comparePixel(ctx,  99,0, 0,255,0,255);
+       //comparePixel(ctx,  0,25, 0,255,0,255);
+       //comparePixel(ctx,  50,25, 0,255,0,255);
+       //comparePixel(ctx,  99,25, 0,255,0,255);
+       //comparePixel(ctx,  0,49, 0,255,0,255);
+       //comparePixel(ctx,  50,49, 0,255,0,255);
+       //comparePixel(ctx,  99,49, 0,255,0,255);
+   }
 
+   function test_shape(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.strokeStyle = '#f00';
+       ctx.lineWidth = 10;
+       ctx.beginPath();
+       ctx.moveTo(10, 25);
+       ctx.arcTo(75, 25, 75, 60, 20);
+       ctx.stroke();
+
+       ctx.fillStyle = '#0f0';
+       ctx.beginPath();
+       ctx.rect(10, 20, 45, 10);
+       ctx.moveTo(80, 45);
+       ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true);
+       ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false);
+       ctx.fill();
+
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       comparePixel(ctx,  55,19, 0,255,0,255);
+       comparePixel(ctx,  55,20, 0,255,0,255);
+       comparePixel(ctx,  55,21, 0,255,0,255);
+       comparePixel(ctx,  64,22, 0,255,0,255);
+       comparePixel(ctx,  65,21, 0,255,0,255);
+       comparePixel(ctx,  72,28, 0,255,0,255);
+       comparePixel(ctx,  73,27, 0,255,0,255);
+       comparePixel(ctx,  78,36, 0,255,0,255);
+       comparePixel(ctx,  79,35, 0,255,0,255);
+       comparePixel(ctx,  80,44, 0,255,0,255);
+       comparePixel(ctx,  80,45, 0,255,0,255);
+       comparePixel(ctx,  80,46, 0,255,0,255);
+       comparePixel(ctx,  65,45, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.fillStyle = '#f00';
+       ctx.beginPath();
+       ctx.rect(10, 20, 45, 10);
+       ctx.moveTo(80, 45);
+       ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true);
+       ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false);
+       ctx.fill();
+
+       ctx.strokeStyle = '#0f0';
+       ctx.lineWidth = 10;
+       ctx.beginPath();
+       ctx.moveTo(10, 25);
+       ctx.arcTo(75, 25, 75, 60, 20);
+       ctx.stroke();
+
+       //comparePixel(ctx,  50,25, 0,255,0,255);
+       comparePixel(ctx,  55,19, 0,255,0,255);
+       comparePixel(ctx,  55,20, 0,255,0,255);
+       if (canvas.renderTarget === Canvas.Image) {
+           //FIXME:broken for Canvas.FramebufferObject
+           comparePixel(ctx,  55,21, 0,255,0,255);
        }
+       comparePixel(ctx,  64,22, 0,255,0,255);
+       comparePixel(ctx,  65,21, 0,255,0,255);
+       comparePixel(ctx,  72,28, 0,255,0,255);
+       comparePixel(ctx,  73,27, 0,255,0,255);
+       comparePixel(ctx,  78,36, 0,255,0,255);
+       comparePixel(ctx,  79,35, 0,255,0,255);
+       comparePixel(ctx,  80,44, 0,255,0,255);
+       comparePixel(ctx,  80,45, 0,255,0,255);
+       comparePixel(ctx,  80,46, 0,255,0,255);
+       ctx.reset();
+
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.strokeStyle = '#f00';
+       ctx.lineWidth = 50;
+       ctx.beginPath();
+       ctx.moveTo(-100, -100);
+       ctx.arcTo(-100, 25, 200, 25, 10);
+       ctx.stroke();
+
+       comparePixel(ctx,  1,1, 0,255,0,255);
+       comparePixel(ctx,  1,48, 0,255,0,255);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       comparePixel(ctx,  98,1, 0,255,0,255);
+       comparePixel(ctx,  98,48, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.strokeStyle = '#0f0';
+       ctx.lineWidth = 50;
+       ctx.beginPath();
+       ctx.moveTo(0, 25);
+       ctx.arcTo(200, 25, 200, 50, 10);
+       ctx.stroke();
+
+       //FIXME
+       //comparePixel(ctx,  1,1, 0,255,0,255);
+       //comparePixel(ctx,  1,48, 0,255,0,255);
+       //comparePixel(ctx,  50,25, 0,255,0,255);
+       //comparePixel(ctx,  98,1, 0,255,0,255);
+       //comparePixel(ctx,  98,48, 0,255,0,255);
+   }
+
+   function test_transform(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.fillStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(0, 50);
+       ctx.translate(100, 0);
+       ctx.arcTo(50, 50, 50, 0, 50);
+       ctx.lineTo(-100, 0);
+       ctx.fill();
+
+       comparePixel(ctx,  0,0, 0,255,0,255);
+       comparePixel(ctx,  50,0, 0,255,0,255);
+       comparePixel(ctx,  99,0, 0,255,0,255);
+       comparePixel(ctx,  0,25, 0,255,0,255);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       comparePixel(ctx,  99,25, 0,255,0,255);
+       comparePixel(ctx,  0,49, 0,255,0,255);
+       comparePixel(ctx,  50,49, 0,255,0,255);
+       comparePixel(ctx,  99,49, 0,255,0,255);
+    }
+   function test_zero(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.lineWidth = 50;
+
+       ctx.strokeStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(0, 25);
+       ctx.arcTo(100, 25, 100, 100, 0);
+       ctx.stroke();
+
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(0, -25);
+       ctx.arcTo(50, -25, 50, 50, 0);
+       ctx.stroke();
+
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.lineWidth = 50;
+
+       ctx.strokeStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(0, 25);
+       ctx.arcTo(100, 25, -100, 25, 0);
+       ctx.stroke();
+
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(100, 25);
+       ctx.arcTo(200, 25, 50, 25, 0);
+       ctx.stroke();
+
+       comparePixel(ctx,  50,25, 0,255,0,255);
    }
 }
index a70c798..7c17499 100644 (file)
 import QtQuick 2.0
-import QtTest 1.0
-
-Rectangle {
-    id:container
-    width:100
-    height:100
-    Component {
-        id:canvas
-        Canvas {
-            id:c
-             width:100;height:100
-             onPaint: {
-                 var context = getContext("2d");
-                 context.fillStyle = "red";
-                 context.fillRect(0, 0, 100, 100);
-             }
-             renderTarget:Canvas.Image
-             renderStrategy:Canvas.Threaded
-             property int paintCount:spyPaint.count
-             property int paintedCount:spyPainted.count
-             property int canvasSizeChangedCount:spyCanvasSizeChanged.count
-             property int tileSizeChangedCount:spyTileSizeChanged.count
-             property int renderStrategyChangedCount:spyRenderStrategyChanged.count
-             property int canvasWindowChangedCount:spyCanvasWindowChanged.count
-             property int renderTargetChangedCount:spyRenderTargetChanged.count
-             property int imageLoadedCount:spyImageLoaded.count
-             property int availableChangedCount:spyAvailableChanged.count
-
-             SignalSpy {id: spyPaint;target:c;signalName: "paint"}
-             SignalSpy {id: spyPainted;target:c;signalName: "painted"}
-             SignalSpy {id: spyCanvasSizeChanged;target:c;signalName: "canvasSizeChanged"}
-             SignalSpy {id: spyTileSizeChanged;target:c;signalName: "tileSizeChanged"}
-             SignalSpy {id: spyRenderStrategyChanged;target:c;signalName: "renderStrategyChanged"}
-             SignalSpy {id: spyCanvasWindowChanged;target:c;signalName: "canvasWindowChanged"}
-             SignalSpy {id: spyRenderTargetChanged;target:c;signalName: "renderTargetChanged"}
-             SignalSpy {id: spyImageLoaded;target:c;signalName: "imageLoaded"}
-             SignalSpy {id: spyAvailableChanged;target:c;signalName: "availableChanged"}
-        }
-    }
-
-   TestCase {
-       name: "Canvas"; when: windowShown
-       function test_canvasSize() {
-           var c = canvas.createObject(container);
-           verify(c);
-           wait(100);
-           verify(c.availableChangedCount, 1);
-
-           //by default canvasSize is same with canvas' actual size
-           // when canvas size changes, canvasSize should be changed as well.
-           compare(c.canvasSize.width, c.width);
-           compare(c.canvasSize.height, c.height);
-           c.width = 20;
-           compare(c.canvasSize.width, 20);
-           compare(c.canvasSizeChangedCount, 1);
-           c.height = 5;
-           compare(c.canvasSizeChangedCount, 2);
-           compare(c.canvasSize.height, 5);
-
-           //change canvasSize manually, then canvasSize detaches from canvas
-           //actual size.
-           c.canvasSize.width = 100;
-           compare(c.canvasSizeChangedCount, 3);
-           compare(c.canvasSize.width, 100);
-           compare(c.width, 20);
-           c.canvasSize.height = 50;
-           compare(c.canvasSizeChangedCount, 4);
-           compare(c.canvasSize.height, 50);
-           compare(c.height, 5);
-
-           c.width = 10;
-           compare(c.canvasSizeChangedCount, 4);
-           compare(c.canvasSize.width, 100);
-           compare(c.canvasSize.height, 50);
-
-           c.height = 10;
-           compare(c.canvasSizeChangedCount, 4);
-           compare(c.canvasSize.width, 100);
-           compare(c.canvasSize.height, 50);
-           c.destroy();
-      }
-       function test_tileSize() {
-           var c = canvas.createObject(container);
-           verify(c);
-           wait(100);
-           verify(c.availableChangedCount, 1);
-
-           compare(c.tileSize.width, c.width);
-           compare(c.tileSize.height, c.height);
-           c.width = 20;
-           compare(c.tileSize.width, 20);
-           compare(c.tileSizeChangedCount, 1);
-           c.height = 5;
-           compare(c.tileSizeChangedCount, 2);
-           compare(c.tileSize.height, 5);
-
-           c.tileSize.width = 100;
-           compare(c.tileSizeChangedCount, 3);
-           compare(c.tileSize.width, 100);
-           compare(c.width, 20);
-           c.tileSize.height = 50;
-           compare(c.tileSizeChangedCount, 4);
-           compare(c.tileSize.height, 50);
-           compare(c.height, 5);
-
-           c.width = 10;
-           compare(c.tileSizeChangedCount, 4);
-           compare(c.tileSize.width, 100);
-           compare(c.tileSize.height, 50);
-
-           c.height = 10;
-           compare(c.tileSizeChangedCount, 4);
-           compare(c.tileSize.width, 100);
-           compare(c.tileSize.height, 50);
-           c.destroy();
 
-       }
+CanvasTestCase {
+   id:testCase
+   name: "canvas"
+   function init_data() { return testData("2d"); }
+
+   function test_canvasSize(row) {
+       var c = createCanvasObject(row);
+       verify(c);
+       var ctx = c.getContext("2d");
+       verify(ctx);
+
+       tryCompare(c, "availableChangedCount", 1, 100);
+       //by default canvasSize is same with canvas' actual size
+       // when canvas size changes, canvasSize should be changed as well.
+       compare(c.canvasSize.width, c.width);
+       compare(c.canvasSize.height, c.height);
+       c.width = 20;
+       compare(c.canvasSize.width, 20);
+       compare(c.canvasSizeChangedCount, 1);
+       c.height = 5;
+       compare(c.canvasSizeChangedCount, 2);
+       compare(c.canvasSize.height, 5);
+
+       //change canvasSize manually, then canvasSize detaches from canvas
+       //actual size.
+       c.canvasSize.width = 100;
+       compare(c.canvasSizeChangedCount, 3);
+       compare(c.canvasSize.width, 100);
+       compare(c.width, 20);
+       c.canvasSize.height = 50;
+       compare(c.canvasSizeChangedCount, 4);
+       compare(c.canvasSize.height, 50);
+       compare(c.height, 5);
+
+       c.width = 10;
+       compare(c.canvasSizeChangedCount, 4);
+       compare(c.canvasSize.width, 100);
+       compare(c.canvasSize.height, 50);
+
+       c.height = 10;
+
+       compare(c.canvasSizeChangedCount, 4);
+       compare(c.canvasSize.width, 100);
+       compare(c.canvasSize.height, 50);
+       c.destroy();
+  }
+   function test_tileSize(row) {
+       var c = createCanvasObject(row);
+       verify(c);
+       var ctx = c.getContext("2d");
+       verify(ctx);
+       tryCompare(c, "availableChangedCount", 1, 100);
+
+       compare(c.tileSize.width, c.width);
+       compare(c.tileSize.height, c.height);
+       c.width = 20;
+       compare(c.tileSize.width, 20);
+       compare(c.tileSizeChangedCount, 1);
+       c.height = 5;
+       compare(c.tileSizeChangedCount, 2);
+       compare(c.tileSize.height, 5);
+
+       c.tileSize.width = 100;
+       compare(c.tileSizeChangedCount, 3);
+       compare(c.tileSize.width, 100);
+       compare(c.width, 20);
+       c.tileSize.height = 50;
+       compare(c.tileSizeChangedCount, 4);
+       compare(c.tileSize.height, 50);
+       compare(c.height, 5);
+
+       c.width = 10;
+       compare(c.tileSizeChangedCount, 4);
+       compare(c.tileSize.width, 100);
+       compare(c.tileSize.height, 50);
+
+       c.height = 10;
+       compare(c.tileSizeChangedCount, 4);
+       compare(c.tileSize.width, 100);
+       compare(c.tileSize.height, 50);
+       c.destroy();
+
+   }
 
-       function test_canvasWindow() {
-           var c = canvas.createObject(container);
-           verify(c);
-           wait(100);
-           verify(c.availableChangedCount, 1);
-           compare(c.canvasWindow.x, 0);
-           compare(c.canvasWindow.y, 0);
-           compare(c.canvasWindow.width, c.width);
-           compare(c.canvasWindow.height, c.height);
-
-           c.width = 20;
-           compare(c.canvasWindow.width, 20);
-           compare(c.canvasWindowChangedCount, 1);
-           c.height = 5;
-           compare(c.canvasWindowChangedCount, 2);
-           compare(c.canvasWindow.height, 5);
-
-           c.canvasWindow.x = 5;
-           c.canvasWindow.y = 6;
-           c.canvasWindow.width = 10;
-           c.canvasWindow.height =20;
-           compare(c.canvasWindowChangedCount, 6);
-           compare(c.canvasWindow.width, 10);
-           compare(c.canvasWindow.height, 20);
-           compare(c.canvasWindow.x, 5);
-           compare(c.canvasWindow.y, 6);
-           c.destroy();
-
-      }
-       function test_renderTargetAndStrategy() {
-           var c = canvas.createObject(container);
-           verify(c);
-           wait(100);
-           verify(c.availableChangedCount, 1);
-
-           compare(c.renderTarget, Canvas.Image);
-           compare(c.renderStrategy, Canvas.Threaded);
-           c.destroy();
-
-      }
-       function test_save() {
-           var c = canvas.createObject(container);
-           verify(c);
-           wait(100);
-           verify(c.availableChangedCount, 1);
-
-           c.renderTarget = Canvas.Image;
-           c.requestPaint();
-           wait(100);
-           verify(c.save("c.png"));
-           c.loadImage("c.png");
-           wait(200);
-           compare(c.imageLoadedCount, 1);
-           verify(c.isImageLoaded("c.png"));
-           verify(!c.isImageLoading("c.png"));
-           verify(!c.isImageError("c.png"));
-           c.destroy();
-
-      }
-       function test_toDataURL_data() {
-           return [{mimeType:"image/png"},
+   function test_canvasWindow(row) {
+       var c = createCanvasObject(row);
+       verify(c);
+       var ctx = c.getContext("2d");
+       verify(ctx);
+
+       tryCompare(c, "availableChangedCount", 1, 100);
+       compare(c.canvasWindow.x, 0);
+       compare(c.canvasWindow.y, 0);
+       compare(c.canvasWindow.width, c.width);
+       compare(c.canvasWindow.height, c.height);
+
+       c.width = 20;
+       compare(c.canvasWindow.width, 20);
+       compare(c.canvasWindowChangedCount, 1);
+       c.height = 5;
+       compare(c.canvasWindowChangedCount, 2);
+       compare(c.canvasWindow.height, 5);
+
+       c.canvasWindow.x = 5;
+       c.canvasWindow.y = 6;
+       c.canvasWindow.width = 10;
+       c.canvasWindow.height =20;
+       compare(c.canvasWindowChangedCount, 6);
+       compare(c.canvasWindow.width, 10);
+       compare(c.canvasWindow.height, 20);
+       compare(c.canvasWindow.x, 5);
+       compare(c.canvasWindow.y, 6);
+       c.destroy();
+
+  }
+
+   function test_save(row) {
+       var c = createCanvasObject(row);
+       verify(c);
+       var ctx = c.getContext("2d");
+
+       tryCompare(c, "availableChangedCount", 1, 100);
+
+       c.requestPaint();
+       verify(c.save("c.png"));
+       c.loadImage("c.png");
+       wait(200);
+       verify(c.isImageLoaded("c.png"));
+       verify(!c.isImageLoading("c.png"));
+       verify(!c.isImageError("c.png"));
+       c.destroy();
+  }
+
+   function test_toDataURL(row) {
+       var c = createCanvasObject(row);
+       verify(c);
+       var ctx = c.getContext("2d");
+       verify(ctx);
+
+       tryCompare(c, "availableChangedCount", 1, 100);
+
+       var imageTypes = [
+                   {mimeType:"image/png"},
                    {mimeType:"image/bmp"},
                    {mimeType:"image/jpeg"},
                    {mimeType:"image/x-portable-pixmap"},
                    //{mimeType:"image/tiff"}, QTBUG-23980
                    {mimeType:"image/xpm"},
-                   ];
-       }
-
-       function test_toDataURL(data) {
-           var c = canvas.createObject(container);
-           verify(c);
-           wait(100);
-           verify(c.availableChangedCount, 1);
-
-           var ctx = c.getContext("2d");
+                  ];
+       for (var i = 0; i < imageTypes.length; i++) {
            ctx.fillStyle = "red";
            ctx.fillRect(0, 0, c.width, c.height);
-           wait(100);
 
            var dataUrl = c.toDataURL();
-           verify(dataUrl != "data:,");
+           verify(dataUrl !== "data:,");
            dataUrl = c.toDataURL("image/invalid");
-           verify(dataUrl == "data:,");
+           verify(dataUrl === "data:,");
 
-           dataUrl = c.toDataURL(data.mimeType);
-           verify(dataUrl != "data:,");
+           dataUrl = c.toDataURL(imageTypes[i].mimeType);
+           verify(dataUrl !== "data:,");
 
            ctx.save();
            ctx.fillStyle = "blue";
            ctx.fillRect(0, 0, c.width, c.height);
            ctx.restore();
-           wait(100);
-
-           var dataUrl2 = c.toDataURL(data.mimeType);
-           verify (dataUrl2 != "data:,");
-           verify (dataUrl2 != dataUrl);
-           c.destroy();
-
-      }
-       function test_paint() {
-           var c = canvas.createObject(container);
-           verify(c);
-           wait(100);
-           verify(c.availableChangedCount, 1);
-
-           c.renderTarget = Canvas.Image;
-           c.renderStrategy = Canvas.Immediate;
-           var ctx = c.getContext("2d");
-           ctx.fillRect(0, 0, c.width, c.height);
-           c.toDataURL();
-           wait(100);
-
-           compare(c.paintedCount, 2);
-           compare(c.paintCount, 1);
-           c.destroy();
-
-      }
-       function test_loadImage() {
-           var c = canvas.createObject(container);
-           verify(c);
-           wait(100);
-           verify(c.availableChangedCount, 1);
-
-           c.loadImage("red.png");
-           wait(200);
-           compare(c.imageLoadedCount, 1);
-           verify(c.isImageLoaded("red.png"));
-           verify(!c.isImageLoading("red.png"));
-           verify(!c.isImageError("red.png"));
-
-           c.unloadImage("red.png");
-           verify(!c.isImageLoaded("red.png"));
-           verify(!c.isImageLoading("red.png"));
-           verify(!c.isImageError("red.png"));
-           c.destroy();
-
-      }
-
-       function test_getContext() {
-           var c = canvas.createObject(container);
-           verify(c);
-           wait(100);
-           verify(c.availableChangedCount, 1);
-
-           var ctx = c.getContext("2d");
-           verify(ctx);
-           compare(ctx.canvas, c);
-           ctx = c.getContext('2d');
-           verify(ctx);
-           compare(ctx.canvas, c);
-           ctx = c.getContext('2D');
-           verify(ctx);
-           compare(ctx.canvas, c);
-           ignoreWarning(Qt.resolvedUrl("tst_canvas.qml") + ":10:9: QML Canvas: Canvas already initialized with a different context type");
-           ctx = c.getContext('invalid');
-           verify(!ctx);
-           c.destroy();
-
-      }
-   }
+
+           var dataUrl2 = c.toDataURL(imageTypes[i].mimeType);
+           verify (dataUrl2 !== "data:,");
+           verify (dataUrl2 !== dataUrl);
+       }
+       c.destroy();
+
+  }
+   function test_paint(row) {
+       var c = createCanvasObject(row);
+       verify(c);
+       var ctx = c.getContext("2d");
+       tryCompare(c, "availableChangedCount", 1, 100);
+
+       ctx.fillRect(0, 0, c.width, c.height);
+       c.toDataURL();
+       tryCompare(c, "paintedCount", 2, 200);
+       tryCompare(c, "paintCount", 1, 200);
+       c.destroy();
+  }
+   function test_loadImage(row) {
+       var c = createCanvasObject(row);
+       verify(c);
+       var ctx = c.getContext("2d");
+       verify(ctx);
+
+       tryCompare(c, "availableChangedCount", 1, 100);
+
+       verify(!c.isImageLoaded("red.png"));
+       c.loadImage("red.png");
+       wait(200);
+       verify(c.isImageLoaded("red.png"));
+       verify(!c.isImageLoading("red.png"));
+       verify(!c.isImageError("red.png"));
+
+       c.unloadImage("red.png");
+       verify(!c.isImageLoaded("red.png"));
+       verify(!c.isImageLoading("red.png"));
+       verify(!c.isImageError("red.png"));
+       c.destroy();
+
+  }
+
+   function test_getContext(row) {
+       var c = createCanvasObject(row);
+       verify(c);
+       var ctx = c.getContext("2d");
+       verify(ctx);
+       tryCompare(c, "availableChangedCount", 1, 100);
+
+       compare(ctx.canvas, c);
+       ctx = c.getContext('2d');
+       verify(ctx);
+       compare(ctx.canvas, c);
+       ctx = c.getContext('2D');
+       verify(ctx);
+       compare(ctx.canvas, c);
+       ignoreWarning(Qt.resolvedUrl("CanvasComponent.qml") + ":6:9: QML Canvas: Canvas already initialized with a different context type");
+       ctx = c.getContext('invalid');
+       verify(!ctx);
+       c.destroy();
+
+  }
 }
index 60c63ae..3e41efd 100644 (file)
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50; renderTarget:Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       name: "composite"; when: windowShown
-       function test_clearRect() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-atop';
-           ctx.clearRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0));
-      }
-
-       function test_clip_data() {
-           return [ {compsite:"copy"},
-                    {compsite:"destination-atop"},
-                    {compsite:"destination-in"},
-                    {compsite:"destination-out"},
-                    {compsite:"destination-over"},
-                    {compsite:"lighter"},
-                    {compsite:"source-atop"},
-                    {compsite:"source-in"},
-                    {compsite:"source-out"},
-                    {compsite:"source-over"},
-                    {compsite:"xor"}
-                   ];
-       }
 
-       function test_clip(data) {
-           var ctx = canvas.getContext('2d');
+CanvasTestCase {
+   id:testCase
+   name: "composite"
+   function init_data() { return testData("2d"); }
+   function test_clearRect(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-atop';
+       ctx.clearRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,0,0,0);
+  }
+
+   function test_clip(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       var composites = [ {compsite:"copy"},
+                         {compsite:"destination-atop"},
+                         {compsite:"destination-in"},
+                         {compsite:"destination-out"},
+                         {compsite:"destination-over"},
+                        // {compsite:"lighter"}, //qt doesn't support lighter
+                         {compsite:"source-atop"},
+                         {compsite:"source-in"},
+                         {compsite:"source-out"},
+                         {compsite:"source-over"},
+                         {compsite:"xor"}
+                        ];
+       for (var i=0; i<composites.length; i++) {
+//           console.log("composite:" + composites[i].compsite);
            ctx.reset();
            ctx.fillStyle = '#0f0';
            ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = data.compsite;
+           ctx.globalCompositeOperation = composites[i].compsite;
            ctx.rect(-20, -20, 10, 10);
            ctx.clip();
            ctx.fillStyle = '#f00';
            ctx.fillRect(0, 0, 50, 50);
-           verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+           comparePixel(ctx, 25,25, 0,255,0,255);
+           comparePixel(ctx, 75,25, 0,255,0,255);
        }
+   }
 
-       function test_globalAlpha() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           compare(ctx.globalAlpha, 1.0);
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 2,253,0,255, 2));
-
-           ctx.reset();
-           ctx.globalAlpha = 0.5;
-           var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
-           ctx.globalAlpha = Infinity;
-           compare(ctx.globalAlpha, a);
-           ctx.globalAlpha = -Infinity;
-           compare(ctx.globalAlpha, a);
-           ctx.globalAlpha = NaN;
-           compare(ctx.globalAlpha, a);
-
-           ctx.globalAlpha = 0.5;
-           a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
-           ctx.globalAlpha = 1.1;
-           compare(ctx.globalAlpha, a);
-           ctx.globalAlpha = -0.1;
-           compare(ctx.globalAlpha, a);
-           ctx.globalAlpha = 0;
-           compare(ctx.globalAlpha, 0);
-           ctx.globalAlpha = 1;
-           compare(ctx.globalAlpha, 1);
-
-       }
-
-       function test_operation() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.globalCompositeOperation = 'xor';
-           ctx.globalCompositeOperation = 'Source-over';
-           compare(ctx.globalCompositeOperation, 'xor');
-
-           ctx.reset();
-           ctx.globalCompositeOperation = 'xor';
-           ctx.globalCompositeOperation = 'clear';
-           compare(ctx.globalCompositeOperation, 'xor');
-
-           ctx.reset();
-           ctx.globalCompositeOperation = 'xor';
-           ctx.globalCompositeOperation = 'darker';
-           compare(ctx.globalCompositeOperation, 'xor');
-
-           ctx.reset();
-           compare(ctx.globalCompositeOperation, 'source-over');
-
-
-           ctx.reset();
-           var modes = ['source-atop', 'source-in', 'source-out', 'source-over',
-               'destination-atop', 'destination-in', 'destination-out', 'destination-over',
-               'lighter', 'copy', 'xor'];
-           for (var i = 0; i < modes.length; ++i)
-           {
-               ctx.globalCompositeOperation = modes[i];
-               compare(ctx.globalCompositeOperation, modes[i]);
-           }
-
-           ctx.reset();
-           ctx.globalCompositeOperation = 'xor';
-           ctx.globalCompositeOperation = 'highlight';
-           compare(ctx.globalCompositeOperation, 'xor');
-
-           ctx.reset();
-           ctx.globalCompositeOperation = 'xor';
-           ctx.globalCompositeOperation = 'source-over\\0';
-           compare(ctx.globalCompositeOperation, 'xor');
-
-           ctx.reset();
-           ctx.globalCompositeOperation = 'xor';
-           ctx.globalCompositeOperation = 'over';
-           compare(ctx.globalCompositeOperation, 'xor');
-
-
-           ctx.reset();
-           ctx.globalCompositeOperation = 'xor';
-           ctx.globalCompositeOperation = 'nonexistent';
-           compare(ctx.globalCompositeOperation, 'xor');
-       }
-
-       function test_solid() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = Qt.rgba(0, 1, 1, 1.0);
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'copy';
-           ctx.fillStyle = Qt.rgba(1, 1, 0, 1.0);
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-atop';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-in';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-out';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
-
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-over';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'lighter';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 255,255,255,255, 5));
-
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-atop';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5));
-
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-in';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5));
-
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-out';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-          // verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
-
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-over';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'xor';
-           ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
-       }
-       function test_transparent() {
-
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'copy';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,0,255,191, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'copy';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,0,255,191, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-in';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,95, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-out';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,31, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-over';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,145,109,223, 5));
-
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'lighter';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           //FIXME
-           //verify(Helper.comparePixel(ctx, 50,25, 0,127,191,255, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-atop';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,63,191,127, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-in';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,0,255,95, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-out';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,0,255,95, 5));
-
+   function test_globalAlpha(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       compare(ctx.globalAlpha, 1.0);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 2,253,0,255, 2);
+
+       ctx.reset();
+       ctx.globalAlpha = 0.5;
+       var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
+       ctx.globalAlpha = Infinity;
+       compare(ctx.globalAlpha, a);
+       ctx.globalAlpha = -Infinity;
+       compare(ctx.globalAlpha, a);
+       ctx.globalAlpha = NaN;
+       compare(ctx.globalAlpha, a);
+
+       ctx.globalAlpha = 0.5;
+       a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
+       ctx.globalAlpha = 1.1;
+       compare(ctx.globalAlpha, a);
+       ctx.globalAlpha = -0.1;
+       compare(ctx.globalAlpha, a);
+       ctx.globalAlpha = 0;
+       compare(ctx.globalAlpha, 0);
+       ctx.globalAlpha = 1;
+       compare(ctx.globalAlpha, 1);
 
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-over';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,36,218,223, 5));
-
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'xor';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,63,191,127, 5));
+   }
 
+   function test_operation(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.globalCompositeOperation = 'xor';
+       ctx.globalCompositeOperation = 'Source-over';
+       compare(ctx.globalCompositeOperation, 'xor');
+
+       ctx.reset();
+       ctx.globalCompositeOperation = 'xor';
+       ctx.globalCompositeOperation = 'clear';
+       compare(ctx.globalCompositeOperation, 'xor');
+
+       ctx.reset();
+       ctx.globalCompositeOperation = 'xor';
+       ctx.globalCompositeOperation = 'darker';
+       compare(ctx.globalCompositeOperation, 'xor');
+
+       ctx.reset();
+       compare(ctx.globalCompositeOperation, 'source-over');
+
+
+       ctx.reset();
+       var modes = ['source-atop', 'source-in', 'source-out', 'source-over',
+           'destination-atop', 'destination-in', 'destination-out', 'destination-over',
+           'lighter', 'copy', 'xor'];
+       for (var i = 0; i < modes.length; ++i)
+       {
+           ctx.globalCompositeOperation = modes[i];
+           compare(ctx.globalCompositeOperation, modes[i]);
        }
 
-       function test_uncovered() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'copy';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.translate(0, 25);
-           ctx.fillRect(0, 50, 100, 50);
-           //FIXME
-           //verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+       ctx.reset();
+       ctx.globalCompositeOperation = 'xor';
+       ctx.globalCompositeOperation = 'highlight';
+       compare(ctx.globalCompositeOperation, 'xor');
 
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-atop';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.translate(0, 25);
-           ctx.fillRect(0, 50, 100, 50);
-           //FIXME
-           //verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+       ctx.reset();
+       ctx.globalCompositeOperation = 'xor';
+       ctx.globalCompositeOperation = 'source-over\\0';
+       compare(ctx.globalCompositeOperation, 'xor');
 
+       ctx.reset();
+       ctx.globalCompositeOperation = 'xor';
+       ctx.globalCompositeOperation = 'over';
+       compare(ctx.globalCompositeOperation, 'xor');
 
 
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-in';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.translate(0, 25);
-           ctx.fillRect(0, 50, 100, 50);
-           //FIXME
-           //verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+       ctx.reset();
+       ctx.globalCompositeOperation = 'xor';
+       ctx.globalCompositeOperation = 'nonexistent';
+       compare(ctx.globalCompositeOperation, 'xor');
+   }
 
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-in';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.translate(0, 25);
-           ctx.fillRect(0, 50, 100, 50);
-           //FIXME
-           //verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+   function test_solid(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = Qt.rgba(0, 1, 1, 1.0);
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'copy';
+       ctx.fillStyle = Qt.rgba(1, 1, 0, 1.0);
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 255,255,0, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-atop';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 0,255,255,255, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-in';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 0,255,255,255, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-out';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,0,0,0, 5);
+
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-over';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 0,255,255,255, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'lighter';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 255,255,255,255, 5);
+
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-atop';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 255,255,0, 5);
+
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-in';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 255,255,0, 5);
+
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-out';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+      // comparePixel(ctx, 50,25, 0,0,0,0, 5);
+
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-over';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 255,255,0, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'xor';
+       ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 0,0,0,0, 5);
+   }
+   function test_transparent(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'copy';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,0,255,191, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'copy';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,0,255,191, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-in';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,255,0,95, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-out';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,255,0,31, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-over';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,145,109,223, 5);
+
+
+//       qt does not support lighter...
+//       ctx.reset();
+//       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+//       ctx.fillRect(0, 0, 100, 50);
+//       ctx.globalCompositeOperation = 'lighter';
+//       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+//       ctx.fillRect(0, 0, 100, 50);
+       //FIXME
+       //comparePixel(ctx, 50,25, 0,127,191,255, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-atop';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,63,191,127, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-in';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,0,255,95, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-out';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,0,255,95, 5);
+
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-over';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,36,218,223, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'xor';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,63,191,127, 5);
 
-           ctx.reset();
-           ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'source-out';
-           ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
-           ctx.translate(0, 25);
-           ctx.fillRect(0, 50, 100, 50);
-           //FIXME
-           //verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+   }
 
-       }
+   function test_uncovered(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'copy';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.translate(0, 25);
+       ctx.fillRect(0, 50, 100, 50);
+       //FIXME
+       //comparePixel(ctx, 50,25, 0,0,0,0, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-atop';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.translate(0, 25);
+       ctx.fillRect(0, 50, 100, 50);
+       //FIXME
+       //comparePixel(ctx, 50,25, 0,0,0,0, 5);
+
+
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-in';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.translate(0, 25);
+       ctx.fillRect(0, 50, 100, 50);
+       //FIXME
+       //comparePixel(ctx, 50,25, 0,0,0,0, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-in';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.translate(0, 25);
+       ctx.fillRect(0, 50, 100, 50);
+       //FIXME
+       //comparePixel(ctx, 50,25, 0,0,0,0, 5);
+
+       ctx.reset();
+       ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'source-out';
+       ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+       ctx.translate(0, 25);
+       ctx.fillRect(0, 50, 100, 50);
+       //FIXME
+       //comparePixel(ctx, 50,25, 0,0,0,0, 5);
 
    }
+
 }
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_drawimage.qml b/tests/auto/quick/qquickcanvasitem/data/tst_drawimage.qml
deleted file mode 100644 (file)
index 75dd2b3..0000000
+++ /dev/null
@@ -1,667 +0,0 @@
-import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   Component.onCompleted: {
-       canvas.loadImage('green.png');
-       canvas.loadImage('red.png');
-       canvas.loadImage('rgrg-256x256.png');
-       canvas.loadImage('ggrr-256x256.png');
-       canvas.loadImage('broken.png');
-   }
-
-   TestCase {
-       //TODO
-       name: "image"; when: windowShown
-       function test_3args() {
-           //make sure all images are loaded
-           wait(200);
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.drawImage('green.png', 0, 0);
-           ctx.drawImage('red.png', -100, 0);
-           ctx.drawImage('red.png', 100, 0);
-           ctx.drawImage('red.png', 0, -50);
-           ctx.drawImage('red.png', 0, 50);
-
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-
-      }
-       function test_5args() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.drawImage('green.png', 50, 0, 50, 50);
-           ctx.drawImage('red.png', 0, 0, 50, 50);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 50, 50);
-
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-
-      }
-       function test_9args() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50);
-           ctx.drawImage('red.png', 0, 0, 100, 50, -100, 0, 100, 50);
-           ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 100, 50);
-           ctx.drawImage('red.png', 0, 0, 100, 50, 0, -50, 100, 50);
-           ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 50);
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.drawImage('green.png', 1, 1, 1, 1, 0, 0, 100, 50);
-           ctx.drawImage('red.png', 0, 0, 100, 50, -50, 0, 50, 50);
-           ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 50, 50);
-           ctx.drawImage('red.png', 0, 0, 100, 50, 0, -25, 100, 25);
-           ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 25);
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.drawImage('rgrg-256x256.png', 140, 20, 100, 50, 0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.drawImage('rgrg-256x256.png', 0, 0, 256, 256, 0, 0, 100, 50);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 51, 26);
-           ctx.fillRect(49, 24, 51, 26);
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 20,20, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 80,20, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 20,30, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 80,30, 0,255,0,255,2));
-
-       }
-       function test_animated() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           //should animated image be supported at all?
-      }
-       function test_clip() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.rect(-10, -10, 1, 1);
-           ctx.clip();
-           ctx.drawImage('red.png', 0, 0);
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
-
-
-      }
-       function test_self() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ignoreWarning("QImage::scaled: Image is a null image");
-           ignoreWarning("QImage::scaled: Image is a null image");
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 50, 50);
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(50, 0, 50, 50);
-           ctx.drawImage(canvas, 50, 0);
-
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 1, 100, 49);
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 1);
-           ctx.drawImage(canvas, 0, 1);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 2);
-
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-
-
-       }
-
-       function test_outsidesource() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.drawImage('green.png', 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50);
-           ctx.drawImage('green.png', 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50);
-           ctx.drawImage('green.png', 100, 50, -5, -5, 0, 0, 100, 50);
-           try { var err = false;
-             ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50)"); }
-           try { var err = false;
-             ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50)"); }
-           try { var err = false;
-             ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50)"); }
-           try { var err = false;
-             ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50)"); }
-           try { var err = false;
-             ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50)"); }
-           try { var err = false;
-             ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50)"); }
-           try { var err = false;
-             ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50)"); }
-//           try { var err = false;
-//             ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50);
-//           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50)"); }
-//           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
-
-       }
-
-       function test_null() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           try { var err = false;
-             ctx.drawImage(null, 0, 0);
-           } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(null, 0, 0)"); }
-
-       }
-
-       function test_composite() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalCompositeOperation = 'destination-over';
-           ctx.drawImage('red.png', 0, 0);
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
-
-      }
-       function test_path() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_transform() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.translate(100, 0);
-           ctx.drawImage('red.png', 0, 0);
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
-
-      }
-
-       function test_imageitem() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           //TODO
-       }
-
-       function test_imageData() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           //TODO
-       }
-
-       function test_wrongtype() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           try { var err = false;
-             ctx.drawImage(undefined, 0, 0);
-           } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(undefined, 0, 0)"); }
-           try { var err = false;
-             ctx.drawImage(0, 0, 0);
-           } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(0, 0, 0)"); }
-           try { var err = false;
-             ctx.drawImage("", 0, 0);
-           } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(\"\", 0, 0)"); }
-       }
-
-       function test_nonfinite() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ignoreWarning("QImage::scaled: Image is a null image");
-           ignoreWarning("QImage::scaled: Image is a null image");
-           ignoreWarning("QImage::scaled: Image is a null image");
-           ignoreWarning("QImage::scaled: Image is a null image");
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           var red = 'red.png';
-           ctx.drawImage(red, Infinity, 0);
-           ctx.drawImage(red, -Infinity, 0);
-           ctx.drawImage(red, NaN, 0);
-           ctx.drawImage(red, 0, Infinity);
-           ctx.drawImage(red, 0, -Infinity);
-           ctx.drawImage(red, 0, NaN);
-           ctx.drawImage(red, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50);
-           ctx.drawImage(red, -Infinity, 0, 100, 50);
-           ctx.drawImage(red, NaN, 0, 100, 50);
-           ctx.drawImage(red, 0, Infinity, 100, 50);
-           ctx.drawImage(red, 0, -Infinity, 100, 50);
-           ctx.drawImage(red, 0, NaN, 100, 50);
-           ctx.drawImage(red, 0, 0, Infinity, 50);
-           ctx.drawImage(red, 0, 0, -Infinity, 50);
-           ctx.drawImage(red, 0, 0, NaN, 50);
-           ctx.drawImage(red, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, -Infinity);
-           ctx.drawImage(red, 0, 0, 100, NaN);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, -Infinity, 0, 100, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, NaN, 0, 100, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, -Infinity, 100, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, NaN, 100, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, -Infinity, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, NaN, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, -Infinity, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, NaN, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, -Infinity, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, NaN, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, -Infinity, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, NaN, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, 0, -Infinity, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, 0, NaN, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, -Infinity);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, NaN);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, 50);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, 50);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, 50);
-           ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, 50);
-           ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, 50);
-           ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, 50);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, 50);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, 50);
-           ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, 50);
-           ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, 50);
-           ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, 50);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, 50);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, 50);
-           ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, 50);
-           ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, 50);
-           ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, 50);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, Infinity);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, Infinity);
-           ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, Infinity);
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-
-       }
-
-       function test_negative() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.drawImage('ggrr-256x256.png', 100, 78, 50, 50, 0, 50, 50, -50);
-           ctx.drawImage('ggrr-256x256.png', 100, 128, 50, -50, 100, 50, -50, -50);
-//           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.drawImage('ggrr-256x256.png', 0, 178, 50, -100, 0, 0, 50, 100);
-           ctx.drawImage('ggrr-256x256.png', 0, 78, 50, 100, 50, 100, 50, -100);
-//           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.drawImage('ggrr-256x256.png', 100, 78, -100, 50, 0, 0, 50, 50);
-           ctx.drawImage('ggrr-256x256.png', 100, 128, -100, -50, 50, 0, 50, 50);
-//           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2));
-//           verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2));
-
-       }
-
-       function test_canvas() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           var canvas2 = Qt.createQmlObject("import QtQuick 2.0; Canvas{renderTarget:Canvas.Image}", canvas);
-           canvas2.width = 100;
-           canvas2.height = 50;
-           var ctx2 = canvas2.getContext('2d');
-           ctx2.fillStyle = '#0f0';
-           ctx2.fillRect(0, 0, 100, 50);
-
-           ctx.fillStyle = '#f00';
-           ctx.drawImage(canvas2, 0, 0);
-
-           //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
-           //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
-           //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
-           //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
-
-       }
-
-       function test_broken() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           var img = 'broken.png';
-           verify(!img.complete);
-           ctx.drawImage(img, 0, 0);
-       }
-
-       function test_alpha() {
-           var ctx=canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.globalAlpha = 0;
-           ctx.drawImage('red.png', 0, 0);
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255, 2));
-
-       }
-   }
-}
index 153a103..58ea6d7 100644 (file)
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
 
-Canvas {
-   id:canvas; width:1;height:1;renderTarget:Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       name: "fillStyle"; when: windowShown
-       function test_default() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           verify(ctx.fillStyle, "#000000");
-           ctx.clearRect(0, 0, 1, 1);
-           compare(ctx.fillStyle, "#000000");
-       }
-       function test_get() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#fa0';
-           compare(ctx.fillStyle, '#ffaa00');
-           ctx.fillStyle = Qt.rgba(0,0,0,0);
-           compare(ctx.fillStyle, 'rgba(0, 0, 0, 0.0)');
-       }
-       function test_hex() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           compare(ctx.fillStyle, '#ff0000');
-           ctx.fillStyle = "#0f0";
-           compare(ctx.fillStyle, '#00ff00');
-           ctx.fillStyle = "#0fF";
-           compare(ctx.fillStyle, '#00ffff');
-           ctx.fillStyle = "#0aCCfb";
-           compare(ctx.fillStyle, '#0accfb');
-
-       }
-       function test_invalid() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#fa0';
-           compare(ctx.fillStyle, '#ffaa00');
-           ctx.fillStyle = "invalid";
-           compare(ctx.fillStyle, '#ffaa00');
-           ctx.fillStyle = "rgb (1, 2, 3)";
-           compare(ctx.fillStyle, '#ffaa00');
-           ctx.fillStyle = '#fa0';
+CanvasTestCase {
+   id:testCase
+   name: "fillStyle"
+   function init_data() { return testData("2d"); }
+   function test_default(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       verify(ctx.fillStyle, "#000000");
+       ctx.clearRect(0, 0, 1, 1);
+       compare(ctx.fillStyle, "#000000");
+   }
+   function test_get(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#fa0';
+       compare(ctx.fillStyle, '#ffaa00');
+       ctx.fillStyle = Qt.rgba(0,0,0,0);
+       compare(ctx.fillStyle, 'rgba(0, 0, 0, 0.0)');
+   }
+   function test_hex(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       compare(ctx.fillStyle, '#ff0000');
+       ctx.fillStyle = "#0f0";
+       compare(ctx.fillStyle, '#00ff00');
+       ctx.fillStyle = "#0fF";
+       compare(ctx.fillStyle, '#00ffff');
+       ctx.fillStyle = "#0aCCfb";
+       compare(ctx.fillStyle, '#0accfb');
 
-           ctx.fillStyle = "rgba(3, 1, 2)";
-           compare(ctx.fillStyle, '#ffaa00');
-           ctx.fillStyle = "rgb((3,4,1)";
-           compare(ctx.fillStyle, '#ffaa00');
-           ctx.fillStyle = "rgb(1, 3, 4, 0.5)";
-           compare(ctx.fillStyle, '#ffaa00');
-           ctx.fillStyle = "hsl(2, 3, 4, 0.8)";
-           compare(ctx.fillStyle, '#ffaa00');
-           ctx.fillStyle = "hsl(2, 3, 4";
-           compare(ctx.fillStyle, '#ffaa00');
-       }
-       function test_saverestore() {
-           var ctx = canvas.getContext('2d');
-           var old = ctx.fillStyle;
-           ctx.save();
-           ctx.fillStyle = "#ffaaff";
-           ctx.restore();
-           compare(ctx.fillStyle, old);
+   }
+   function test_invalid(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#fa0';
+       compare(ctx.fillStyle, '#ffaa00');
+       ctx.fillStyle = "invalid";
+       compare(ctx.fillStyle, '#ffaa00');
+       ctx.fillStyle = "rgb (1, 2, 3)";
+       compare(ctx.fillStyle, '#ffaa00');
+       ctx.fillStyle = '#fa0';
 
-           ctx.fillStyle = "#ffcc88";
-           old = ctx.fillStyle;
-           ctx.save();
-           compare(ctx.fillStyle, old);
-           ctx.restore();
-       }
-       function test_namedColor() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = "red";
-           ctx.fillRect(0,0,1,1);
-           verify(Helper.comparePixel(ctx,0,0,255,0,0,255));
+       ctx.fillStyle = "rgba(3, 1, 2)";
+       compare(ctx.fillStyle, '#ffaa00');
+       ctx.fillStyle = "rgb((3,4,1)";
+       compare(ctx.fillStyle, '#ffaa00');
+       ctx.fillStyle = "rgb(1, 3, 4, 0.5)";
+       compare(ctx.fillStyle, '#ffaa00');
+       ctx.fillStyle = "hsl(2, 3, 4, 0.8)";
+       compare(ctx.fillStyle, '#ffaa00');
+       ctx.fillStyle = "hsl(2, 3, 4";
+       compare(ctx.fillStyle, '#ffaa00');
+   }
+   function test_saverestore(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       var old = ctx.fillStyle;
+       ctx.save();
+       ctx.fillStyle = "#ffaaff";
+       ctx.restore();
+       compare(ctx.fillStyle, old);
 
-           ctx.fillStyle = "black";
-           ctx.fillRect(0,0,1,1);
-           verify(Helper.comparePixel(ctx,0,0,0,0,0,255));
+       ctx.fillStyle = "#ffcc88";
+       old = ctx.fillStyle;
+       ctx.save();
+       compare(ctx.fillStyle, old);
+       ctx.restore();
+   }
+   function test_namedColor(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = "red";
+       ctx.fillRect(0,0,1,1);
+       comparePixel(ctx,0,0,255,0,0,255);
 
-           ctx.fillStyle = "white";
-           ctx.fillRect(0,0,1,1);
-           verify(Helper.comparePixel(ctx,0,0,255,255,255,255));
-       }
-       function test_rgba() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = "rgb(-100, 300, 255)";
-           compare(ctx.fillStyle, "#00ffff");
-           ctx.fillStyle = "rgba(-100, 300, 255, 0.0)";
-           compare(ctx.fillStyle, "rgba(0, 255, 255, 0.0)");
-           ctx.fillStyle = "rgb(-10%, 110%, 50%)";
-           compare(ctx.fillStyle, "#00ff80");
+       ctx.fillStyle = "black";
+       ctx.fillRect(0,0,1,1);
+       comparePixel(ctx,0,0,0,0,0,255);
 
-           ctx.clearRect(0, 0, 1, 1);
-           ctx.fillStyle = 'rgba(0%, 100%, 0%, 0.499)';
-           ctx.fillRect(0, 0, 1, 1);
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,127));
-       }
+       ctx.fillStyle = "white";
+       ctx.fillRect(0,0,1,1);
+       comparePixel(ctx,0,0,255,255,255,255);
+   }
+   function test_rgba(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = "rgb(-100, 300, 255)";
+       compare(ctx.fillStyle, "#00ffff");
+       ctx.fillStyle = "rgba(-100, 300, 255, 0.0)";
+       compare(ctx.fillStyle, "rgba(0, 255, 255, 0.0)");
+       ctx.fillStyle = "rgb(-10%, 110%, 50%)";
+       compare(ctx.fillStyle, "#00ff80");
 
-       function test_hsla() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = "hsla(120, 100%, 50%, 0.499)";
-           ctx.fillRect(0, 0, 1, 1);
-           verify(Helper.comparePixel(ctx,0,0,0,255,0,127));
-       }
+       ctx.clearRect(0, 0, 1, 1);
+       ctx.fillStyle = 'rgba(0%, 100%, 0%, 0.499)';
+       ctx.fillRect(0, 0, 1, 1);
+       comparePixel(ctx, 0,0, 0,255,0,127);
+   }
 
+   function test_hsla(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = "hsla(120, 100%, 50%, 0.499)";
+       ctx.fillRect(0, 0, 1, 1);
+       comparePixel(ctx,0,0,0,255,0,127);
    }
 }
index 0819781..ce1c27c 100644 (file)
@@ -1,26 +1,21 @@
 import QtQuick 2.0
-import QtTest 1.0
 
-Canvas {
-   id:canvas; width:1;height:1;
-   renderTarget:Canvas.Image
-   renderStrategy: Canvas.Immediate
+CanvasTestCase {
+   id:testCase
+   name: "fillRect"
+   function init_data() { return testData("2d"); }
+   function test_fillRect(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.fillStyle = "red";
+       ctx.fillRect(0, 0, canvas.width, canvas.height);
+       var imageData = ctx.getImageData(0, 0, 1, 1);
+       var d = imageData.data;
+       compare(d.length, 4);
+       compare(d[0], 255);
+       compare(d[1], 0);
+       compare(d[2], 0);
+       compare(d[3], 255);
+  }
 
-   TestCase {
-       name: "FillRect"; when: canvas.available
-
-       function test_fillRect() {
-           var ctx = canvas.getContext('2d');
-           ctx.fillStyle = "red";
-           ctx.fillRect(0, 0, canvas.width, canvas.height);
-
-           var imageData = ctx.getImageData(0, 0, 1, 1);
-           var d = imageData.data;
-           verify(d.length == 4);
-           verify(d[0] == 255);
-           verify(d[1] == 0);
-           verify(d[2] == 0);
-           verify(d[3] == 255);
-      }
-   }
 }
index 10ee6a6..00a12f2 100644 (file)
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       name: "gradient"; when: windowShown
-       function test_basic() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           var g = ctx.createLinearGradient(0, 0, 0, 50);
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
 
+CanvasTestCase {
+   id:testCase
+   name: "gradient"
+   function init_data() { return testData("2d"); }
+   function test_basic(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       var g = ctx.createLinearGradient(0, 0, 0, 50);
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 0,255,0,255,2);
+   }
+
+   function test_interpolate(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#ff0';
+       ctx.fillRect(0, 0, 100, 50);
+       var g = ctx.createLinearGradient(0, 0, 100, 0);
+       g.addColorStop(0, 'rgba(0,0,255, 0)');
+       g.addColorStop(1, 'rgba(0,0,255, 1)');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 25,25, 191,191,63,255,3);
+       //comparePixel(ctx, 50,25, 127,127,127,255,3);
+       //comparePixel(ctx, 75,25, 63,63,191,255,3);
+
+       ctx.reset();
+       var g = ctx.createLinearGradient(0, 0, 100, 0);
+       g.addColorStop(0, '#ff0');
+       g.addColorStop(1, '#00f');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 25,25, 191,191,63,255,3);
+       //comparePixel(ctx, 50,25, 127,127,127,255,3);
+       //comparePixel(ctx, 75,25, 63,63,191,255,3);
+
+
+       ctx.reset();
+       var g = ctx.createLinearGradient(0, 0, 100, 0);
+       g.addColorStop(0, 'rgba(255,255,0, 0)');
+       g.addColorStop(1, 'rgba(0,0,255, 1)');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 25,25, 191,191,63,63,3);
+       //comparePixel(ctx, 50,25, 127,127,127,127,3);
+       //comparePixel(ctx, 75,25, 63,63,191,191,3);
+
+       ctx.reset();
+       canvas.width = 200;
+       var g = ctx.createLinearGradient(0, 0, 200, 0);
+       g.addColorStop(0, '#ff0');
+       g.addColorStop(0.5, '#0ff');
+       g.addColorStop(1, '#f0f');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 200, 50);
+       //comparePixel(ctx, 50,25, 127,255,127,255,3);
+       //comparePixel(ctx, 100,25, 0,255,255,255,3);
+       //comparePixel(ctx, 150,25, 127,127,255,255,3);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       var g = ctx.createLinearGradient(25, 0, 75, 0);
+       g.addColorStop(0.4, '#0f0');
+       g.addColorStop(0.6, '#0f0');
+
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 20,25, 0,255,0,255,2);
+       //comparePixel(ctx, 50,25, 0,255,0,255,2);
+       //comparePixel(ctx, 80,25, 0,255,0,255,2);
+
+
+       ctx.reset();
+       ctx.canvas.width = 200;
+       var g = ctx.createLinearGradient(0, 0, 200, 0);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(0, '#ff0');
+       g.addColorStop(0.25, '#00f');
+       g.addColorStop(0.25, '#0f0');
+       g.addColorStop(0.25, '#0f0');
+       g.addColorStop(0.25, '#0f0');
+       g.addColorStop(0.25, '#ff0');
+       g.addColorStop(0.5, '#00f');
+       g.addColorStop(0.5, '#0f0');
+       g.addColorStop(0.75, '#00f');
+       g.addColorStop(0.75, '#f00');
+       g.addColorStop(0.75, '#ff0');
+       g.addColorStop(0.5, '#0f0');
+       g.addColorStop(0.5, '#0f0');
+       g.addColorStop(0.5, '#ff0');
+       g.addColorStop(1, '#00f');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 200, 50);
+       //comparePixel(ctx, 49,25, 0,0,255,255,16);
+       //comparePixel(ctx, 51,25, 255,255,0,255,16);
+       //comparePixel(ctx, 99,25, 0,0,255,255,16);
+       //comparePixel(ctx, 101,25, 255,255,0,255,16);
+       //comparePixel(ctx, 149,25, 0,0,255,255,16);
+       //comparePixel(ctx, 151,25, 255,255,0,255,16);
+       ctx.canvas.width = 100;
+
+       ctx.reset();
+       var g = ctx.createLinearGradient(0, 0, 100, 0);
+       var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ];
+       for (var p = 0; p < ps.length; ++p)
+       {
+               g.addColorStop(ps[p], '#0f0');
+               for (var i = 0; i < 15; ++i)
+                       g.addColorStop(ps[p], '#f00');
+               g.addColorStop(ps[p], '#0f0');
        }
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 1,25, 0,255,0,255);
+       //comparePixel(ctx, 30,25, 0,255,0,255);
+       //comparePixel(ctx, 40,25, 0,255,0,255);
+       //comparePixel(ctx, 60,25, 0,255,0,255);
+       //comparePixel(ctx, 80,25, 0,255,0,255);
 
-       function test_interpolate() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#ff0';
-           ctx.fillRect(0, 0, 100, 50);
-           var g = ctx.createLinearGradient(0, 0, 100, 0);
-           g.addColorStop(0, 'rgba(0,0,255, 0)');
-           g.addColorStop(1, 'rgba(0,0,255, 1)');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,255,3));
-           //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,3));
-           //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,255,3));
-
-           ctx.reset();
-           var g = ctx.createLinearGradient(0, 0, 100, 0);
-           g.addColorStop(0, '#ff0');
-           g.addColorStop(1, '#00f');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,255,3));
-           //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,3));
-           //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,255,3));
-
-
-           ctx.reset();
-           var g = ctx.createLinearGradient(0, 0, 100, 0);
-           g.addColorStop(0, 'rgba(255,255,0, 0)');
-           g.addColorStop(1, 'rgba(0,0,255, 1)');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,63,3));
-           //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,127,3));
-           //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,191,3));
-
-           ctx.reset();
-           canvas.width = 200;
-           var g = ctx.createLinearGradient(0, 0, 200, 0);
-           g.addColorStop(0, '#ff0');
-           g.addColorStop(0.5, '#0ff');
-           g.addColorStop(1, '#f0f');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 200, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 127,255,127,255,3));
-           //verify(Helper.comparePixel(ctx, 100,25, 0,255,255,255,3));
-           //verify(Helper.comparePixel(ctx, 150,25, 127,127,255,255,3));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           var g = ctx.createLinearGradient(25, 0, 75, 0);
-           g.addColorStop(0.4, '#0f0');
-           g.addColorStop(0.6, '#0f0');
-
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 20,25, 0,255,0,255,2));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
-           //verify(Helper.comparePixel(ctx, 80,25, 0,255,0,255,2));
-
-
-           ctx.reset();
-           ctx.canvas.width = 200;
-           var g = ctx.createLinearGradient(0, 0, 200, 0);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(0, '#ff0');
-           g.addColorStop(0.25, '#00f');
-           g.addColorStop(0.25, '#0f0');
-           g.addColorStop(0.25, '#0f0');
-           g.addColorStop(0.25, '#0f0');
-           g.addColorStop(0.25, '#ff0');
-           g.addColorStop(0.5, '#00f');
-           g.addColorStop(0.5, '#0f0');
-           g.addColorStop(0.75, '#00f');
-           g.addColorStop(0.75, '#f00');
-           g.addColorStop(0.75, '#ff0');
-           g.addColorStop(0.5, '#0f0');
-           g.addColorStop(0.5, '#0f0');
-           g.addColorStop(0.5, '#ff0');
-           g.addColorStop(1, '#00f');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 200, 50);
-           //verify(Helper.comparePixel(ctx, 49,25, 0,0,255,255,16));
-           //verify(Helper.comparePixel(ctx, 51,25, 255,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 99,25, 0,0,255,255,16));
-           //verify(Helper.comparePixel(ctx, 101,25, 255,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 149,25, 0,0,255,255,16));
-           //verify(Helper.comparePixel(ctx, 151,25, 255,255,0,255,16));
-           ctx.canvas.width = 100;
-
-           ctx.reset();
-           var g = ctx.createLinearGradient(0, 0, 100, 0);
-           var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ];
-           for (var p = 0; p < ps.length; ++p)
-           {
-                   g.addColorStop(ps[p], '#0f0');
-                   for (var i = 0; i < 15; ++i)
-                           g.addColorStop(ps[p], '#f00');
-                   g.addColorStop(ps[p], '#0f0');
-           }
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 30,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 40,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 60,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 80,25, 0,255,0,255));
-
-
-           ctx.reset();
-           var g = ctx.createLinearGradient(0, 0, 100, 0);
-           g.addColorStop(0, '#0f0');
-           g.addColorStop(1, '#0f0');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-
-
-
-           ctx.reset();
-           var g = ctx.createLinearGradient(0, 0, 0, 50);
-           g.addColorStop(0, '#ff0');
-           g.addColorStop(1, '#00f');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,12, 191,191,63,255,10));
-           //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,5));
-           //verify(Helper.comparePixel(ctx, 50,37, 63,63,191,255,10));
-
-
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 40,20, 0,255,0,255,2));
 
+       ctx.reset();
+       var g = ctx.createLinearGradient(0, 0, 100, 0);
+       g.addColorStop(0, '#0f0');
+       g.addColorStop(1, '#0f0');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
 
 
-       }
-       function test_radial() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101);
-           g.addColorStop(0, '#0f0');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
-           g.addColorStop(0, '#0f0');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#0f0');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           var tol = 1; // tolerance to avoid antialiasing artifacts
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.fillStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(30+tol, 40);
-           ctx.lineTo(110, -20+tol);
-           ctx.lineTo(110, 100-tol);
-           ctx.fill();
-
-           g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
-           g.addColorStop(0, '#0f0');
-           g.addColorStop(1, '#0f0');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           var tol = 1; // tolerance to avoid antialiasing artifacts
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.fillStyle = '#0f0';
-           ctx.beginPath();
-           ctx.moveTo(30-tol, 40);
-           ctx.lineTo(110, -20-tol);
-           ctx.lineTo(110, 100+tol);
-           ctx.fill();
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#0f0');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200);
-           g.addColorStop(0, '#0f0');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#0f0');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(0.993, '#f00');
-           g.addColorStop(1, '#0f0');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1);
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1)"); }
-
-
-           ctx.reset();
-
-
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, NaN, 1, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, NaN, 1, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, NaN, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, NaN, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, NaN, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, NaN, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, 0, NaN, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, NaN, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, 0, 0, NaN);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, NaN)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity)"); }
-           try { var err = false;
-             ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity)"); }
-
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#0f0');
-           ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
-           g.addColorStop(0, '#0f0');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
-           g.addColorStop(0, '#0f0');
-           g.addColorStop(0.001, '#f00');
-           g.addColorStop(1, '#f00');ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(0.01, '#0f0');
-           g.addColorStop(0.99, '#0f0');g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-           ctx.reset();
-           g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
-           g.addColorStop(0, '#0f0');
-           g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.translate(50, 25);ctx.scale(10, 10);
-           ctx.fillRect(-5, -2.5, 10, 5);
-           //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-
-           ctx.reset();
-           ctx.translate(100, 0);
-           g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
-           g.addColorStop(0, '#0f0');g.addColorStop(0.5, '#0f0');
-           g.addColorStop(0.51, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;ctx.translate(-50, 25);
-           ctx.scale(10, 10);
-           ctx.fillRect(-5, -2.5, 10, 5);
-           //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-
-
-           ctx.reset();
-           g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
-           g.addColorStop(0, '#0f0');
-           g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);ctx.translate(50, 25);
-           ctx.scale(10, 10);
-           ctx.fillRect(-5, -2.5, 10, 5);
-           //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-
-
-      }
-       function test_linear() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           try { var err = false;
-             ctx.createLinearGradient(Infinity, 0, 1, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(-Infinity, 0, 1, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(-Infinity, 0, 1, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(NaN, 0, 1, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(NaN, 0, 1, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, Infinity, 1, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, -Infinity, 1, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, -Infinity, 1, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, NaN, 1, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, NaN, 1, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, 0, Infinity, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, 0, -Infinity, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, -Infinity, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, 0, NaN, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, NaN, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, 0, 1, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, Infinity)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, 0, 1, -Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, -Infinity)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, 0, 1, NaN);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, NaN)"); }
-           try { var err = false;
-             ctx.createLinearGradient(Infinity, Infinity, 1, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(Infinity, Infinity, Infinity, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createLinearGradient(Infinity, Infinity, 1, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, Infinity)"); }
-           try { var err = false;
-             ctx.createLinearGradient(Infinity, 0, Infinity, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(Infinity, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createLinearGradient(Infinity, 0, 1, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, Infinity)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, Infinity, Infinity, 0);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, 0)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, Infinity, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, Infinity)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, Infinity, 1, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, Infinity)"); }
-           try { var err = false;
-             ctx.createLinearGradient(0, 0, Infinity, Infinity);
-           } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, Infinity)"); }
-
-           ctx.reset();
-           var g = ctx.createLinearGradient(0, 0, 200, 0);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(0.25, '#0f0');
-           g.addColorStop(0.75, '#0f0');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.translate(-50, 0);
-           ctx.fillRect(50, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-
-           ctx.reset();
-           ctx.translate(100, 0);
-           g = ctx.createLinearGradient(0, 0, 200, 0);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(0.25, '#0f0');
-           g.addColorStop(0.75, '#0f0');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.translate(-150, 0);
-           ctx.fillRect(50, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-
-
-           ctx.reset();
-           g = ctx.createLinearGradient(0, 0, 200, 0);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(0.25, '#0f0');
-           g.addColorStop(0.75, '#0f0');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.translate(-50, 0);
-           ctx.fillRect(50, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-
-      }
-       function test_object() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           var g1 = ctx.createLinearGradient(0, 0, 100, 0);
-           var g2 = ctx.createLinearGradient(0, 0, 100, 0);
-           ctx.fillStyle = g1;
-
-
-           ctx.reset();
-           var g = ctx.createLinearGradient(0, 0, 100, 0);
-           try { var err = false;
-             g.addColorStop(0, "");
-           } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, \"\")"); }
-           try { var err = false;
-             g.addColorStop(0, 'undefined');
-           } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, 'undefined')"); }
-
-
-           ctx.reset();
-           g = ctx.createLinearGradient(0, 0, 100, 0);
-           try { var err = false;
-             g.addColorStop(-1, '#000');
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-1, '#000')"); }
-           try { var err = false;
-             g.addColorStop(2, '#000');
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(2, '#000')"); }
-           try { var err = false;
-             g.addColorStop(Infinity, '#000');
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(Infinity, '#000')"); }
-           try { var err = false;
-             g.addColorStop(-Infinity, '#000');
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-Infinity, '#000')"); }
-           try { var err = false;
-             g.addColorStop(NaN, '#000');
-           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(NaN, '#000')"); }
-
-
-           ctx.reset();
-           g = ctx.createLinearGradient(-100, 0, 200, 0);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           g.addColorStop(0.1, '#0f0');
-           g.addColorStop(0.9, '#0f0');
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100);
-           g.addColorStop(0, '#f00');
-           g.addColorStop(1, '#f00');
-           ctx.fillStyle = g;
-           ctx.fillRect(0, 0, 100, 50);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
-
-      }
-
-       function test_conical() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           var g = ctx.createConicalGradient(10, 10, 50);
-           //TODO
-       }
+
+       ctx.reset();
+       var g = ctx.createLinearGradient(0, 0, 0, 50);
+       g.addColorStop(0, '#ff0');
+       g.addColorStop(1, '#00f');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,12, 191,191,63,255,10);
+       //comparePixel(ctx, 50,25, 127,127,127,255,5);
+       //comparePixel(ctx, 50,37, 63,63,191,255,10);
+
+
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 40,20, 0,255,0,255,2);
+
+
+
+   }
+   function test_radial(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101);
+       g.addColorStop(0, '#0f0');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
+       g.addColorStop(0, '#0f0');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#0f0');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       var tol = 1; // tolerance to avoid antialiasing artifacts
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.fillStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(30+tol, 40);
+       ctx.lineTo(110, -20+tol);
+       ctx.lineTo(110, 100-tol);
+       ctx.fill();
+
+       g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+       g.addColorStop(0, '#0f0');
+       g.addColorStop(1, '#0f0');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       var tol = 1; // tolerance to avoid antialiasing artifacts
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.fillStyle = '#0f0';
+       ctx.beginPath();
+       ctx.moveTo(30-tol, 40);
+       ctx.lineTo(110, -20-tol);
+       ctx.lineTo(110, 100+tol);
+       ctx.fill();
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#0f0');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200);
+       g.addColorStop(0, '#0f0');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#0f0');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(0.993, '#f00');
+       g.addColorStop(1, '#0f0');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1)"); }
+
+
+       ctx.reset();
+
+
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, NaN, 1, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, NaN, 1, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, NaN, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, NaN, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, NaN, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, NaN, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, 0, NaN, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, NaN, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, 0, 0, NaN);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, NaN)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity)"); }
+       try { var err = false;
+         ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity)"); }
+
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#0f0');
+       ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);//comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);//comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+       g.addColorStop(0, '#0f0');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);//comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);//comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+       g.addColorStop(0, '#0f0');
+       g.addColorStop(0.001, '#f00');
+       g.addColorStop(1, '#f00');ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);//comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);//comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);//comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);//comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(0.01, '#0f0');
+       g.addColorStop(0.99, '#0f0');g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);//comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);//comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);//comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);//comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+       ctx.reset();
+       g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+       g.addColorStop(0, '#0f0');
+       g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.translate(50, 25);ctx.scale(10, 10);
+       ctx.fillRect(-5, -2.5, 10, 5);
+       //comparePixel(ctx, 25,25, 0,255,0,255);
+       //comparePixel(ctx, 50,25, 0,255,0,255);//comparePixel(ctx, 75,25, 0,255,0,255);
+
+       ctx.reset();
+       ctx.translate(100, 0);
+       g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+       g.addColorStop(0, '#0f0');g.addColorStop(0.5, '#0f0');
+       g.addColorStop(0.51, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;ctx.translate(-50, 25);
+       ctx.scale(10, 10);
+       ctx.fillRect(-5, -2.5, 10, 5);
+       //comparePixel(ctx, 25,25, 0,255,0,255);//comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 75,25, 0,255,0,255);
+
+
+       ctx.reset();
+       g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+       g.addColorStop(0, '#0f0');
+       g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);ctx.translate(50, 25);
+       ctx.scale(10, 10);
+       ctx.fillRect(-5, -2.5, 10, 5);
+       //comparePixel(ctx, 25,25, 0,255,0,255);//comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 75,25, 0,255,0,255);
+
+
+  }
+   function test_linear(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       try { var err = false;
+         ctx.createLinearGradient(Infinity, 0, 1, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(-Infinity, 0, 1, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(-Infinity, 0, 1, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(NaN, 0, 1, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(NaN, 0, 1, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, Infinity, 1, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, -Infinity, 1, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, -Infinity, 1, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, NaN, 1, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, NaN, 1, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, 0, Infinity, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, 0, -Infinity, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, -Infinity, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, 0, NaN, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, NaN, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, 0, 1, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, Infinity)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, 0, 1, -Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, -Infinity)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, 0, 1, NaN);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, NaN)"); }
+       try { var err = false;
+         ctx.createLinearGradient(Infinity, Infinity, 1, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(Infinity, Infinity, Infinity, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createLinearGradient(Infinity, Infinity, 1, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, Infinity)"); }
+       try { var err = false;
+         ctx.createLinearGradient(Infinity, 0, Infinity, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(Infinity, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createLinearGradient(Infinity, 0, 1, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, Infinity)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, Infinity, Infinity, 0);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, 0)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, Infinity, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, Infinity)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, Infinity, 1, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, Infinity)"); }
+       try { var err = false;
+         ctx.createLinearGradient(0, 0, Infinity, Infinity);
+       } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, Infinity)"); }
+
+       ctx.reset();
+       var g = ctx.createLinearGradient(0, 0, 200, 0);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(0.25, '#0f0');
+       g.addColorStop(0.75, '#0f0');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.translate(-50, 0);
+       ctx.fillRect(50, 0, 100, 50);
+       comparePixel(ctx, 25,25, 0,255,0,255);
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       comparePixel(ctx, 75,25, 0,255,0,255);
+
+       ctx.reset();
+       ctx.translate(100, 0);
+       g = ctx.createLinearGradient(0, 0, 200, 0);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(0.25, '#0f0');
+       g.addColorStop(0.75, '#0f0');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.translate(-150, 0);
+       ctx.fillRect(50, 0, 100, 50);
+       comparePixel(ctx, 25,25, 0,255,0,255);
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       comparePixel(ctx, 75,25, 0,255,0,255);
+
+
+       ctx.reset();
+       g = ctx.createLinearGradient(0, 0, 200, 0);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(0.25, '#0f0');
+       g.addColorStop(0.75, '#0f0');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.translate(-50, 0);
+       ctx.fillRect(50, 0, 100, 50);
+
+       if (canvas.renderTarget === Canvas.Image) //FIXME:broken on FramebufferObject
+           comparePixel(ctx, 25,25, 0,255,0,255);
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       comparePixel(ctx, 75,25, 0,255,0,255);
+
+  }
+   function test_object(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+       var g2 = ctx.createLinearGradient(0, 0, 100, 0);
+       ctx.fillStyle = g1;
+
+
+       ctx.reset();
+       var g = ctx.createLinearGradient(0, 0, 100, 0);
+       try { var err = false;
+         g.addColorStop(0, "");
+       } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, \"\")"); }
+       try { var err = false;
+         g.addColorStop(0, 'undefined');
+       } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, 'undefined')"); }
+
+
+       ctx.reset();
+       g = ctx.createLinearGradient(0, 0, 100, 0);
+       try { var err = false;
+         g.addColorStop(-1, '#000');
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-1, '#000')"); }
+       try { var err = false;
+         g.addColorStop(2, '#000');
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(2, '#000')"); }
+       try { var err = false;
+         g.addColorStop(Infinity, '#000');
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(Infinity, '#000')"); }
+       try { var err = false;
+         g.addColorStop(-Infinity, '#000');
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-Infinity, '#000')"); }
+       try { var err = false;
+         g.addColorStop(NaN, '#000');
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(NaN, '#000')"); }
+
+
+       ctx.reset();
+       g = ctx.createLinearGradient(-100, 0, 200, 0);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       g.addColorStop(0.1, '#0f0');
+       g.addColorStop(0.9, '#0f0');
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 0,255,0,255,2);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100);
+       g.addColorStop(0, '#f00');
+       g.addColorStop(1, '#f00');
+       ctx.fillStyle = g;
+       ctx.fillRect(0, 0, 100, 50);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 50,1, 0,255,0,255);
+       //comparePixel(ctx, 98,1, 0,255,0,255);
+       //comparePixel(ctx, 1,25, 0,255,0,255,16);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 98,25, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       //comparePixel(ctx, 50,48, 0,255,0,255);
+       //comparePixel(ctx, 98,48, 0,255,0,255);
+
+
+  }
+
+   function test_conical(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       var g = ctx.createConicalGradient(10, 10, 50);
+       //TODO
    }
 }
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
new file mode 100644 (file)
index 0000000..5853c03
--- /dev/null
@@ -0,0 +1,695 @@
+import QtQuick 2.0
+
+CanvasTestCase {
+   id:testCase
+   name: "image"
+   function init_data() { return testData("2d"); }
+
+   function loadImages(canvas) {
+       canvas.loadImage('green.png');
+       canvas.loadImage('red.png');
+       canvas.loadImage('rgrg-256x256.png');
+       canvas.loadImage('ggrr-256x256.png');
+       canvas.loadImage('broken.png');
+       if (!canvas.isImageLoaded('green.png'))
+          wait(200);
+   }
+
+   function test_3args(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+       ctx.reset();
+
+       ctx.drawImage('green.png', 0, 0);
+       ctx.drawImage('red.png', -100, 0);
+       ctx.drawImage('red.png', 100, 0);
+       ctx.drawImage('red.png', 0, -50);
+       ctx.drawImage('red.png', 0, 50);
+
+       comparePixel(ctx, 0,0, 0,255,0,255,2);
+       comparePixel(ctx, 99,0, 0,255,0,255,2);
+       comparePixel(ctx, 0,49, 0,255,0,255,2);
+       comparePixel(ctx, 99,49, 0,255,0,255,2);
+
+  }
+   function test_5args(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.drawImage('green.png', 50, 0, 50, 50);
+       ctx.drawImage('red.png', 0, 0, 50, 50);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 50, 50);
+
+       comparePixel(ctx, 0,0, 0,255,0,255,2);
+       comparePixel(ctx, 99,0, 0,255,0,255,2);
+       comparePixel(ctx, 0,49, 0,255,0,255,2);
+       comparePixel(ctx, 99,49, 0,255,0,255,2);
+
+  }
+   function test_9args(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50);
+       comparePixel(ctx, 0,0, 0,255,0,255,2);
+       comparePixel(ctx, 99,0, 0,255,0,255,2);
+       comparePixel(ctx, 0,49, 0,255,0,255,2);
+       comparePixel(ctx, 99,49, 0,255,0,255,2);
+
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50);
+       ctx.drawImage('red.png', 0, 0, 100, 50, -100, 0, 100, 50);
+       ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 100, 50);
+       ctx.drawImage('red.png', 0, 0, 100, 50, 0, -50, 100, 50);
+       ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 50);
+       comparePixel(ctx, 0,0, 0,255,0,255,2);
+       comparePixel(ctx, 99,0, 0,255,0,255,2);
+       comparePixel(ctx, 0,49, 0,255,0,255,2);
+       comparePixel(ctx, 99,49, 0,255,0,255,2);
+
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.drawImage('green.png', 1, 1, 1, 1, 0, 0, 100, 50);
+       ctx.drawImage('red.png', 0, 0, 100, 50, -50, 0, 50, 50);
+       ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 50, 50);
+       ctx.drawImage('red.png', 0, 0, 100, 50, 0, -25, 100, 25);
+       ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 25);
+       comparePixel(ctx, 0,0, 0,255,0,255,2);
+       comparePixel(ctx, 99,0, 0,255,0,255,2);
+       comparePixel(ctx, 0,49, 0,255,0,255,2);
+       comparePixel(ctx, 99,49, 0,255,0,255,2);
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.drawImage('rgrg-256x256.png', 140, 20, 100, 50, 0, 0, 100, 50);
+       comparePixel(ctx, 0,0, 0,255,0,255,2);
+       comparePixel(ctx, 99,0, 0,255,0,255,2);
+       comparePixel(ctx, 0,49, 0,255,0,255,2);
+       comparePixel(ctx, 99,49, 0,255,0,255,2);
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.drawImage('rgrg-256x256.png', 0, 0, 256, 256, 0, 0, 100, 50);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 51, 26);
+       ctx.fillRect(49, 24, 51, 26);
+       comparePixel(ctx, 0,0, 0,255,0,255,2);
+       comparePixel(ctx, 99,0, 0,255,0,255,2);
+       comparePixel(ctx, 0,49, 0,255,0,255,2);
+       comparePixel(ctx, 99,49, 0,255,0,255,2);
+       comparePixel(ctx, 20,20, 0,255,0,255,2);
+       comparePixel(ctx, 80,20, 0,255,0,255,2);
+       comparePixel(ctx, 20,30, 0,255,0,255,2);
+       comparePixel(ctx, 80,30, 0,255,0,255,2);
+
+   }
+   function test_animated(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       //should animated image be supported at all?
+  }
+   function test_clip(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.rect(-10, -10, 1, 1);
+       ctx.clip();
+       ctx.drawImage('red.png', 0, 0);
+       comparePixel(ctx, 50,25, 0,255,0,255,2);
+
+
+  }
+   function test_self(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 50, 50);
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(50, 0, 50, 50);
+       ctx.drawImage(canvas, 50, 0);
+
+       comparePixel(ctx, 0,0, 0,255,0,255,2);
+       comparePixel(ctx, 99,0, 0,255,0,255,2);
+       comparePixel(ctx, 0,49, 0,255,0,255,2);
+       comparePixel(ctx, 99,49, 0,255,0,255,2);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 1, 100, 49);
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 1);
+       ctx.drawImage(canvas, 0, 1);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 2);
+
+       comparePixel(ctx, 0,0, 0,255,0,255,2);
+       comparePixel(ctx, 99,0, 0,255,0,255,2);
+       comparePixel(ctx, 0,49, 0,255,0,255,2);
+       comparePixel(ctx, 99,49, 0,255,0,255,2);
+   }
+
+   function test_outsidesource(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+
+       ctx.drawImage('green.png', 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50);
+       ctx.drawImage('green.png', 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50);
+       ctx.drawImage('green.png', 100, 50, -5, -5, 0, 0, 100, 50);
+       try { var err = false;
+         ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50)"); }
+       try { var err = false;
+         ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50)"); }
+       try { var err = false;
+         ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50)"); }
+       try { var err = false;
+         ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50)"); }
+       try { var err = false;
+         ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50)"); }
+       try { var err = false;
+         ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50)"); }
+       try { var err = false;
+         ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50);
+       } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50)"); }
+//           try { var err = false;
+//             ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50);
+//           } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50)"); }
+//           comparePixel(ctx, 50,25, 0,255,0,255,2);
+
+   }
+
+   function test_null(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       try { var err = false;
+         ctx.drawImage(null, 0, 0);
+       } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(null, 0, 0)"); }
+
+   }
+
+   function test_composite(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalCompositeOperation = 'destination-over';
+       ctx.drawImage('red.png', 0, 0);
+       comparePixel(ctx, 50,25, 0,255,0,255,2);
+
+  }
+   function test_path(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+  }
+   function test_transform(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.translate(100, 0);
+       ctx.drawImage('red.png', 0, 0);
+       comparePixel(ctx, 50,25, 0,255,0,255,2);
+
+  }
+
+   function test_imageitem(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       //TODO
+   }
+
+   function test_imageData(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       //TODO
+   }
+
+   function test_wrongtype(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+
+       try { var err = false;
+         ctx.drawImage(undefined, 0, 0);
+       } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(undefined, 0, 0)"); }
+       try { var err = false;
+         ctx.drawImage(0, 0, 0);
+       } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(0, 0, 0)"); }
+       try { var err = false;
+         ctx.drawImage("", 0, 0);
+       } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(\"\", 0, 0)"); }
+   }
+
+   function test_nonfinite(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       var red = 'red.png';
+       ctx.drawImage(red, Infinity, 0);
+       ctx.drawImage(red, -Infinity, 0);
+       ctx.drawImage(red, NaN, 0);
+       ctx.drawImage(red, 0, Infinity);
+       ctx.drawImage(red, 0, -Infinity);
+       ctx.drawImage(red, 0, NaN);
+       ctx.drawImage(red, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50);
+       ctx.drawImage(red, -Infinity, 0, 100, 50);
+       ctx.drawImage(red, NaN, 0, 100, 50);
+       ctx.drawImage(red, 0, Infinity, 100, 50);
+       ctx.drawImage(red, 0, -Infinity, 100, 50);
+       ctx.drawImage(red, 0, NaN, 100, 50);
+       ctx.drawImage(red, 0, 0, Infinity, 50);
+       ctx.drawImage(red, 0, 0, -Infinity, 50);
+       ctx.drawImage(red, 0, 0, NaN, 50);
+       ctx.drawImage(red, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, -Infinity);
+       ctx.drawImage(red, 0, 0, 100, NaN);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, -Infinity, 0, 100, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, NaN, 0, 100, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, -Infinity, 100, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, NaN, 100, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, -Infinity, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, NaN, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, -Infinity, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, NaN, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, -Infinity, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, NaN, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, -Infinity, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, NaN, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, 0, -Infinity, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, 0, NaN, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, -Infinity);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, NaN);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, 50);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, 50);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, 50);
+       ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, 50);
+       ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, 50);
+       ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, 50);
+       ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, 50);
+       ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, 50);
+       ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, 50);
+       ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, 50);
+       ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, 50);
+       ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, 50);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, Infinity);
+       ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, Infinity);
+       comparePixel(ctx, 50,25, 0,255,0,255);
+
+   }
+
+   function test_negative(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.drawImage('ggrr-256x256.png', 100, 78, 50, 50, 0, 50, 50, -50);
+       ctx.drawImage('ggrr-256x256.png', 100, 128, 50, -50, 100, 50, -50, -50);
+//           comparePixel(ctx, 1,1, 0,255,0,255,2);
+//           comparePixel(ctx, 1,48, 0,255,0,255,2);
+//           comparePixel(ctx, 98,1, 0,255,0,255,2);
+//           comparePixel(ctx, 98,48, 0,255,0,255,2);
+//           comparePixel(ctx, 48,1, 0,255,0,255,2);
+//           comparePixel(ctx, 48,48, 0,255,0,255,2);
+//           comparePixel(ctx, 51,1, 0,255,0,255,2);
+//           comparePixel(ctx, 51,48, 0,255,0,255,2);
+//           comparePixel(ctx, 25,25, 0,255,0,255,2);
+//           comparePixel(ctx, 75,25, 0,255,0,255,2);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.drawImage('ggrr-256x256.png', 0, 178, 50, -100, 0, 0, 50, 100);
+       ctx.drawImage('ggrr-256x256.png', 0, 78, 50, 100, 50, 100, 50, -100);
+//           comparePixel(ctx, 1,1, 0,255,0,255,2);
+//           comparePixel(ctx, 1,48, 0,255,0,255,2);
+//           comparePixel(ctx, 98,1, 0,255,0,255,2);
+//           comparePixel(ctx, 98,48, 0,255,0,255,2);
+//           comparePixel(ctx, 48,1, 0,255,0,255,2);
+//           comparePixel(ctx, 48,48, 0,255,0,255,2);
+//           comparePixel(ctx, 51,1, 0,255,0,255,2);
+//           comparePixel(ctx, 51,48, 0,255,0,255,2);
+//           comparePixel(ctx, 25,25, 0,255,0,255,2);
+//           comparePixel(ctx, 75,25, 0,255,0,255,2);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.drawImage('ggrr-256x256.png', 100, 78, -100, 50, 0, 0, 50, 50);
+       ctx.drawImage('ggrr-256x256.png', 100, 128, -100, -50, 50, 0, 50, 50);
+//           comparePixel(ctx, 1,1, 0,255,0,255,2);
+//           comparePixel(ctx, 1,48, 0,255,0,255,2);
+//           comparePixel(ctx, 98,1, 0,255,0,255,2);
+//           comparePixel(ctx, 98,48, 0,255,0,255,2);
+//           comparePixel(ctx, 48,1, 0,255,0,255,2);
+//           comparePixel(ctx, 48,48, 0,255,0,255,2);
+//           comparePixel(ctx, 51,1, 0,255,0,255,2);
+//           comparePixel(ctx, 51,48, 0,255,0,255,2);
+//           comparePixel(ctx, 25,25, 0,255,0,255,2);
+//           comparePixel(ctx, 75,25, 0,255,0,255,2);
+
+   }
+
+   function test_canvas(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       var canvas2 = Qt.createQmlObject("import QtQuick 2.0; Canvas{renderTarget:Canvas.Image}", canvas);
+       canvas2.width = 100;
+       canvas2.height = 50;
+       var ctx2 = canvas2.getContext('2d');
+       ctx2.fillStyle = '#0f0';
+       ctx2.fillRect(0, 0, 100, 50);
+
+       ctx.fillStyle = '#f00';
+       ctx.drawImage(canvas2, 0, 0);
+
+       //comparePixel(ctx, 0,0, 0,255,0,255,2);
+       //comparePixel(ctx, 99,0, 0,255,0,255,2);
+       //comparePixel(ctx, 0,49, 0,255,0,255,2);
+       //comparePixel(ctx, 99,49, 0,255,0,255,2);
+
+   }
+
+   function test_broken(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       var img = 'broken.png';
+       verify(!img.complete);
+       ctx.drawImage(img, 0, 0);
+   }
+
+   function test_alpha(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       loadImages(canvas);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.globalAlpha = 0;
+       ctx.drawImage('red.png', 0, 0);
+       comparePixel(ctx, 50,25, 0,255,0,255, 2);
+
+   }
+}
index f1c2820..750f376 100644 (file)
 import QtQuick 2.0
-import QtTest 1.0
-import"testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50;renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       name: "line"; when: windowShown
-       function test_default() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           compare(ctx.lineWidth, 1);
-           compare(ctx.lineCap, 'butt');
-           compare(ctx.lineJoin, 'miter');
-           compare(ctx.miterLimit, 10);
-       }
-
-       function test_cross() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineWidth = 200;
-           ctx.lineJoin = 'bevel';
 
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(110, 50);
-           ctx.lineTo(110, 60);
-           ctx.lineTo(100, 60);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+CanvasTestCase {
+   id:testCase
+   name: "line"
+   function init_data() { return testData("2d"); }
+   function test_default(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       compare(ctx.lineWidth, 1);
+       compare(ctx.lineCap, 'butt');
+       compare(ctx.lineJoin, 'miter');
+       compare(ctx.miterLimit, 10);
+   }
 
+   function test_cross(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineWidth = 200;
+       ctx.lineJoin = 'bevel';
+
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(110, 50);
+       ctx.lineTo(110, 60);
+       ctx.lineTo(100, 60);
+       ctx.stroke();
+
+       comparePixel(ctx, 1,1, 0,255,0,255);
+       comparePixel(ctx, 48,1, 0,255,0,255);
+       comparePixel(ctx, 1,48, 0,255,0,255);
+
+       if (canvas.renderTarget === Canvas.Image) {
+           //FIXME: broken for Canvas.FramebufferObject
+            comparePixel(ctx, 48,48, 0,255,0,255);
        }
+   }
 
-       function test_join() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           var tol = 1; // tolerance to avoid antialiasing artifacts
-
-           ctx.lineJoin = 'bevel';
-           ctx.lineWidth = 20;
-
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-
-           ctx.fillRect(10, 10, 20, 20);
-           ctx.fillRect(20, 20, 20, 20);
-           ctx.beginPath();
-           ctx.moveTo(30, 20);
-           ctx.lineTo(40-tol, 20);
-           ctx.lineTo(30, 10+tol);
-           ctx.fill();
-
-           ctx.beginPath();
-           ctx.moveTo(10, 20);
-           ctx.lineTo(30, 20);
-           ctx.lineTo(30, 40);
-           ctx.stroke();
+   function test_join(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       var tol = 1; // tolerance to avoid antialiasing artifacts
+
+       ctx.lineJoin = 'bevel';
+       ctx.lineWidth = 20;
+
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+
+       ctx.fillRect(10, 10, 20, 20);
+       ctx.fillRect(20, 20, 20, 20);
+       ctx.beginPath();
+       ctx.moveTo(30, 20);
+       ctx.lineTo(40-tol, 20);
+       ctx.lineTo(30, 10+tol);
+       ctx.fill();
 
+       ctx.beginPath();
+       ctx.moveTo(10, 20);
+       ctx.lineTo(30, 20);
+       ctx.lineTo(30, 40);
+       ctx.stroke();
 
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
 
-           ctx.beginPath();
-           ctx.moveTo(60, 20);
-           ctx.lineTo(80, 20);
-           ctx.lineTo(80, 40);
-           ctx.stroke();
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+
+       ctx.beginPath();
+       ctx.moveTo(60, 20);
+       ctx.lineTo(80, 20);
+       ctx.lineTo(80, 40);
+       ctx.stroke();
 
-           ctx.fillRect(60, 10, 20, 20);
-           ctx.fillRect(70, 20, 20, 20);
-           ctx.beginPath();
-           ctx.moveTo(80, 20);
-           ctx.lineTo(90+tol, 20);
-           ctx.lineTo(80, 10-tol);
-           ctx.fill();
+       ctx.fillRect(60, 10, 20, 20);
+       ctx.fillRect(70, 20, 20, 20);
+       ctx.beginPath();
+       ctx.moveTo(80, 20);
+       ctx.lineTo(90+tol, 20);
+       ctx.lineTo(80, 10-tol);
+       ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 34,16, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 34,15, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 35,15, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 36,15, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 36,14, 0,255,0,255));
+       comparePixel(ctx, 34,16, 0,255,0,255);
+       comparePixel(ctx, 34,15, 0,255,0,255);
+       comparePixel(ctx, 35,15, 0,255,0,255);
+       comparePixel(ctx, 36,15, 0,255,0,255);
+       comparePixel(ctx, 36,14, 0,255,0,255);
 
-           verify(Helper.comparePixel(ctx, 84,16, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 84,15, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 85,15, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 86,15, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 86,14, 0,255,0,255));
-
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx, 84,16, 0,255,0,255);
+       comparePixel(ctx, 84,15, 0,255,0,255);
+       comparePixel(ctx, 85,15, 0,255,0,255);
+       comparePixel(ctx, 86,15, 0,255,0,255);
+       comparePixel(ctx, 86,14, 0,255,0,255);
+
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
 
-           ctx.lineJoin = 'miter';
-           ctx.lineWidth = 200;
-
-           ctx.beginPath();
-           ctx.moveTo(100, 50);
-           ctx.lineTo(100, 1000);
-           ctx.lineTo(1000, 1000);
-           ctx.lineTo(1000, 50);
-           ctx.closePath();
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-
-
-           ctx.reset();
-           ctx.lineJoin = 'bevel'
-           compare(ctx.lineJoin, 'bevel');
-
-           ctx.lineJoin = 'bevel';
-           ctx.lineJoin = 'invalid';
-           compare(ctx.lineJoin, 'bevel');
-
-           ctx.lineJoin = 'bevel';
-           ctx.lineJoin = 'ROUND';
-           compare(ctx.lineJoin, 'bevel');
-
-           ctx.lineJoin = 'bevel';
-           ctx.lineJoin = 'round\\0';
-           compare(ctx.lineJoin, 'bevel');
-
-           ctx.lineJoin = 'bevel';
-           ctx.lineJoin = 'round ';
-           compare(ctx.lineJoin, 'bevel');
-
-           ctx.lineJoin = 'bevel';
-           ctx.lineJoin = "";
-           compare(ctx.lineJoin, 'bevel');
-
-           ctx.lineJoin = 'bevel';
-           ctx.lineJoin = 'butt';
-           compare(ctx.lineJoin, 'bevel');
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineJoin = 'miter';
-           ctx.lineWidth = 20;
-
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-
-           ctx.fillRect(10, 10, 30, 20);
-           ctx.fillRect(20, 10, 20, 30);
-
-           ctx.beginPath();
-           ctx.moveTo(10, 20);
-           ctx.lineTo(30, 20);
-           ctx.lineTo(30, 40);
-           ctx.stroke();
-
-
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
-
-           ctx.beginPath();
-           ctx.moveTo(60, 20);
-           ctx.lineTo(80, 20);
-           ctx.lineTo(80, 40);
-           ctx.stroke();
-
-           ctx.fillRect(60, 10, 30, 20);
-           ctx.fillRect(70, 10, 20, 30);
-
-           verify(Helper.comparePixel(ctx, 38,12, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 39,11, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 40,10, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 41,9, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 42,8, 0,255,0,255));
-
-           verify(Helper.comparePixel(ctx, 88,12, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 89,11, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 91,9, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 92,8, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineJoin = 'miter';
-           ctx.lineWidth = 200;
-
-           ctx.beginPath();
-           ctx.moveTo(100, 50);
-           ctx.lineTo(100, 1000);
-           ctx.lineTo(1000, 1000);
-           ctx.lineTo(1000, 50);
-           ctx.lineTo(100, 50);
-           ctx.stroke();
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.strokeStyle = '#0f0';
-           ctx.lineWidth = 300;
-           ctx.lineJoin = 'round';
-           ctx.beginPath();
-           ctx.moveTo(-100, 25);
-           ctx.lineTo(0, 25);
-           ctx.lineTo(-100, 25);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           var tol = 1; // tolerance to avoid antialiasing artifacts
-
-           ctx.lineJoin = 'round';
-           ctx.lineWidth = 20;
-
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-
-           ctx.fillRect(10, 10, 20, 20);
-           ctx.fillRect(20, 20, 20, 20);
-           ctx.beginPath();
-           ctx.moveTo(30, 20);
-           ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true);
-           ctx.fill();
-
-           ctx.beginPath();
-           ctx.moveTo(10, 20);
-           ctx.lineTo(30, 20);
-           ctx.lineTo(30, 40);
-           ctx.stroke();
-
-
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
-
-           ctx.beginPath();
-           ctx.moveTo(60, 20);
-           ctx.lineTo(80, 20);
-           ctx.lineTo(80, 40);
-           ctx.stroke();
-
-           ctx.fillRect(60, 10, 20, 20);
-           ctx.fillRect(70, 20, 20, 20);
-           ctx.beginPath();
-           ctx.moveTo(80, 20);
-           ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true);
-           ctx.fill();
-
-           verify(Helper.comparePixel(ctx, 36,14, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 36,13, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 37,13, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 38,13, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 38,12, 0,255,0,255));
-
-           verify(Helper.comparePixel(ctx, 86,14, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 86,13, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 87,13, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 88,13, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 88,12, 0,255,0,255));
-
-           ctx.reset();
-           ctx.lineJoin = 'bevel'
-           compare(ctx.lineJoin, 'bevel');
-
-           ctx.lineJoin = 'round';
-           compare(ctx.lineJoin, 'round');
-
-           ctx.lineJoin = 'miter';
-           compare(ctx.lineJoin, 'miter');
+       ctx.lineJoin = 'miter';
+       ctx.lineWidth = 200;
+
+       ctx.beginPath();
+       ctx.moveTo(100, 50);
+       ctx.lineTo(100, 1000);
+       ctx.lineTo(1000, 1000);
+       ctx.lineTo(1000, 50);
+       ctx.closePath();
+       ctx.stroke();
+
+       comparePixel(ctx, 1,1, 0,255,0,255);
+       comparePixel(ctx, 48,1, 0,255,0,255);
+       comparePixel(ctx, 48,48, 0,255,0,255);
+       comparePixel(ctx, 1,48, 0,255,0,255);
+
+
+       ctx.reset();
+       ctx.lineJoin = 'bevel'
+       compare(ctx.lineJoin, 'bevel');
+
+       ctx.lineJoin = 'bevel';
+       ctx.lineJoin = 'invalid';
+       compare(ctx.lineJoin, 'bevel');
+
+       ctx.lineJoin = 'bevel';
+       ctx.lineJoin = 'ROUND';
+       compare(ctx.lineJoin, 'bevel');
+
+       ctx.lineJoin = 'bevel';
+       ctx.lineJoin = 'round\\0';
+       compare(ctx.lineJoin, 'bevel');
+
+       ctx.lineJoin = 'bevel';
+       ctx.lineJoin = 'round ';
+       compare(ctx.lineJoin, 'bevel');
+
+       ctx.lineJoin = 'bevel';
+       ctx.lineJoin = "";
+       compare(ctx.lineJoin, 'bevel');
+
+       ctx.lineJoin = 'bevel';
+       ctx.lineJoin = 'butt';
+       compare(ctx.lineJoin, 'bevel');
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineJoin = 'miter';
+       ctx.lineWidth = 20;
+
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+
+       ctx.fillRect(10, 10, 30, 20);
+       ctx.fillRect(20, 10, 20, 30);
+
+       ctx.beginPath();
+       ctx.moveTo(10, 20);
+       ctx.lineTo(30, 20);
+       ctx.lineTo(30, 40);
+       ctx.stroke();
+
+
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+
+       ctx.beginPath();
+       ctx.moveTo(60, 20);
+       ctx.lineTo(80, 20);
+       ctx.lineTo(80, 40);
+       ctx.stroke();
+
+       ctx.fillRect(60, 10, 30, 20);
+       ctx.fillRect(70, 10, 20, 30);
+
+       comparePixel(ctx, 38,12, 0,255,0,255);
+       comparePixel(ctx, 39,11, 0,255,0,255);
+       comparePixel(ctx, 40,10, 0,255,0,255);
+       comparePixel(ctx, 41,9, 0,255,0,255);
+       comparePixel(ctx, 42,8, 0,255,0,255);
+
+       comparePixel(ctx, 88,12, 0,255,0,255);
+       comparePixel(ctx, 89,11, 0,255,0,255);
+       comparePixel(ctx, 90,10, 0,255,0,255);
+       comparePixel(ctx, 91,9, 0,255,0,255);
+       comparePixel(ctx, 92,8, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineJoin = 'miter';
+       ctx.lineWidth = 200;
+
+       ctx.beginPath();
+       ctx.moveTo(100, 50);
+       ctx.lineTo(100, 1000);
+       ctx.lineTo(1000, 1000);
+       ctx.lineTo(1000, 50);
+       ctx.lineTo(100, 50);
+       ctx.stroke();
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 48,1, 0,255,0,255);
+       //comparePixel(ctx, 48,48, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.strokeStyle = '#0f0';
+       ctx.lineWidth = 300;
+       ctx.lineJoin = 'round';
+       ctx.beginPath();
+       ctx.moveTo(-100, 25);
+       ctx.lineTo(0, 25);
+       ctx.lineTo(-100, 25);
+       ctx.stroke();
+
+       comparePixel(ctx, 1,1, 0,255,0,255);
+       comparePixel(ctx, 48,1, 0,255,0,255);
+       comparePixel(ctx, 48,48, 0,255,0,255);
+       comparePixel(ctx, 1,48, 0,255,0,255);
+
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       var tol = 1; // tolerance to avoid antialiasing artifacts
+
+       ctx.lineJoin = 'round';
+       ctx.lineWidth = 20;
+
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+
+       ctx.fillRect(10, 10, 20, 20);
+       ctx.fillRect(20, 20, 20, 20);
+       ctx.beginPath();
+       ctx.moveTo(30, 20);
+       ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true);
+       ctx.fill();
+
+       ctx.beginPath();
+       ctx.moveTo(10, 20);
+       ctx.lineTo(30, 20);
+       ctx.lineTo(30, 40);
+       ctx.stroke();
+
+
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+
+       ctx.beginPath();
+       ctx.moveTo(60, 20);
+       ctx.lineTo(80, 20);
+       ctx.lineTo(80, 40);
+       ctx.stroke();
+
+       ctx.fillRect(60, 10, 20, 20);
+       ctx.fillRect(70, 20, 20, 20);
+       ctx.beginPath();
+       ctx.moveTo(80, 20);
+       ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true);
+       ctx.fill();
+
+       comparePixel(ctx, 36,14, 0,255,0,255);
+       comparePixel(ctx, 36,13, 0,255,0,255);
+       comparePixel(ctx, 37,13, 0,255,0,255);
+       comparePixel(ctx, 38,13, 0,255,0,255);
+       comparePixel(ctx, 38,12, 0,255,0,255);
+
+       comparePixel(ctx, 86,14, 0,255,0,255);
+       comparePixel(ctx, 86,13, 0,255,0,255);
+       comparePixel(ctx, 87,13, 0,255,0,255);
+       comparePixel(ctx, 88,13, 0,255,0,255);
+       comparePixel(ctx, 88,12, 0,255,0,255);
+
+       ctx.reset();
+       ctx.lineJoin = 'bevel'
+       compare(ctx.lineJoin, 'bevel');
+
+       ctx.lineJoin = 'round';
+       compare(ctx.lineJoin, 'round');
+
+       ctx.lineJoin = 'miter';
+       compare(ctx.lineJoin, 'miter');
 
-       }
-       function test_miter() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineWidth = 200;
-           ctx.lineJoin = 'miter';
-
-           ctx.strokeStyle = '#0f0';
-           ctx.miterLimit = 2.614;
-           ctx.beginPath();
-           ctx.moveTo(100, 1000);
-           ctx.lineTo(100, 100);
-           ctx.lineTo(1000, 1000);
-           ctx.stroke();
-
-           ctx.strokeStyle = '#f00';
-           ctx.miterLimit = 2.613;
-           ctx.beginPath();
-           ctx.moveTo(100, 1000);
-           ctx.lineTo(100, 100);
-           ctx.lineTo(1000, 1000);
-           ctx.stroke();
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineWidth = 400;
-           ctx.lineJoin = 'miter';
-
-           ctx.strokeStyle = '#f00';
-           ctx.miterLimit = 1.414;
-           ctx.beginPath();
-           ctx.moveTo(200, 1000);
-           ctx.lineTo(200, 200);
-           ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case
-           ctx.stroke();
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.miterLimit = 1.5;
-           compare(ctx.miterLimit, 1.5);
-
-           ctx.miterLimit = 1.5;
-           ctx.miterLimit = 0;
-           compare(ctx.miterLimit, 1.5);
-
-           ctx.miterLimit = 1.5;
-           ctx.miterLimit = -1;
-           compare(ctx.miterLimit, 1.5);
-
-           ctx.miterLimit = 1.5;
-           ctx.miterLimit = Infinity;
-           compare(ctx.miterLimit, 1.5);
-
-           ctx.miterLimit = 1.5;
-           ctx.miterLimit = -Infinity;
-           compare(ctx.miterLimit, 1.5);
-
-           ctx.miterLimit = 1.5;
-           ctx.miterLimit = NaN;
-           compare(ctx.miterLimit, 1.5);
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineWidth = 200;
-           ctx.lineJoin = 'miter';
-
-           ctx.strokeStyle = '#f00';
-           ctx.miterLimit = 1.414;
-           ctx.beginPath();
-           ctx.strokeRect(100, 25, 200, 0);
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineWidth = 1600;
-           ctx.lineJoin = 'miter';
-
-           ctx.strokeStyle = '#0f0';
-           ctx.miterLimit = 1.083;
-           ctx.beginPath();
-           ctx.moveTo(800, 10000);
-           ctx.lineTo(800, 300);
-           ctx.lineTo(10000, -8900);
-           ctx.stroke();
-
-           ctx.strokeStyle = '#f00';
-           ctx.miterLimit = 1.082;
-           ctx.beginPath();
-           ctx.moveTo(800, 10000);
-           ctx.lineTo(800, 300);
-           ctx.lineTo(10000, -8900);
-           ctx.stroke();
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineWidth = 400;
-           ctx.lineJoin = 'miter';
-
-           ctx.strokeStyle = '#f00';
-           ctx.miterLimit = 1.414;
-           ctx.beginPath();
-           ctx.moveTo(200, 1000);
-           ctx.lineTo(200, 200);
-           ctx.lineTo(1000, 200);
-           ctx.stroke();
-
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-
-           ctx.reset();
-           ctx.miterLimit = 1.5;
-           compare(ctx.miterLimit, 1.5);
-
-           ctx.miterLimit = "1e1";
-           compare(ctx.miterLimit, 10);
-
-           ctx.miterLimit = 1/1024;
-           compare(ctx.miterLimit, 1/1024);
-
-           ctx.miterLimit = 1000;
-           compare(ctx.miterLimit, 1000);
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineWidth = 400;
-           ctx.lineJoin = 'miter';
-
-           ctx.strokeStyle = '#0f0';
-           ctx.miterLimit = 1.416;
-           ctx.beginPath();
-           ctx.moveTo(200, 1000);
-           ctx.lineTo(200, 200);
-           ctx.lineTo(1000, 201);
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+   }
+   function test_miter(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineWidth = 200;
+       ctx.lineJoin = 'miter';
+
+       ctx.strokeStyle = '#0f0';
+       ctx.miterLimit = 2.614;
+       ctx.beginPath();
+       ctx.moveTo(100, 1000);
+       ctx.lineTo(100, 100);
+       ctx.lineTo(1000, 1000);
+       ctx.stroke();
+
+       ctx.strokeStyle = '#f00';
+       ctx.miterLimit = 2.613;
+       ctx.beginPath();
+       ctx.moveTo(100, 1000);
+       ctx.lineTo(100, 100);
+       ctx.lineTo(1000, 1000);
+       ctx.stroke();
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 48,1, 0,255,0,255);
+       //comparePixel(ctx, 48,48, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineWidth = 400;
+       ctx.lineJoin = 'miter';
+
+       ctx.strokeStyle = '#f00';
+       ctx.miterLimit = 1.414;
+       ctx.beginPath();
+       ctx.moveTo(200, 1000);
+       ctx.lineTo(200, 200);
+       ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case
+       ctx.stroke();
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 48,1, 0,255,0,255);
+       //comparePixel(ctx, 48,48, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.miterLimit = 1.5;
+       compare(ctx.miterLimit, 1.5);
+
+       ctx.miterLimit = 1.5;
+       ctx.miterLimit = 0;
+       compare(ctx.miterLimit, 1.5);
+
+       ctx.miterLimit = 1.5;
+       ctx.miterLimit = -1;
+       compare(ctx.miterLimit, 1.5);
+
+       ctx.miterLimit = 1.5;
+       ctx.miterLimit = Infinity;
+       compare(ctx.miterLimit, 1.5);
+
+       ctx.miterLimit = 1.5;
+       ctx.miterLimit = -Infinity;
+       compare(ctx.miterLimit, 1.5);
+
+       ctx.miterLimit = 1.5;
+       ctx.miterLimit = NaN;
+       compare(ctx.miterLimit, 1.5);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineWidth = 200;
+       ctx.lineJoin = 'miter';
+
+       ctx.strokeStyle = '#f00';
+       ctx.miterLimit = 1.414;
+       ctx.beginPath();
+       ctx.strokeRect(100, 25, 200, 0);
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 48,1, 0,255,0,255);
+       //comparePixel(ctx, 48,48, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineWidth = 1600;
+       ctx.lineJoin = 'miter';
+
+       ctx.strokeStyle = '#0f0';
+       ctx.miterLimit = 1.083;
+       ctx.beginPath();
+       ctx.moveTo(800, 10000);
+       ctx.lineTo(800, 300);
+       ctx.lineTo(10000, -8900);
+       ctx.stroke();
+
+       ctx.strokeStyle = '#f00';
+       ctx.miterLimit = 1.082;
+       ctx.beginPath();
+       ctx.moveTo(800, 10000);
+       ctx.lineTo(800, 300);
+       ctx.lineTo(10000, -8900);
+       ctx.stroke();
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 48,1, 0,255,0,255);
+       //comparePixel(ctx, 48,48, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineWidth = 400;
+       ctx.lineJoin = 'miter';
+
+       ctx.strokeStyle = '#f00';
+       ctx.miterLimit = 1.414;
+       ctx.beginPath();
+       ctx.moveTo(200, 1000);
+       ctx.lineTo(200, 200);
+       ctx.lineTo(1000, 200);
+       ctx.stroke();
+
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 48,1, 0,255,0,255);
+       //comparePixel(ctx, 48,48, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+
+       ctx.reset();
+       ctx.miterLimit = 1.5;
+       compare(ctx.miterLimit, 1.5);
+
+       ctx.miterLimit = "1e1";
+       compare(ctx.miterLimit, 10);
+
+       ctx.miterLimit = 1/1024;
+       compare(ctx.miterLimit, 1/1024);
+
+       ctx.miterLimit = 1000;
+       compare(ctx.miterLimit, 1000);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineWidth = 400;
+       ctx.lineJoin = 'miter';
+
+       ctx.strokeStyle = '#0f0';
+       ctx.miterLimit = 1.416;
+       ctx.beginPath();
+       ctx.moveTo(200, 1000);
+       ctx.lineTo(200, 200);
+       ctx.lineTo(1000, 201);
+       ctx.stroke();
+
+       comparePixel(ctx, 1,1, 0,255,0,255);
+       comparePixel(ctx, 48,1, 0,255,0,255);
+       comparePixel(ctx, 48,48, 0,255,0,255);
+       comparePixel(ctx, 1,48, 0,255,0,255);
 
 
-       }
-       function test_width() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineWidth = 20;
-           // Draw a green line over a red box, to check the line is not too small
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-           ctx.fillRect(15, 15, 20, 20);
-           ctx.beginPath();
-           ctx.moveTo(25, 15);
-           ctx.lineTo(25, 35);
-           ctx.stroke();
-
-           // Draw a green box over a red line, to check the line is not too large
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(75, 15);
-           ctx.lineTo(75, 35);
-           ctx.stroke();
-           ctx.fillRect(65, 15, 20, 20);
-
-           verify(Helper.comparePixel(ctx, 14,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 15,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 16,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 34,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 35,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 36,25, 0,255,0,255));
-
-           verify(Helper.comparePixel(ctx, 64,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 65,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 66,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 84,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 85,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 86,25, 0,255,0,255));
-
-           ctx.reset();
-           ctx.lineWidth = 1.5;
-           compare(ctx.lineWidth, 1.5);
-
-           ctx.lineWidth = 1.5;
-           ctx.lineWidth = 0;
-           compare(ctx.lineWidth, 1.5);
-
-           ctx.lineWidth = 1.5;
-           ctx.lineWidth = -1;
-           compare(ctx.lineWidth, 1.5);
-
-           ctx.lineWidth = 1.5;
-           ctx.lineWidth = Infinity;
-           compare(ctx.lineWidth, 1.5);
-
-           ctx.lineWidth = 1.5;
-           ctx.lineWidth = -Infinity;
-           compare(ctx.lineWidth, 1.5);
-
-           ctx.lineWidth = 1.5;
-           ctx.lineWidth = NaN;
-           compare(ctx.lineWidth, 1.5);
-
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.scale(50, 50);
-           ctx.strokeStyle = '#0f0';
-           ctx.moveTo(0, 0.5);
-           ctx.lineTo(2, 0.5);
-           ctx.stroke();
-
-           //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,5, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,45, 0,255,0,255));
-
-           ctx.reset();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineWidth = 4;
-           // Draw a green line over a red box, to check the line is not too small
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-           ctx.fillRect(15, 15, 20, 20);
-           ctx.save();
-            ctx.scale(5, 1);
-            ctx.beginPath();
-            ctx.moveTo(5, 15);
-            ctx.lineTo(5, 35);
-            ctx.stroke();
-           ctx.restore();
-
-           // Draw a green box over a red line, to check the line is not too large
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
-           ctx.save();
-            ctx.scale(-5, 1);
-            ctx.beginPath();
-            ctx.moveTo(-15, 15);
-            ctx.lineTo(-15, 35);
-            ctx.stroke();
-           ctx.restore();
-           ctx.fillRect(65, 15, 20, 20);
-
-           verify(Helper.comparePixel(ctx, 14,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 15,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 16,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 34,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 35,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 36,25, 0,255,0,255));
-
-           //verify(Helper.comparePixel(ctx, 64,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 65,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 66,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 84,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 85,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 86,25, 0,255,0,255));
-
-           ctx.reset();
-           ctx.lineWidth = 1.5;
-           compare(ctx.lineWidth, 1.5);
-
-           ctx.lineWidth = "1e1";
-           compare(ctx.lineWidth, 10);
-
-           ctx.lineWidth = 1/1024;
-           compare(ctx.lineWidth, 1/1024);
-
-           ctx.lineWidth = 1000;
-           compare(ctx.lineWidth, 1000);
+   }
+   function test_width(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineWidth = 20;
+       // Draw a green line over a red box, to check the line is not too small
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+       ctx.fillRect(15, 15, 20, 20);
+       ctx.beginPath();
+       ctx.moveTo(25, 15);
+       ctx.lineTo(25, 35);
+       ctx.stroke();
+
+       // Draw a green box over a red line, to check the line is not too large
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(75, 15);
+       ctx.lineTo(75, 35);
+       ctx.stroke();
+       ctx.fillRect(65, 15, 20, 20);
+
+       comparePixel(ctx, 14,25, 0,255,0,255);
+       comparePixel(ctx, 15,25, 0,255,0,255);
+       comparePixel(ctx, 16,25, 0,255,0,255);
+       comparePixel(ctx, 25,25, 0,255,0,255);
+       comparePixel(ctx, 34,25, 0,255,0,255);
+       comparePixel(ctx, 35,25, 0,255,0,255);
+       comparePixel(ctx, 36,25, 0,255,0,255);
+
+       comparePixel(ctx, 64,25, 0,255,0,255);
+       comparePixel(ctx, 65,25, 0,255,0,255);
+       comparePixel(ctx, 66,25, 0,255,0,255);
+       comparePixel(ctx, 75,25, 0,255,0,255);
+       comparePixel(ctx, 84,25, 0,255,0,255);
+       comparePixel(ctx, 85,25, 0,255,0,255);
+       comparePixel(ctx, 86,25, 0,255,0,255);
+
+       ctx.reset();
+       ctx.lineWidth = 1.5;
+       compare(ctx.lineWidth, 1.5);
+
+       ctx.lineWidth = 1.5;
+       ctx.lineWidth = 0;
+       compare(ctx.lineWidth, 1.5);
+
+       ctx.lineWidth = 1.5;
+       ctx.lineWidth = -1;
+       compare(ctx.lineWidth, 1.5);
+
+       ctx.lineWidth = 1.5;
+       ctx.lineWidth = Infinity;
+       compare(ctx.lineWidth, 1.5);
+
+       ctx.lineWidth = 1.5;
+       ctx.lineWidth = -Infinity;
+       compare(ctx.lineWidth, 1.5);
+
+       ctx.lineWidth = 1.5;
+       ctx.lineWidth = NaN;
+       compare(ctx.lineWidth, 1.5);
+
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.scale(50, 50);
+       ctx.strokeStyle = '#0f0';
+       ctx.moveTo(0, 0.5);
+       ctx.lineTo(2, 0.5);
+       ctx.stroke();
+
+       //comparePixel(ctx, 25,25, 0,255,0,255);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       //comparePixel(ctx, 75,25, 0,255,0,255);
+       //comparePixel(ctx, 50,5, 0,255,0,255);
+       //comparePixel(ctx, 50,45, 0,255,0,255);
+
+       ctx.reset();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineWidth = 4;
+       // Draw a green line over a red box, to check the line is not too small
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+       ctx.fillRect(15, 15, 20, 20);
+       ctx.save();
+        ctx.scale(5, 1);
+        ctx.beginPath();
+        ctx.moveTo(5, 15);
+        ctx.lineTo(5, 35);
+        ctx.stroke();
+       ctx.restore();
+
+       // Draw a green box over a red line, to check the line is not too large
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+       ctx.save();
+        ctx.scale(-5, 1);
+        ctx.beginPath();
+        ctx.moveTo(-15, 15);
+        ctx.lineTo(-15, 35);
+        ctx.stroke();
+       ctx.restore();
+       ctx.fillRect(65, 15, 20, 20);
+
+       comparePixel(ctx, 14,25, 0,255,0,255);
+       //comparePixel(ctx, 15,25, 0,255,0,255);
+       //comparePixel(ctx, 16,25, 0,255,0,255);
+       //comparePixel(ctx, 25,25, 0,255,0,255);
+       //comparePixel(ctx, 34,25, 0,255,0,255);
+       //comparePixel(ctx, 35,25, 0,255,0,255);
+       //comparePixel(ctx, 36,25, 0,255,0,255);
+
+       //comparePixel(ctx, 64,25, 0,255,0,255);
+       //comparePixel(ctx, 65,25, 0,255,0,255);
+       //comparePixel(ctx, 66,25, 0,255,0,255);
+       //comparePixel(ctx, 75,25, 0,255,0,255);
+       //comparePixel(ctx, 84,25, 0,255,0,255);
+       //comparePixel(ctx, 85,25, 0,255,0,255);
+       //comparePixel(ctx, 86,25, 0,255,0,255);
+
+       ctx.reset();
+       ctx.lineWidth = 1.5;
+       compare(ctx.lineWidth, 1.5);
+
+       ctx.lineWidth = "1e1";
+       compare(ctx.lineWidth, 10);
+
+       ctx.lineWidth = 1/1024;
+       compare(ctx.lineWidth, 1/1024);
+
+       ctx.lineWidth = 1000;
+       compare(ctx.lineWidth, 1000);
 
-       }
-       function test_cap() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineCap = 'butt';
-           ctx.lineWidth = 20;
-
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-           ctx.fillRect(15, 15, 20, 20);
-           ctx.beginPath();
-           ctx.moveTo(25, 15);
-           ctx.lineTo(25, 35);
-           ctx.stroke();
-
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(75, 15);
-           ctx.lineTo(75, 35);
-           ctx.stroke();
-           ctx.fillRect(65, 15, 20, 20);
-
-           verify(Helper.comparePixel(ctx, 25,14, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,15, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,16, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,34, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,35, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,36, 0,255,0,255));
-
-           verify(Helper.comparePixel(ctx, 75,14, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,15, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,16, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,34, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,35, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,36, 0,255,0,255));
-
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineJoin = 'bevel';
-           ctx.lineCap = 'square';
-           ctx.lineWidth = 400;
-
-           ctx.beginPath();
-           ctx.moveTo(200, 200);
-           ctx.lineTo(200, 1000);
-           ctx.lineTo(1000, 1000);
-           ctx.lineTo(1000, 200);
-           ctx.closePath();
-           ctx.stroke();
-
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           ctx.reset();
-
-           ctx.lineCap = 'butt'
-           compare(ctx.lineCap, 'butt');
-
-           ctx.lineCap = 'butt';
-           ctx.lineCap = 'invalid';
-           compare(ctx.lineCap, 'butt');
-
-           ctx.lineCap = 'butt';
-           ctx.lineCap = 'ROUND';
-           compare(ctx.lineCap, 'butt');
-
-           ctx.lineCap = 'butt';
-           ctx.lineCap = 'round\\0';
-           compare(ctx.lineCap, 'butt');
-
-           ctx.lineCap = 'butt';
-           ctx.lineCap = 'round ';
-           compare(ctx.lineCap, 'butt');
-
-           ctx.lineCap = 'butt';
-           ctx.lineCap = "";
-           compare(ctx.lineCap, 'butt');
-
-           ctx.lineCap = 'butt';
-           ctx.lineCap = 'bevel';
-           compare(ctx.lineCap, 'butt');
-
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineJoin = 'bevel';
-           ctx.lineCap = 'square';
-           ctx.lineWidth = 400;
-
-           ctx.beginPath();
-           ctx.moveTo(200, 200);
-           ctx.lineTo(200, 1000);
-           ctx.lineTo(1000, 1000);
-           ctx.lineTo(1000, 200);
-           ctx.lineTo(200, 200);
-           ctx.stroke();
-
-           //FIXME:!!!
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           var tol = 1; // tolerance to avoid antialiasing artifacts
-
-           ctx.lineCap = 'round';
-           ctx.lineWidth = 20;
-
-
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-
-           ctx.beginPath();
-           ctx.moveTo(35-tol, 15);
-           ctx.arc(25, 15, 10-tol, 0, Math.PI, true);
-           ctx.arc(25, 35, 10-tol, Math.PI, 0, true);
-           ctx.fill();
-
-           ctx.beginPath();
-           ctx.moveTo(25, 15);
-           ctx.lineTo(25, 35);
-           ctx.stroke();
-
-
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
-
-           ctx.beginPath();
-           ctx.moveTo(75, 15);
-           ctx.lineTo(75, 35);
-           ctx.stroke();
-
-           ctx.beginPath();
-           ctx.moveTo(85+tol, 15);
-           ctx.arc(75, 15, 10+tol, 0, Math.PI, true);
-           ctx.arc(75, 35, 10+tol, Math.PI, 0, true);
-           ctx.fill();
-
-           verify(Helper.comparePixel(ctx, 17,6, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,6, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 32,6, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 17,43, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,43, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 32,43, 0,255,0,255));
-
-           verify(Helper.comparePixel(ctx, 67,6, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,6, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 82,6, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 67,43, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,43, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 82,43, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.lineCap = 'square';
-           ctx.lineWidth = 20;
-
-           ctx.fillStyle = '#f00';
-           ctx.strokeStyle = '#0f0';
-           ctx.fillRect(15, 5, 20, 40);
-           ctx.beginPath();
-           ctx.moveTo(25, 15);
-           ctx.lineTo(25, 35);
-           ctx.stroke();
-
-           ctx.fillStyle = '#0f0';
-           ctx.strokeStyle = '#f00';
-           ctx.beginPath();
-           ctx.moveTo(75, 15);
-           ctx.lineTo(75, 35);
-           ctx.stroke();
-           ctx.fillRect(65, 5, 20, 40);
-
-           verify(Helper.comparePixel(ctx, 25,4, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,5, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,6, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,44, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,45, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,46, 0,255,0,255));
-
-           verify(Helper.comparePixel(ctx, 75,4, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,5, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,6, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,44, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,45, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,46, 0,255,0,255));
-
-           ctx.reset();
-           ctx.lineCap = 'butt'
-           compare(ctx.lineCap, 'butt');
-
-           ctx.lineCap = 'round';
-           compare(ctx.lineCap, 'round');
-
-           ctx.lineCap = 'square';
-           compare(ctx.lineCap, 'square');
-
-      }
    }
+   function test_cap(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineCap = 'butt';
+       ctx.lineWidth = 20;
+
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+       ctx.fillRect(15, 15, 20, 20);
+       ctx.beginPath();
+       ctx.moveTo(25, 15);
+       ctx.lineTo(25, 35);
+       ctx.stroke();
+
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(75, 15);
+       ctx.lineTo(75, 35);
+       ctx.stroke();
+       ctx.fillRect(65, 15, 20, 20);
+
+       comparePixel(ctx, 25,14, 0,255,0,255);
+       comparePixel(ctx, 25,15, 0,255,0,255);
+       comparePixel(ctx, 25,16, 0,255,0,255);
+       comparePixel(ctx, 25,34, 0,255,0,255);
+       comparePixel(ctx, 25,35, 0,255,0,255);
+       comparePixel(ctx, 25,36, 0,255,0,255);
+
+       comparePixel(ctx, 75,14, 0,255,0,255);
+       comparePixel(ctx, 75,15, 0,255,0,255);
+       comparePixel(ctx, 75,16, 0,255,0,255);
+       comparePixel(ctx, 75,34, 0,255,0,255);
+       comparePixel(ctx, 75,35, 0,255,0,255);
+       comparePixel(ctx, 75,36, 0,255,0,255);
+
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineJoin = 'bevel';
+       ctx.lineCap = 'square';
+       ctx.lineWidth = 400;
+
+       ctx.beginPath();
+       ctx.moveTo(200, 200);
+       ctx.lineTo(200, 1000);
+       ctx.lineTo(1000, 1000);
+       ctx.lineTo(1000, 200);
+       ctx.closePath();
+       ctx.stroke();
+
+       comparePixel(ctx, 1,1, 0,255,0,255);
+       comparePixel(ctx, 48,1, 0,255,0,255);
+       comparePixel(ctx, 48,48, 0,255,0,255);
+       comparePixel(ctx, 1,48, 0,255,0,255);
+       ctx.reset();
+
+       ctx.lineCap = 'butt'
+       compare(ctx.lineCap, 'butt');
+
+       ctx.lineCap = 'butt';
+       ctx.lineCap = 'invalid';
+       compare(ctx.lineCap, 'butt');
+
+       ctx.lineCap = 'butt';
+       ctx.lineCap = 'ROUND';
+       compare(ctx.lineCap, 'butt');
+
+       ctx.lineCap = 'butt';
+       ctx.lineCap = 'round\\0';
+       compare(ctx.lineCap, 'butt');
+
+       ctx.lineCap = 'butt';
+       ctx.lineCap = 'round ';
+       compare(ctx.lineCap, 'butt');
+
+       ctx.lineCap = 'butt';
+       ctx.lineCap = "";
+       compare(ctx.lineCap, 'butt');
+
+       ctx.lineCap = 'butt';
+       ctx.lineCap = 'bevel';
+       compare(ctx.lineCap, 'butt');
+
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineJoin = 'bevel';
+       ctx.lineCap = 'square';
+       ctx.lineWidth = 400;
+
+       ctx.beginPath();
+       ctx.moveTo(200, 200);
+       ctx.lineTo(200, 1000);
+       ctx.lineTo(1000, 1000);
+       ctx.lineTo(1000, 200);
+       ctx.lineTo(200, 200);
+       ctx.stroke();
+
+       //FIXME:!!!
+       //comparePixel(ctx, 1,1, 0,255,0,255);
+       //comparePixel(ctx, 48,1, 0,255,0,255);
+       //comparePixel(ctx, 48,48, 0,255,0,255);
+       //comparePixel(ctx, 1,48, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       var tol = 1; // tolerance to avoid antialiasing artifacts
+
+       ctx.lineCap = 'round';
+       ctx.lineWidth = 20;
+
+
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+
+       ctx.beginPath();
+       ctx.moveTo(35-tol, 15);
+       ctx.arc(25, 15, 10-tol, 0, Math.PI, true);
+       ctx.arc(25, 35, 10-tol, Math.PI, 0, true);
+       ctx.fill();
+
+       ctx.beginPath();
+       ctx.moveTo(25, 15);
+       ctx.lineTo(25, 35);
+       ctx.stroke();
+
+
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+
+       ctx.beginPath();
+       ctx.moveTo(75, 15);
+       ctx.lineTo(75, 35);
+       ctx.stroke();
+
+       ctx.beginPath();
+       ctx.moveTo(85+tol, 15);
+       ctx.arc(75, 15, 10+tol, 0, Math.PI, true);
+       ctx.arc(75, 35, 10+tol, Math.PI, 0, true);
+       ctx.fill();
+
+       comparePixel(ctx, 17,6, 0,255,0,255);
+       comparePixel(ctx, 25,6, 0,255,0,255);
+       comparePixel(ctx, 32,6, 0,255,0,255);
+       comparePixel(ctx, 17,43, 0,255,0,255);
+       comparePixel(ctx, 25,43, 0,255,0,255);
+       comparePixel(ctx, 32,43, 0,255,0,255);
+
+       comparePixel(ctx, 67,6, 0,255,0,255);
+       comparePixel(ctx, 75,6, 0,255,0,255);
+       comparePixel(ctx, 82,6, 0,255,0,255);
+       comparePixel(ctx, 67,43, 0,255,0,255);
+       comparePixel(ctx, 75,43, 0,255,0,255);
+       comparePixel(ctx, 82,43, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.lineCap = 'square';
+       ctx.lineWidth = 20;
+
+       ctx.fillStyle = '#f00';
+       ctx.strokeStyle = '#0f0';
+       ctx.fillRect(15, 5, 20, 40);
+       ctx.beginPath();
+       ctx.moveTo(25, 15);
+       ctx.lineTo(25, 35);
+       ctx.stroke();
+
+       ctx.fillStyle = '#0f0';
+       ctx.strokeStyle = '#f00';
+       ctx.beginPath();
+       ctx.moveTo(75, 15);
+       ctx.lineTo(75, 35);
+       ctx.stroke();
+       ctx.fillRect(65, 5, 20, 40);
+
+       comparePixel(ctx, 25,4, 0,255,0,255);
+       comparePixel(ctx, 25,5, 0,255,0,255);
+       comparePixel(ctx, 25,6, 0,255,0,255);
+       comparePixel(ctx, 25,44, 0,255,0,255);
+       comparePixel(ctx, 25,45, 0,255,0,255);
+       comparePixel(ctx, 25,46, 0,255,0,255);
+
+       comparePixel(ctx, 75,4, 0,255,0,255);
+       comparePixel(ctx, 75,5, 0,255,0,255);
+       comparePixel(ctx, 75,6, 0,255,0,255);
+       comparePixel(ctx, 75,44, 0,255,0,255);
+       comparePixel(ctx, 75,45, 0,255,0,255);
+       comparePixel(ctx, 75,46, 0,255,0,255);
+
+       ctx.reset();
+       ctx.lineCap = 'butt'
+       compare(ctx.lineCap, 'butt');
+
+       ctx.lineCap = 'round';
+       compare(ctx.lineCap, 'round');
+
+       ctx.lineCap = 'square';
+       compare(ctx.lineCap, 'square');
+
+  }
 }
index 7c88106..60c782c 100644 (file)
@@ -1,13 +1,11 @@
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
 
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       name: "path"; when: windowShown
-
-       function test_basic() {
+CanvasTestCase {
+   id:testCase
+   name: "path"
+   function init_data() { return testData("2d"); }
+       function test_basic(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -15,7 +13,7 @@ Canvas {
            ctx.closePath();
            ctx.fillStyle = '#f00';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -25,7 +23,7 @@ Canvas {
            ctx.restore();
            ctx.fillStyle = '#0f0';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
 
            canvas.width = 100;
@@ -33,9 +31,11 @@ Canvas {
            canvas.width = 100;
            ctx.fillStyle = '#f00';
            ctx.fill();
-           //verify(Helper.comparePixel(ctx, 20,20, 0,0,0,0));
+           //comparePixel(ctx, 20,20, 0,0,0,0);
+           canvas.destroy()
        }
-       function test_beginPath() {
+       function test_beginPath(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.fillStyle = '#0f0';
            ctx.fillRect(0, 0, 100, 50);
@@ -43,9 +43,11 @@ Canvas {
            ctx.beginPath();
            ctx.fillStyle = '#f00';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
-       function test_closePath() {
+       function test_closePath(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -53,7 +55,7 @@ Canvas {
            ctx.closePath();
            ctx.fillStyle = '#f00';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -66,7 +68,7 @@ Canvas {
            ctx.lineTo(200, 25);
            ctx.closePath();
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -78,10 +80,12 @@ Canvas {
            ctx.closePath();
            ctx.lineTo(1000, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
 
-       function test_isPointInPath() {
+       function test_isPointInPath(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.arc(50, 25, 10, 0, Math.PI, false);
@@ -246,10 +250,12 @@ Canvas {
            verify(ctx.isPointInPath(5, 45));
            verify(ctx.isPointInPath(25, 45));
            verify(ctx.isPointInPath(45, 45));
+           canvas.destroy()
        }
 
 
-       function test_fill() {
+       function test_fill(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -262,7 +268,7 @@ Canvas {
            ctx.lineTo(0, 50);
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
 
            ctx.reset();
@@ -278,8 +284,8 @@ Canvas {
            ctx.fillStyle = '#0f0';
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 10,40, 0,255,0,255));
+           comparePixel(ctx, 90,10, 0,255,0,255);
+           comparePixel(ctx, 10,40, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#000';
@@ -291,7 +297,7 @@ Canvas {
            ctx.rect(10, 10, 80, 30);
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,127,0,255, 1));
+           comparePixel(ctx, 50,25, 0,127,0,255, 1);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -309,7 +315,7 @@ Canvas {
            ctx.lineTo(0, 50);
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -327,7 +333,7 @@ Canvas {
            ctx.lineTo(100, 0);
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -344,7 +350,7 @@ Canvas {
            ctx.lineTo(100, 0);
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -367,10 +373,11 @@ Canvas {
            ctx.lineTo(100, 0);
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
-       function test_stroke() {
+       function test_stroke(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -386,7 +393,7 @@ Canvas {
            ctx.moveTo(60, 25);
            ctx.stroke();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#000';
@@ -400,7 +407,7 @@ Canvas {
            ctx.lineTo(100, 30);
            ctx.stroke();
 
-           //verify(Helper.comparePixel(ctx, 50,25, 0,127,0,255));
+           //comparePixel(ctx, 50,25, 0,127,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -421,7 +428,7 @@ Canvas {
            ctx.arc(50, 25, 10, 0, 0, false);
            ctx.stroke();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
            ctx.reset();
            ctx.fillStyle = '#0f0';
            ctx.fillRect(0, 0, 100, 50);
@@ -437,7 +444,7 @@ Canvas {
            ctx.closePath();
            ctx.stroke();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
            ctx.reset();
 
            ctx.fillStyle = '#0f0';
@@ -457,7 +464,7 @@ Canvas {
            ctx.stroke();
 
            //FIXME:lineJoin with miterLimit test fail!
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           //comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -478,7 +485,7 @@ Canvas {
            ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
            ctx.stroke();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.fillStyle = '#0f0';
            ctx.fillRect(0, 0, 100, 50);
@@ -493,7 +500,7 @@ Canvas {
            ctx.lineTo(50, 25);
            ctx.stroke();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -510,7 +517,7 @@ Canvas {
 
            ctx.strokeRect(50, 25, 0, 0);
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
 
            ctx.fillStyle = '#f00';
@@ -532,15 +539,15 @@ Canvas {
            ctx.stroke();
            ctx.restore();
 
-           //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+           //comparePixel(ctx, 0,0, 0,255,0,255);
+           //comparePixel(ctx, 50,0, 0,255,0,255);
+           //comparePixel(ctx, 99,0, 0,255,0,255);
+           //comparePixel(ctx, 0,25, 0,255,0,255);
+           //comparePixel(ctx, 50,25, 0,255,0,255);
+           //comparePixel(ctx, 99,25, 0,255,0,255);
+           //comparePixel(ctx, 0,49, 0,255,0,255);
+           //comparePixel(ctx, 50,49, 0,255,0,255);
+           //comparePixel(ctx, 99,49, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -564,15 +571,15 @@ Canvas {
            ctx.stroke();
            ctx.restore();
 
-           verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+           comparePixel(ctx, 0,0, 0,255,0,255);
+           comparePixel(ctx, 50,0, 0,255,0,255);
+           comparePixel(ctx, 99,0, 0,255,0,255);
+           comparePixel(ctx, 0,25, 0,255,0,255);
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 99,25, 0,255,0,255);
+           comparePixel(ctx, 0,49, 0,255,0,255);
+           comparePixel(ctx, 50,49, 0,255,0,255);
+           comparePixel(ctx, 99,49, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -610,15 +617,15 @@ Canvas {
            ctx.stroke();
            ctx.restore();
 
-           //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+           //comparePixel(ctx, 0,0, 0,255,0,255);
+           comparePixel(ctx, 50,0, 0,255,0,255);
+           //comparePixel(ctx, 99,0, 0,255,0,255);
+           //comparePixel(ctx, 0,25, 0,255,0,255);
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 99,25, 0,255,0,255);
+           //comparePixel(ctx, 0,49, 0,255,0,255);
+           comparePixel(ctx, 50,49, 0,255,0,255);
+           comparePixel(ctx, 99,49, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -636,7 +643,7 @@ Canvas {
            ctx.strokeStyle = '#0f0';
            ctx.stroke();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -650,10 +657,11 @@ Canvas {
            ctx.lineTo(0, 40);
            ctx.stroke();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
-       function test_clip() {
+       function test_clip(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -666,7 +674,7 @@ Canvas {
            ctx.fillStyle = '#0f0';
            ctx.fillRect(0, 0, 100, 50);
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -679,7 +687,7 @@ Canvas {
            ctx.fillStyle = '#f00';
            ctx.fillRect(0, 0, 100, 50);
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
            ctx.reset();
            ctx.fillStyle = '#0f0';
            ctx.fillRect(0, 0, 100, 50);
@@ -690,7 +698,7 @@ Canvas {
            ctx.fillStyle = '#f00';
            ctx.fillRect(0, 0, 100, 50);
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.fillStyle = '#0f0';
            ctx.fillRect(0, 0, 100, 50);
@@ -705,7 +713,7 @@ Canvas {
            ctx.fillStyle = '#f00';
            ctx.fillRect(0, 0, 100, 50);
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -723,7 +731,7 @@ Canvas {
            ctx.lineTo(0, 0);
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
 
            ctx.reset();
@@ -745,7 +753,7 @@ Canvas {
            ctx.fillStyle = '#f00';
            ctx.fillRect(0, 0, 100, 50);
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -770,10 +778,12 @@ Canvas {
            ctx.fillStyle = '#0f0';
            ctx.fillRect(0, 0, 100, 50);
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
 
-       function test_moveTo() {
+       function test_moveTo(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -785,7 +795,7 @@ Canvas {
            ctx.lineTo(100, 50);
            ctx.fillStyle = '#0f0';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 90,25, 0,255,0,255));
+           comparePixel(ctx, 90,25, 0,255,0,255);
            ctx.reset();
            ctx.fillStyle = '#f00';
            ctx.fillRect(0, 0, 100, 50);
@@ -796,7 +806,7 @@ Canvas {
            ctx.strokeStyle = '#0f0';
            ctx.lineWidth = 50;
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -808,7 +818,7 @@ Canvas {
            ctx.moveTo(0, 50);
            ctx.fillStyle = '#f00';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.moveTo(0, 0);
@@ -824,9 +834,11 @@ Canvas {
            ctx.lineTo(0, 50);
            ctx.fillStyle = '#0f0';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
-       function test_lineTo() {
+       function test_lineTo(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -837,7 +849,7 @@ Canvas {
            ctx.moveTo(0, 25);
            ctx.lineTo(100, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -847,7 +859,7 @@ Canvas {
            ctx.beginPath();
            ctx.lineTo(100, 50);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -858,7 +870,7 @@ Canvas {
            ctx.lineTo(0, 25);
            ctx.lineTo(100, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -870,7 +882,7 @@ Canvas {
            ctx.lineTo(0, 25);
            ctx.lineTo(100, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.moveTo(0, 0);
@@ -886,11 +898,12 @@ Canvas {
            ctx.lineTo(0, 50);
            ctx.fillStyle = '#0f0';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255));
-
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 90,45, 0,255,0,255);
+           canvas.destroy()
        }
-       function test_bezierCurveTo() {
+       function test_bezierCurveTo(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -901,7 +914,7 @@ Canvas {
            ctx.moveTo(0, 25);
            ctx.bezierCurveTo(100, 25, 100, 25, 100, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -911,8 +924,8 @@ Canvas {
            ctx.beginPath();
            ctx.bezierCurveTo(100, 50, 200, 50, 200, 50);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 95,45, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 95,45, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -922,8 +935,8 @@ Canvas {
            ctx.beginPath();
            ctx.bezierCurveTo(0, 25, 100, 25, 100, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 5,45, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 5,45, 0,255,0,255);
 
            ctx.reset();
            ctx.moveTo(0, 0);
@@ -1022,8 +1035,8 @@ Canvas {
            ctx.lineTo(0, 50);
            ctx.fillStyle = '#0f0';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 90,45, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1035,11 +1048,11 @@ Canvas {
            ctx.moveTo(-2, 3.1);
            ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1050,14 +1063,15 @@ Canvas {
            ctx.moveTo(-2000, 3100);
            ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
-
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
+           canvas.destroy()
        }
-       function test_quadraticCurveTo() {
+       function test_quadraticCurveTo(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1068,7 +1082,7 @@ Canvas {
            ctx.moveTo(0, 25);
            ctx.quadraticCurveTo(100, 25, 100, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -1078,8 +1092,8 @@ Canvas {
            ctx.beginPath();
            ctx.quadraticCurveTo(100, 50, 200, 50);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 95,45, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 95,45, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1089,8 +1103,8 @@ Canvas {
            ctx.beginPath();
            ctx.quadraticCurveTo(0, 25, 100, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 5,45, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 5,45, 0,255,0,255);
 
            ctx.reset();
            ctx.moveTo(0, 0);
@@ -1122,8 +1136,8 @@ Canvas {
            ctx.lineTo(0, 50);
            ctx.fillStyle = '#0f0';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 90,45, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1135,11 +1149,11 @@ Canvas {
            ctx.moveTo(-1, 1.05);
            ctx.quadraticCurveTo(0, -1, 1.2, 1.05);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           //comparePixel(ctx, 1,1, 0,255,0,255);
+           //comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1150,13 +1164,15 @@ Canvas {
            ctx.moveTo(-1000, 1050);
            ctx.quadraticCurveTo(0, -1000, 1200, 1050);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           //comparePixel(ctx, 1,1, 0,255,0,255);
+           //comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
+           canvas.destroy()
        }
-       function test_rect() {
+       function test_rect(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
 
@@ -1165,7 +1181,7 @@ Canvas {
            ctx.fillStyle = '#0f0';
            ctx.rect(0, 0, 100, 50);
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1175,7 +1191,7 @@ Canvas {
            ctx.lineJoin = 'miter';
            ctx.rect(100, 50, 100, 100);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1185,7 +1201,7 @@ Canvas {
            ctx.rect(200, 100, 400, 1000);
            ctx.lineTo(-2000, -1000);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1197,10 +1213,10 @@ Canvas {
            ctx.rect(150, 150, 2000, 2000);
            ctx.lineTo(160, 160);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+           comparePixel(ctx, 1,1, 0,255,0,255);
+           comparePixel(ctx, 98,1, 0,255,0,255);
+           comparePixel(ctx, 1,48, 0,255,0,255);
+           comparePixel(ctx, 98,48, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1212,10 +1228,10 @@ Canvas {
            ctx.rect(0, 50, 50, -25);
            ctx.rect(100, 50, -50, -25);
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 25,12, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,12, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,37, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,37, 0,255,0,255));
+           comparePixel(ctx, 25,12, 0,255,0,255);
+           comparePixel(ctx, 75,12, 0,255,0,255);
+           comparePixel(ctx, 25,37, 0,255,0,255);
+           comparePixel(ctx, 75,37, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -1227,7 +1243,7 @@ Canvas {
            ctx.lineTo(-50, 25);
            ctx.rect(200, 25, 1, 1);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
 
            ctx.reset();
@@ -1260,8 +1276,8 @@ Canvas {
            ctx.lineTo(0, 50);
            ctx.fillStyle = '#0f0';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           comparePixel(ctx, 90,45, 0,255,0,255);
 
 
            ctx.reset();
@@ -1272,7 +1288,7 @@ Canvas {
            ctx.beginPath();
            ctx.rect(45, 20, 10, 10);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -1284,10 +1300,10 @@ Canvas {
            ctx.rect(0, 25, 100, -25);
            ctx.rect(100, 25, -100, 25);
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 25,12, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,12, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 25,37, 0,255,0,255));
-           verify(Helper.comparePixel(ctx, 75,37, 0,255,0,255));
+           comparePixel(ctx, 25,12, 0,255,0,255);
+           comparePixel(ctx, 75,12, 0,255,0,255);
+           comparePixel(ctx, 25,37, 0,255,0,255);
+           comparePixel(ctx, 75,37, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1297,7 +1313,7 @@ Canvas {
            ctx.beginPath();
            ctx.rect(0, 50, 100, 0);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1307,7 +1323,7 @@ Canvas {
            ctx.beginPath();
            ctx.rect(50, -100, 0, 250);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -1317,7 +1333,7 @@ Canvas {
            ctx.beginPath();
            ctx.rect(50, 25, 0, 0);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1327,7 +1343,7 @@ Canvas {
            ctx.rect(100, 25, 0, 0);
            ctx.lineTo(0, 25);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -1337,7 +1353,7 @@ Canvas {
            ctx.moveTo(0, 0);
            ctx.rect(100, 25, 0, 0);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -1349,10 +1365,12 @@ Canvas {
            ctx.beginPath();
            ctx.rect(100, 25, 1000, 0);
            ctx.stroke();
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           //comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
 
-       function test_clearRect() {
+       function test_clearRect(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -1360,9 +1378,11 @@ Canvas {
            ctx.rect(0, 0, 100, 50);
            ctx.clearRect(0, 0, 16, 16);
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
-       function test_fillRect() {
+       function test_fillRect(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.beginPath();
@@ -1371,10 +1391,12 @@ Canvas {
            ctx.fillRect(0, 0, 16, 16);
            ctx.fillStyle = '#0f0';
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
 
-       function test_strokeRect() {
+       function test_strokeRect(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.beginPath();
@@ -1385,9 +1407,11 @@ Canvas {
            ctx.fillStyle = '#0f0';
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
-       function test_transform() {
+       function test_transform(row) {
+           var canvas = createCanvasObject(row);
            var ctx = canvas.getContext('2d');
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1399,7 +1423,7 @@ Canvas {
            ctx.fillStyle = '#0f0';
            ctx.fill();
 
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#f00';
@@ -1416,7 +1440,7 @@ Canvas {
            ctx.rotate(Math.PI/2);
            ctx.scale(0.1, 0.1);
            ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
 
            ctx.reset();
            ctx.fillStyle = '#0f0';
@@ -1438,7 +1462,7 @@ Canvas {
            ctx.stroke();
            ctx.translate(0, 50);
            ctx.stroke();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+           comparePixel(ctx, 50,25, 0,255,0,255);
+           canvas.destroy()
        }
-   }
 }
index 29c8bc9..1d7fd2c 100644 (file)
@@ -1,34 +1,43 @@
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       //TODO
-       name: "pattern"; when: windowShown
-       function test_basic() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_animated() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_image() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_modified() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_paint() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_repeat() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-   }
+
+CanvasTestCase {
+   id:testCase
+   name: "pattern"
+   function init_data() { return testData("2d"); }
+   function test_basic(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_animated(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_image(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_modified(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_paint(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_repeat(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
 }
index 8fd390a..469ff23 100644 (file)
@@ -1,30 +1,37 @@
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       //TODO
-       name: "pixel"; when: windowShown
-       function test_createImageData() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_getImageData() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_object() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_putImageData() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_filters() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-   }
+
+CanvasTestCase {
+   id:testCase
+   name: "pixel"
+   function init_data() { return testData("2d"); }
+   function test_createImageData(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_getImageData(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_object(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_putImageData(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_filters(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
 }
index bcb602a..2baaa07 100644 (file)
@@ -1,59 +1,77 @@
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       //TODO
 
-       name: "shadow"; when: windowShown
-       function test_basic() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_blur() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
+CanvasTestCase {
+   id:testCase
+   name: "shadow"
+   function init_data() { return testData("2d"); }
+   function test_basic(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_blur(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+   }
 
-       function test_clip() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
+   function test_clip(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+   }
 
-       function test_composite() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
+   function test_composite(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+   }
 
-       function test_enable() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
+   function test_enable(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+   }
 
-       function test_gradient() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
-       function test_image() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
-       function test_offset() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
-       function test_pattern() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
-       function test_stroke() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
-       function test_tranform() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-       }
+   function test_gradient(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+   }
+   function test_image(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+   }
+   function test_offset(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+   }
+   function test_pattern(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+   }
+   function test_stroke(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+   }
+   function test_tranform(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
    }
 }
index def312d..1ceb17b 100644 (file)
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       id:testCase
-       name: "state"; when: windowShown
-       function test_bitmap() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.save();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.restore();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-      }
-       function test_clip() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.save();
-           ctx.rect(0, 0, 1, 1);
-           ctx.clip();
-           ctx.restore();
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-
-       }
-       function test_fillStyle() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           // Test that restore() undoes any modifications
-           var old = ctx.fillStyle;
-           ctx.save();
-           ctx.fillStyle = "#ff0000";
-           ctx.restore();
-           compare(ctx.fillStyle, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.fillStyle = "#ff0000";
-           old = ctx.fillStyle;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "#ff0000"
-           ctx.save();
-           compare(ctx.fillStyle, old);
-           ctx.restore();
-       }
-       function test_font() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.font;
-           ctx.save();
-           ctx.font = "25px serif";
-           ctx.restore();
-           compare(ctx.font, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.font = "25px serif";
-           old = ctx.font;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "25px serif"
-           ctx.save();
-           compare(ctx.font, old);
-           ctx.restore();
-       }
-       function test_globalAlpha() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.globalAlpha;
-           ctx.save();
-           ctx.globalAlpha = 0.5;
-           ctx.restore();
-           compare(ctx.globalAlpha, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.globalAlpha = 0.5;
-           old = ctx.globalAlpha;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against 0.5
-           ctx.save();
-           compare(ctx.globalAlpha, old);
-           ctx.restore();
-        }
-       function test_globalCompositeOperation() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.globalCompositeOperation;
-           ctx.save();
-           ctx.globalCompositeOperation = "copy";
-           ctx.restore();
-           compare(ctx.globalCompositeOperation, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.globalCompositeOperation = "copy";
-           old = ctx.globalCompositeOperation;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "copy"
-           ctx.save();
-           compare(ctx.globalCompositeOperation, old);
-           ctx.restore();
-       }
-       function test_lineCap() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.lineCap;
-           ctx.save();
-           ctx.lineCap = "round";
-           ctx.restore();
-           compare(ctx.lineCap, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.lineCap = "round";
-           old = ctx.lineCap;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "round"
-           ctx.save();
-           compare(ctx.lineCap, old);
-           ctx.restore();
-       }
-       function test_lineJoin() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.lineJoin;
-           ctx.save();
-           ctx.lineJoin = "round";
-           ctx.restore();
-           compare(ctx.lineJoin, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.lineJoin = "round";
-           old = ctx.lineJoin;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "round"
-           ctx.save();
-           compare(ctx.lineJoin, old);
-           ctx.restore();
-       }
-       function test_lineWidth() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.lineJoin;
-           ctx.save();
-           ctx.lineJoin = "round";
-           ctx.restore();
-           compare(ctx.lineJoin, old, "ctx.lineJoin", "old");
-
-           // Also test that save() doesn't modify the values
-           ctx.lineJoin = "round";
-           old = ctx.lineJoin;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "round"
-           ctx.save();
-           compare(ctx.lineJoin, old);
-           ctx.restore();
-       }
-       function test_miterLimit() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.miterLimit;
-           ctx.save();
-           ctx.miterLimit = 0.5;
-           ctx.restore();
-           compare(ctx.miterLimit, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.miterLimit = 0.5;
-           old = ctx.miterLimit;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against 0.5
-           ctx.save();
-           compare(ctx.miterLimit, old);
-           ctx.restore();
-       }
-       function test_path() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.save();
-           ctx.rect(0, 0, 100, 50);
-           ctx.restore();
-           ctx.fillStyle = '#0f0';
-           ctx.fill();
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-       }
-       function test_shadow() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.shadowBlur;
-           ctx.save();
-           ctx.shadowBlur = 5;
-           ctx.restore();
-           compare(ctx.shadowBlur, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.shadowBlur = 5;
-           old = ctx.shadowBlur;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against 5
-           ctx.save();
-           compare(ctx.shadowBlur, old);
-           ctx.restore();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.shadowColor;
-           ctx.save();
-           ctx.shadowColor = "#ff0000";
-           ctx.restore();
-           compare(ctx.shadowColor, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.shadowColor = "#ff0000";
-           old = ctx.shadowColor;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "#ff0000"
-           ctx.save();
-           compare(ctx.shadowColor, old);
-           ctx.restore();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.shadowOffsetX;
-           ctx.save();
-           ctx.shadowOffsetX = 5;
-           ctx.restore();
-           compare(ctx.shadowOffsetX, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.shadowOffsetX = 5;
-           old = ctx.shadowOffsetX;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against 5
-           ctx.save();
-           compare(ctx.shadowOffsetX, old);
-           ctx.restore();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.shadowOffsetY;
-           ctx.save();
-           ctx.shadowOffsetY = 5;
-           ctx.restore();
-           compare(ctx.shadowOffsetY, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.shadowOffsetY = 5;
-           old = ctx.shadowOffsetY;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against 5
-           ctx.save();
-           compare(ctx.shadowOffsetY, old);
-           ctx.restore();
-
-       }
-       function test_stack() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.lineWidth = 1;
-           ctx.save();
-           ctx.lineWidth = 2;
-           ctx.save();
-           ctx.lineWidth = 3;
-           compare(ctx.lineWidth, 3);
-           ctx.restore();
-           compare(ctx.lineWidth, 2);
-           ctx.restore();
-           compare(ctx.lineWidth, 1);
-
-           var limit = 512;
-           for (var i = 1; i < limit; ++i)
-           {
-               ctx.save();
-               ctx.lineWidth = i;
-           }
-           for (var i = limit-1; i > 0; --i)
-           {
-               testCase.compare(ctx.lineWidth, i); //strange javascript error here
-               ctx.restore();
-           }
-
-           for (var i = 0; i < 16; ++i)
-               ctx.restore();
-           ctx.lineWidth = 0.5;
-           ctx.restore();
-           compare(ctx.lineWidth, 0.5);
-
-       }
-       function test_strokeStyle() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.strokeStyle;
-           ctx.save();
-           ctx.strokeStyle = "#ff0000";
-           ctx.restore();
-           compare(ctx.strokeStyle, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.strokeStyle = "#ff0000";
-           old = ctx.strokeStyle;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "#ff0000"
-           ctx.save();
-           compare(ctx.strokeStyle, old);
-           ctx.restore();
-
 
+CanvasTestCase {
+   id:testCase
+   name: "state"
+   function init_data() { return testData("2d"); }
+   function test_bitmap(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.save();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.restore();
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       canvas.destroy()
+  }
+   function test_clip(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.save();
+       ctx.rect(0, 0, 1, 1);
+       ctx.clip();
+       ctx.restore();
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       //comparePixel(ctx, 50,25, 0,255,0,255);
+       canvas.destroy()
+   }
+   function test_fillStyle(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       // Test that restore() undoes any modifications
+       var old = ctx.fillStyle;
+       ctx.save();
+       ctx.fillStyle = "#ff0000";
+       ctx.restore();
+       compare(ctx.fillStyle, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.fillStyle = "#ff0000";
+       old = ctx.fillStyle;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "#ff0000"
+       ctx.save();
+       compare(ctx.fillStyle, old);
+       ctx.restore();
+       canvas.destroy()
+   }
+   function test_font(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.font;
+       ctx.save();
+       ctx.font = "25px serif";
+       ctx.restore();
+       compare(ctx.font, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.font = "25px serif";
+       old = ctx.font;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "25px serif"
+       ctx.save();
+       compare(ctx.font, old);
+       ctx.restore();
+       canvas.destroy()
+   }
+   function test_globalAlpha(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.globalAlpha;
+       ctx.save();
+       ctx.globalAlpha = 0.5;
+       ctx.restore();
+       compare(ctx.globalAlpha, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.globalAlpha = 0.5;
+       old = ctx.globalAlpha;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against 0.5
+       ctx.save();
+       compare(ctx.globalAlpha, old);
+       ctx.restore();
+       canvas.destroy()
+    }
+   function test_globalCompositeOperation(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.globalCompositeOperation;
+       ctx.save();
+       ctx.globalCompositeOperation = "copy";
+       ctx.restore();
+       compare(ctx.globalCompositeOperation, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.globalCompositeOperation = "copy";
+       old = ctx.globalCompositeOperation;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "copy"
+       ctx.save();
+       compare(ctx.globalCompositeOperation, old);
+       ctx.restore();
+       canvas.destroy()
+   }
+   function test_lineCap(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.lineCap;
+       ctx.save();
+       ctx.lineCap = "round";
+       ctx.restore();
+       compare(ctx.lineCap, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.lineCap = "round";
+       old = ctx.lineCap;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "round"
+       ctx.save();
+       compare(ctx.lineCap, old);
+       ctx.restore();
+       canvas.destroy()
+   }
+   function test_lineJoin(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.lineJoin;
+       ctx.save();
+       ctx.lineJoin = "round";
+       ctx.restore();
+       compare(ctx.lineJoin, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.lineJoin = "round";
+       old = ctx.lineJoin;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "round"
+       ctx.save();
+       compare(ctx.lineJoin, old);
+       ctx.restore();
+       canvas.destroy()
+   }
+   function test_lineWidth(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.lineJoin;
+       ctx.save();
+       ctx.lineJoin = "round";
+       ctx.restore();
+       compare(ctx.lineJoin, old, "ctx.lineJoin", "old");
+
+       // Also test that save() doesn't modify the values
+       ctx.lineJoin = "round";
+       old = ctx.lineJoin;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "round"
+       ctx.save();
+       compare(ctx.lineJoin, old);
+       ctx.restore();
+       canvas.destroy()
+   }
+   function test_miterLimit(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.miterLimit;
+       ctx.save();
+       ctx.miterLimit = 0.5;
+       ctx.restore();
+       compare(ctx.miterLimit, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.miterLimit = 0.5;
+       old = ctx.miterLimit;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against 0.5
+       ctx.save();
+       compare(ctx.miterLimit, old);
+       ctx.restore();
+       canvas.destroy()
+   }
+   function test_path(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.save();
+       ctx.rect(0, 0, 100, 50);
+       ctx.restore();
+       ctx.fillStyle = '#0f0';
+       ctx.fill();
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       canvas.destroy()
+   }
+   function test_shadow(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.shadowBlur;
+       ctx.save();
+       ctx.shadowBlur = 5;
+       ctx.restore();
+       compare(ctx.shadowBlur, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.shadowBlur = 5;
+       old = ctx.shadowBlur;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against 5
+       ctx.save();
+       compare(ctx.shadowBlur, old);
+       ctx.restore();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.shadowColor;
+       ctx.save();
+       ctx.shadowColor = "#ff0000";
+       ctx.restore();
+       compare(ctx.shadowColor, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.shadowColor = "#ff0000";
+       old = ctx.shadowColor;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "#ff0000"
+       ctx.save();
+       compare(ctx.shadowColor, old);
+       ctx.restore();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.shadowOffsetX;
+       ctx.save();
+       ctx.shadowOffsetX = 5;
+       ctx.restore();
+       compare(ctx.shadowOffsetX, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.shadowOffsetX = 5;
+       old = ctx.shadowOffsetX;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against 5
+       ctx.save();
+       compare(ctx.shadowOffsetX, old);
+       ctx.restore();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.shadowOffsetY;
+       ctx.save();
+       ctx.shadowOffsetY = 5;
+       ctx.restore();
+       compare(ctx.shadowOffsetY, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.shadowOffsetY = 5;
+       old = ctx.shadowOffsetY;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against 5
+       ctx.save();
+       compare(ctx.shadowOffsetY, old);
+       ctx.restore();
+       canvas.destroy()
+   }
+   function test_stack(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.lineWidth = 1;
+       ctx.save();
+       ctx.lineWidth = 2;
+       ctx.save();
+       ctx.lineWidth = 3;
+       compare(ctx.lineWidth, 3);
+       ctx.restore();
+       compare(ctx.lineWidth, 2);
+       ctx.restore();
+       compare(ctx.lineWidth, 1);
+
+       var limit = 512;
+       for (var i = 1; i < limit; ++i)
+       {
+           ctx.save();
+           ctx.lineWidth = i;
        }
-
-       function test_text() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.textAlign;
-           ctx.save();
-           ctx.textAlign = "center";
-           ctx.restore();
-           compare(ctx.textAlign, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.textAlign = "center";
-           old = ctx.textAlign;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "center"
-           ctx.save();
-           compare(ctx.textAlign, old);
+       for (var i = limit-1; i > 0; --i)
+       {
+           testCase.compare(ctx.lineWidth, i); //strange javascript error here
            ctx.restore();
-
-           // Test that restore() undoes any modifications
-           var old = ctx.textBaseline;
-           ctx.save();
-           ctx.textBaseline = "bottom";
-           ctx.restore();
-           compare(ctx.textBaseline, old);
-
-           // Also test that save() doesn't modify the values
-           ctx.textBaseline = "bottom";
-           old = ctx.textBaseline;
-               // we're not interested in failures caused by get(set(x)) != x (e.g.
-               // from rounding), so compare against 'old' instead of against "bottom"
-           ctx.save();
-           compare(ctx.textBaseline, old);
-           ctx.restore();
-
-
        }
 
-       function test_transform() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.save();
-           ctx.translate(200, 0);
+       for (var i = 0; i < 16; ++i)
            ctx.restore();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(-200, 0, 100, 50);
-           verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
-
-
-       }
+       ctx.lineWidth = 0.5;
+       ctx.restore();
+       compare(ctx.lineWidth, 0.5);
+       canvas.destroy()
+   }
+   function test_strokeStyle(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.strokeStyle;
+       ctx.save();
+       ctx.strokeStyle = "#ff0000";
+       ctx.restore();
+       compare(ctx.strokeStyle, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.strokeStyle = "#ff0000";
+       old = ctx.strokeStyle;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "#ff0000"
+       ctx.save();
+       compare(ctx.strokeStyle, old);
+       ctx.restore();
+       canvas.destroy()
+   }
 
+   function test_text(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.textAlign;
+       ctx.save();
+       ctx.textAlign = "center";
+       ctx.restore();
+       compare(ctx.textAlign, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.textAlign = "center";
+       old = ctx.textAlign;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "center"
+       ctx.save();
+       compare(ctx.textAlign, old);
+       ctx.restore();
+
+       // Test that restore() undoes any modifications
+       var old = ctx.textBaseline;
+       ctx.save();
+       ctx.textBaseline = "bottom";
+       ctx.restore();
+       compare(ctx.textBaseline, old);
+
+       // Also test that save() doesn't modify the values
+       ctx.textBaseline = "bottom";
+       old = ctx.textBaseline;
+           // we're not interested in failures caused by get(set(x)) != x (e.g.
+           // from rounding), so compare against 'old' instead of against "bottom"
+       ctx.save();
+       compare(ctx.textBaseline, old);
+       ctx.restore();
+       canvas.destroy()
+   }
 
+   function test_transform(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.save();
+       ctx.translate(200, 0);
+       ctx.restore();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(-200, 0, 100, 50);
+       comparePixel(ctx, 50,25, 0,255,0,255);
+       canvas.destroy()
    }
 }
index c81ef73..22803a1 100644 (file)
@@ -1,49 +1,49 @@
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
 
-Canvas {
-   id:canvas; width:100;height:50; renderTarget:Canvas.Image; renderStrategy:Canvas.Threaded
-   smooth: false
-   TestCase {
-       name: "strokeStyle"; when: windowShown
-       function test_default() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           compare(ctx.strokeStyle, "#000000")
-           ctx.clearRect(0, 0, 1, 1);
-           compare(ctx.strokeStyle, "#000000")
-       }
-       function test_saverestore() {
-           var ctx = canvas.getContext('2d');
-           var old = ctx.strokeStyle;
-           ctx.save();
-           ctx.strokeStyle = "#ffaaff";
-           ctx.restore();
-           compare(ctx.strokeStyle, old);
-
-           ctx.strokeStyle = "#ffcc88";
-           old = ctx.strokeStyle;
-           ctx.save();
-           compare(ctx.strokeStyle, old);
-           ctx.restore();
-       }
-       function test_namedColor() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.strokeStyle = "red";
-           ctx.strokeRect(0,0,1,1);
-           verify(Helper.comparePixel(ctx,0,0,255,0,0,255));
-
-           ctx.strokeStyle = "black";
-           ctx.strokeRect(0,0,1,1);
-           verify(Helper.comparePixel(ctx,0,0,0,0,0,255));
+CanvasTestCase {
+   id:testCase
+   name: "strokeStyle"
+   function init_data() { return testData("2d"); }
+   function test_default(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       compare(ctx.strokeStyle, "#000000")
+       ctx.clearRect(0, 0, 1, 1);
+       compare(ctx.strokeStyle, "#000000")
+       canvas.destroy()
+   }
+   function test_saverestore(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       var old = ctx.strokeStyle;
+       ctx.save();
+       ctx.strokeStyle = "#ffaaff";
+       ctx.restore();
+       compare(ctx.strokeStyle, old);
 
-           ctx.strokeStyle = "white";
-           ctx.strokeRect(0,0,1,1);
-           verify(Helper.comparePixel(ctx,0,0,255,255,255,255));
-       }
+       ctx.strokeStyle = "#ffcc88";
+       old = ctx.strokeStyle;
+       ctx.save();
+       compare(ctx.strokeStyle, old);
+       ctx.restore();
+       canvas.destroy()
+   }
+   function test_namedColor(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.strokeStyle = "red";
+       ctx.strokeRect(0,0,1,1);
+       comparePixel(ctx,0,0,255,0,0,255);
 
+       ctx.strokeStyle = "black";
+       ctx.strokeRect(0,0,1,1);
+       comparePixel(ctx,0,0,0,0,0,255);
 
+       ctx.strokeStyle = "white";
+       ctx.strokeRect(0,0,1,1);
+       comparePixel(ctx,0,0,255,255,255,255);
+       canvas.destroy()
    }
 }
index 11618e9..bfc4067 100644 (file)
@@ -1,34 +1,44 @@
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       //TODO
-       name: "text"; when: windowShown
-       function test_baseLine() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_align() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_stroke() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_fill() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_font() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-       function test_measure() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-      }
-   }
+
+CanvasTestCase {
+   id:testCase
+   name: "text"
+   function init_data() { return testData("2d"); }
+   function test_baseLine(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_align(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_stroke(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_fill(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_font(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+   function test_measure(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       canvas.destroy()
+  }
+
 }
index b8505c6..b2f5b51 100644 (file)
 import QtQuick 2.0
-import QtTest 1.0
-import "testhelper.js" as Helper
-Canvas {
-   id:canvas; width:100;height:50; renderTarget: Canvas.Image; renderStrategy:Canvas.Threaded
-   TestCase {
-       name: "transform"; when: windowShown
-       function test_order() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.scale(2, 1);
-           ctx.rotate(Math.PI / 2);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, -50, 50, 50);
-           verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
-      }
-       function test_rotate() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.rotate(Math.PI / 2);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, -100, 50, 100);
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.translate(100, 10);
-           ctx.rotate(Infinity);
-           ctx.rotate(-Infinity);
-           ctx.rotate(NaN);
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-100, -10, 100, 50);
-
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-100, -50, 100, 50);
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi)
-           // We need about pi +/- 0.001 in order to get correct-looking results
-           // 32-bit floats can store pi*4097 with precision 2^-10, so that should
-           // be safe enough on reasonable implementations
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-100, -50, 100, 50);
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  98,2, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  98,47, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.rotate(-Math.PI * (1 + 4096));
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-100, -50, 100, 50);
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  98,2, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  98,47, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.rotate(0);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-
-
-      }
-       function test_scale() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.scale(2, 4);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 50, 12.5);
-           verify(Helper.comparePixel(ctx,  90,40, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.scale(1e5, 1e5);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 1, 1);
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.scale(Math.sqrt(2), Math.sqrt(2));
-           ctx.scale(Math.sqrt(2), Math.sqrt(2));
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 50, 25);
-           verify(Helper.comparePixel(ctx,  90,40, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.save();
-           ctx.scale(-1, 1);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-50, 0, 50, 50);
-           ctx.restore();
-
-           ctx.save();
-           ctx.scale(1, -1);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(50, -50, 50, 50);
-           ctx.restore();
-           verify(Helper.comparePixel(ctx,  25,25, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  75,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.translate(100, 10);
-           ctx.scale(Infinity, 0.1);
-           ctx.scale(-Infinity, 0.1);
-           ctx.scale(NaN, 0.1);
-           ctx.scale(0.1, Infinity);
-           ctx.scale(0.1, -Infinity);
-           ctx.scale(0.1, NaN);
-           ctx.scale(Infinity, Infinity);
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-100, -10, 100, 50);
-
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.save();
-           ctx.translate(50, 0);
-           ctx.scale(0, 1);
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.restore();
-
-           ctx.save();
-           ctx.translate(0, 25);
-           ctx.scale(1, 0);
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.restore();
-
-           // Firefox has a bug where it renders the canvas as empty and toDataURL throws an exception
-           canvas.toDataURL();
-
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-       }
-       function test_setTransform() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.setTransform(1/2,0, 0,1/2, 0,0);
-           ctx.setTransform(2,0, 0,2, 0,0);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 50, 25);
-           verify(Helper.comparePixel(ctx,  75,35, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.translate(100, 10);
-           ctx.setTransform(Infinity, 0, 0, 0, 0, 0);
-           ctx.setTransform(-Infinity, 0, 0, 0, 0, 0);
-           ctx.setTransform(NaN, 0, 0, 0, 0, 0);
-           ctx.setTransform(0, Infinity, 0, 0, 0, 0);
-           ctx.setTransform(0, -Infinity, 0, 0, 0, 0);
-           ctx.setTransform(0, NaN, 0, 0, 0, 0);
-           ctx.setTransform(0, 0, Infinity, 0, 0, 0);
-           ctx.setTransform(0, 0, -Infinity, 0, 0, 0);
-           ctx.setTransform(0, 0, NaN, 0, 0, 0);
-           ctx.setTransform(0, 0, 0, Infinity, 0, 0);
-           ctx.setTransform(0, 0, 0, -Infinity, 0, 0);
-           ctx.setTransform(0, 0, 0, NaN, 0, 0);
-           ctx.setTransform(0, 0, 0, 0, Infinity, 0);
-           ctx.setTransform(0, 0, 0, 0, -Infinity, 0);
-           ctx.setTransform(0, 0, 0, 0, NaN, 0);
-           ctx.setTransform(0, 0, 0, 0, 0, Infinity);
-           ctx.setTransform(0, 0, 0, 0, 0, -Infinity);
-           ctx.setTransform(0, 0, 0, 0, 0, NaN);
-           ctx.setTransform(Infinity, Infinity, 0, 0, 0, 0);
-           ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, 0);
-           ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, 0);
-           ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
-           ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
-           ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, 0);
-           ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, Infinity);
-           ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, 0);
-           ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, 0);
-           ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, Infinity);
-           ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, 0);
-           ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, Infinity);
-           ctx.setTransform(Infinity, Infinity, 0, 0, 0, Infinity);
-           ctx.setTransform(Infinity, 0, Infinity, 0, 0, 0);
-           ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, 0);
-           ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, 0);
-           ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
-           ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, Infinity);
-           ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, 0);
-           ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, Infinity);
-           ctx.setTransform(Infinity, 0, Infinity, 0, 0, Infinity);
-           ctx.setTransform(Infinity, 0, 0, Infinity, 0, 0);
-           ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, 0);
-           ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, Infinity);
-           ctx.setTransform(Infinity, 0, 0, Infinity, 0, Infinity);
-           ctx.setTransform(Infinity, 0, 0, 0, Infinity, 0);
-           ctx.setTransform(Infinity, 0, 0, 0, Infinity, Infinity);
-           ctx.setTransform(Infinity, 0, 0, 0, 0, Infinity);
-           ctx.setTransform(0, Infinity, Infinity, 0, 0, 0);
-           ctx.setTransform(0, Infinity, Infinity, Infinity, 0, 0);
-           ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, 0);
-           ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.setTransform(0, Infinity, Infinity, Infinity, 0, Infinity);
-           ctx.setTransform(0, Infinity, Infinity, 0, Infinity, 0);
-           ctx.setTransform(0, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.setTransform(0, Infinity, Infinity, 0, 0, Infinity);
-           ctx.setTransform(0, Infinity, 0, Infinity, 0, 0);
-           ctx.setTransform(0, Infinity, 0, Infinity, Infinity, 0);
-           ctx.setTransform(0, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.setTransform(0, Infinity, 0, Infinity, 0, Infinity);
-           ctx.setTransform(0, Infinity, 0, 0, Infinity, 0);
-           ctx.setTransform(0, Infinity, 0, 0, Infinity, Infinity);
-           ctx.setTransform(0, Infinity, 0, 0, 0, Infinity);
-           ctx.setTransform(0, 0, Infinity, Infinity, 0, 0);
-           ctx.setTransform(0, 0, Infinity, Infinity, Infinity, 0);
-           ctx.setTransform(0, 0, Infinity, Infinity, Infinity, Infinity);
-           ctx.setTransform(0, 0, Infinity, Infinity, 0, Infinity);
-           ctx.setTransform(0, 0, Infinity, 0, Infinity, 0);
-           ctx.setTransform(0, 0, Infinity, 0, Infinity, Infinity);
-           ctx.setTransform(0, 0, Infinity, 0, 0, Infinity);
-           ctx.setTransform(0, 0, 0, Infinity, Infinity, 0);
-           ctx.setTransform(0, 0, 0, Infinity, Infinity, Infinity);
-           ctx.setTransform(0, 0, 0, Infinity, 0, Infinity);
-           ctx.setTransform(0, 0, 0, 0, Infinity, Infinity);
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-100, -10, 100, 50);
-
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           ctx.reset();
-
-           // Create green with a red square ring inside it
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(20, 10, 60, 30);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(40, 20, 20, 10);
-
-           // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
-           ctx.setTransform(1,4, 2,3, 5,6);
-           // Post-transform coordinates:
-           //   [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
-           // Hence pre-transform coordinates:
-           var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
-                    [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
-                    [-7.4,11.2]];
-           ctx.beginPath();
-           ctx.moveTo(pts[0][0], pts[0][1]);
-           for (var i = 0; i < pts.length; ++i)
-               ctx.lineTo(pts[i][0], pts[i][1]);
-           ctx.fill();
-           /*
-            //FIXME:
-           verify(Helper.comparePixel(ctx,  21,11, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  79,11, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  21,39, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  79,39, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  39,19, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  61,19, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  39,31, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  61,31, 0,255,0,255));
-           */
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.transform(1,0, 0,1, 0,0);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-
-      }
-       function test_transform() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.transform(1,2, 3,4, 5,6);
-           ctx.transform(-2,1, 3/2,-1/2, 1,-2);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.translate(100, 10);
-           ctx.transform(Infinity, 0, 0, 0, 0, 0);
-           ctx.transform(-Infinity, 0, 0, 0, 0, 0);
-           ctx.transform(NaN, 0, 0, 0, 0, 0);
-           ctx.transform(0, Infinity, 0, 0, 0, 0);
-           ctx.transform(0, -Infinity, 0, 0, 0, 0);
-           ctx.transform(0, NaN, 0, 0, 0, 0);
-           ctx.transform(0, 0, Infinity, 0, 0, 0);
-           ctx.transform(0, 0, -Infinity, 0, 0, 0);
-           ctx.transform(0, 0, NaN, 0, 0, 0);
-           ctx.transform(0, 0, 0, Infinity, 0, 0);
-           ctx.transform(0, 0, 0, -Infinity, 0, 0);
-           ctx.transform(0, 0, 0, NaN, 0, 0);
-           ctx.transform(0, 0, 0, 0, Infinity, 0);
-           ctx.transform(0, 0, 0, 0, -Infinity, 0);
-           ctx.transform(0, 0, 0, 0, NaN, 0);
-           ctx.transform(0, 0, 0, 0, 0, Infinity);
-           ctx.transform(0, 0, 0, 0, 0, -Infinity);
-           ctx.transform(0, 0, 0, 0, 0, NaN);
-           ctx.transform(Infinity, Infinity, 0, 0, 0, 0);
-           ctx.transform(Infinity, Infinity, Infinity, 0, 0, 0);
-           ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, 0);
-           ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
-           ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
-           ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, 0);
-           ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.transform(Infinity, Infinity, Infinity, 0, 0, Infinity);
-           ctx.transform(Infinity, Infinity, 0, Infinity, 0, 0);
-           ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, 0);
-           ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.transform(Infinity, Infinity, 0, Infinity, 0, Infinity);
-           ctx.transform(Infinity, Infinity, 0, 0, Infinity, 0);
-           ctx.transform(Infinity, Infinity, 0, 0, Infinity, Infinity);
-           ctx.transform(Infinity, Infinity, 0, 0, 0, Infinity);
-           ctx.transform(Infinity, 0, Infinity, 0, 0, 0);
-           ctx.transform(Infinity, 0, Infinity, Infinity, 0, 0);
-           ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, 0);
-           ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
-           ctx.transform(Infinity, 0, Infinity, Infinity, 0, Infinity);
-           ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0);
-           ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0);
-           ctx.transform(Infinity, 0, Infinity, 0, Infinity, Infinity);
-           ctx.transform(Infinity, 0, Infinity, 0, 0, Infinity);
-           ctx.transform(Infinity, 0, 0, Infinity, 0, 0);
-           ctx.transform(Infinity, 0, 0, Infinity, Infinity, 0);
-           ctx.transform(Infinity, 0, 0, Infinity, Infinity, Infinity);
-           ctx.transform(Infinity, 0, 0, Infinity, 0, Infinity);
-           ctx.transform(Infinity, 0, 0, 0, Infinity, 0);
-           ctx.transform(Infinity, 0, 0, 0, Infinity, Infinity);
-           ctx.transform(Infinity, 0, 0, 0, 0, Infinity);
-           ctx.transform(0, Infinity, Infinity, 0, 0, 0);
-           ctx.transform(0, Infinity, Infinity, Infinity, 0, 0);
-           ctx.transform(0, Infinity, Infinity, Infinity, Infinity, 0);
-           ctx.transform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
-           ctx.transform(0, Infinity, Infinity, Infinity, 0, Infinity);
-           ctx.transform(0, Infinity, Infinity, 0, Infinity, 0);
-           ctx.transform(0, Infinity, Infinity, 0, Infinity, Infinity);
-           ctx.transform(0, Infinity, Infinity, 0, 0, Infinity);
-           ctx.transform(0, Infinity, 0, Infinity, 0, 0);
-           ctx.transform(0, Infinity, 0, Infinity, Infinity, 0);
-           ctx.transform(0, Infinity, 0, Infinity, Infinity, Infinity);
-           ctx.transform(0, Infinity, 0, Infinity, 0, Infinity);
-           ctx.transform(0, Infinity, 0, 0, Infinity, 0);
-           ctx.transform(0, Infinity, 0, 0, Infinity, Infinity);
-           ctx.transform(0, Infinity, 0, 0, 0, Infinity);
-           ctx.transform(0, 0, Infinity, Infinity, 0, 0);
-           ctx.transform(0, 0, Infinity, Infinity, Infinity, 0);
-           ctx.transform(0, 0, Infinity, Infinity, Infinity, Infinity);
-           ctx.transform(0, 0, Infinity, Infinity, 0, Infinity);
-           ctx.transform(0, 0, Infinity, 0, Infinity, 0);
-           ctx.transform(0, 0, Infinity, 0, Infinity, Infinity);
-           ctx.transform(0, 0, Infinity, 0, 0, Infinity);
-           ctx.transform(0, 0, 0, Infinity, Infinity, 0);
-           ctx.transform(0, 0, 0, Infinity, Infinity, Infinity);
-           ctx.transform(0, 0, 0, Infinity, 0, Infinity);
-           ctx.transform(0, 0, 0, 0, Infinity, Infinity);
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-100, -10, 100, 50);
-
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-           ctx.reset();
-
-           // Create green with a red square ring inside it
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(0, 0, 100, 50);
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(20, 10, 60, 30);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(40, 20, 20, 10);
-
-           // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
-           ctx.transform(1,4, 2,3, 5,6);
-           // Post-transform coordinates:
-           //   [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
-           // Hence pre-transform coordinates:
-           var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
-                    [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
-                    [-7.4,11.2]];
-           ctx.beginPath();
-           ctx.moveTo(pts[0][0], pts[0][1]);
-           for (var i = 0; i < pts.length; ++i)
-               ctx.lineTo(pts[i][0], pts[i][1]);
-           ctx.fill();
-           /*
-             //FIXME:
-           verify(Helper.comparePixel(ctx,  21,11, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  79,11, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  21,39, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  79,39, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  39,19, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  61,19, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  39,31, 0,255,0,255));
-           verify(Helper.comparePixel(ctx,  61,31, 0,255,0,255));
-           */
-      }
-       function test_translate() {
-           var ctx = canvas.getContext('2d');
-           ctx.reset();
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.translate(100, 50);
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-100, -50, 100, 50);
-           verify(Helper.comparePixel(ctx,  90,40, 0,255,0,255));
-           ctx.reset();
-
-           ctx.fillStyle = '#f00';
-           ctx.fillRect(0, 0, 100, 50);
-
-           ctx.translate(100, 10);
-           ctx.translate(Infinity, 0.1);
-           ctx.translate(-Infinity, 0.1);
-           ctx.translate(NaN, 0.1);
-           ctx.translate(0.1, Infinity);
-           ctx.translate(0.1, -Infinity);
-           ctx.translate(0.1, NaN);
-           ctx.translate(Infinity, Infinity);
-
-           ctx.fillStyle = '#0f0';
-           ctx.fillRect(-100, -10, 100, 50);
-
-           verify(Helper.comparePixel(ctx,  50,25, 0,255,0,255));
-
-
-      }
+
+CanvasTestCase {
+   id:testCase
+   name: "transform"
+   function init_data() { return testData("2d"); }
+   function test_order(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.scale(2, 1);
+       ctx.rotate(Math.PI / 2);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, -50, 50, 50);
+       comparePixel(ctx, 75,25, 0,255,0,255);
+       canvas.destroy()
+  }
+   function test_rotate(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.rotate(Math.PI / 2);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, -100, 50, 100);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.translate(100, 10);
+       ctx.rotate(Infinity);
+       ctx.rotate(-Infinity);
+       ctx.rotate(NaN);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-100, -10, 100, 50);
+
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-100, -50, 100, 50);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi)
+       // We need about pi +/- 0.001 in order to get correct-looking results
+       // 32-bit floats can store pi*4097 with precision 2^-10, so that should
+       // be safe enough on reasonable implementations
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-100, -50, 100, 50);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       comparePixel(ctx,  98,2, 0,255,0,255);
+       comparePixel(ctx,  98,47, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.rotate(-Math.PI * (1 + 4096));
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-100, -50, 100, 50);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       comparePixel(ctx,  98,2, 0,255,0,255);
+       comparePixel(ctx,  98,47, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.rotate(0);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       canvas.destroy()
+  }
+   function test_scale(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.scale(2, 4);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 50, 12.5);
+       comparePixel(ctx,  90,40, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.scale(1e5, 1e5);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 1, 1);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.scale(Math.sqrt(2), Math.sqrt(2));
+       ctx.scale(Math.sqrt(2), Math.sqrt(2));
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 50, 25);
+       comparePixel(ctx,  90,40, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.save();
+       ctx.scale(-1, 1);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-50, 0, 50, 50);
+       ctx.restore();
+
+       ctx.save();
+       ctx.scale(1, -1);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(50, -50, 50, 50);
+       ctx.restore();
+       comparePixel(ctx,  25,25, 0,255,0,255);
+       comparePixel(ctx,  75,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.translate(100, 10);
+       ctx.scale(Infinity, 0.1);
+       ctx.scale(-Infinity, 0.1);
+       ctx.scale(NaN, 0.1);
+       ctx.scale(0.1, Infinity);
+       ctx.scale(0.1, -Infinity);
+       ctx.scale(0.1, NaN);
+       ctx.scale(Infinity, Infinity);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-100, -10, 100, 50);
+
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.save();
+       ctx.translate(50, 0);
+       ctx.scale(0, 1);
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.restore();
+
+       ctx.save();
+       ctx.translate(0, 25);
+       ctx.scale(1, 0);
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.restore();
+
+       // Firefox has a bug where it renders the canvas as empty and toDataURL throws an exception
+       canvas.toDataURL();
+
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       canvas.destroy()
    }
+   function test_setTransform(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.setTransform(1/2,0, 0,1/2, 0,0);
+       ctx.setTransform(2,0, 0,2, 0,0);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 50, 25);
+       comparePixel(ctx,  75,35, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.translate(100, 10);
+       ctx.setTransform(Infinity, 0, 0, 0, 0, 0);
+       ctx.setTransform(-Infinity, 0, 0, 0, 0, 0);
+       ctx.setTransform(NaN, 0, 0, 0, 0, 0);
+       ctx.setTransform(0, Infinity, 0, 0, 0, 0);
+       ctx.setTransform(0, -Infinity, 0, 0, 0, 0);
+       ctx.setTransform(0, NaN, 0, 0, 0, 0);
+       ctx.setTransform(0, 0, Infinity, 0, 0, 0);
+       ctx.setTransform(0, 0, -Infinity, 0, 0, 0);
+       ctx.setTransform(0, 0, NaN, 0, 0, 0);
+       ctx.setTransform(0, 0, 0, Infinity, 0, 0);
+       ctx.setTransform(0, 0, 0, -Infinity, 0, 0);
+       ctx.setTransform(0, 0, 0, NaN, 0, 0);
+       ctx.setTransform(0, 0, 0, 0, Infinity, 0);
+       ctx.setTransform(0, 0, 0, 0, -Infinity, 0);
+       ctx.setTransform(0, 0, 0, 0, NaN, 0);
+       ctx.setTransform(0, 0, 0, 0, 0, Infinity);
+       ctx.setTransform(0, 0, 0, 0, 0, -Infinity);
+       ctx.setTransform(0, 0, 0, 0, 0, NaN);
+       ctx.setTransform(Infinity, Infinity, 0, 0, 0, 0);
+       ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, 0);
+       ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+       ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+       ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+       ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+       ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+       ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, 0);
+       ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+       ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+       ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, 0);
+       ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+       ctx.setTransform(Infinity, Infinity, 0, 0, 0, Infinity);
+       ctx.setTransform(Infinity, 0, Infinity, 0, 0, 0);
+       ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, 0);
+       ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+       ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+       ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+       ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, 0);
+       ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+       ctx.setTransform(Infinity, 0, Infinity, 0, 0, Infinity);
+       ctx.setTransform(Infinity, 0, 0, Infinity, 0, 0);
+       ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, 0);
+       ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+       ctx.setTransform(Infinity, 0, 0, Infinity, 0, Infinity);
+       ctx.setTransform(Infinity, 0, 0, 0, Infinity, 0);
+       ctx.setTransform(Infinity, 0, 0, 0, Infinity, Infinity);
+       ctx.setTransform(Infinity, 0, 0, 0, 0, Infinity);
+       ctx.setTransform(0, Infinity, Infinity, 0, 0, 0);
+       ctx.setTransform(0, Infinity, Infinity, Infinity, 0, 0);
+       ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, 0);
+       ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.setTransform(0, Infinity, Infinity, Infinity, 0, Infinity);
+       ctx.setTransform(0, Infinity, Infinity, 0, Infinity, 0);
+       ctx.setTransform(0, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.setTransform(0, Infinity, Infinity, 0, 0, Infinity);
+       ctx.setTransform(0, Infinity, 0, Infinity, 0, 0);
+       ctx.setTransform(0, Infinity, 0, Infinity, Infinity, 0);
+       ctx.setTransform(0, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.setTransform(0, Infinity, 0, Infinity, 0, Infinity);
+       ctx.setTransform(0, Infinity, 0, 0, Infinity, 0);
+       ctx.setTransform(0, Infinity, 0, 0, Infinity, Infinity);
+       ctx.setTransform(0, Infinity, 0, 0, 0, Infinity);
+       ctx.setTransform(0, 0, Infinity, Infinity, 0, 0);
+       ctx.setTransform(0, 0, Infinity, Infinity, Infinity, 0);
+       ctx.setTransform(0, 0, Infinity, Infinity, Infinity, Infinity);
+       ctx.setTransform(0, 0, Infinity, Infinity, 0, Infinity);
+       ctx.setTransform(0, 0, Infinity, 0, Infinity, 0);
+       ctx.setTransform(0, 0, Infinity, 0, Infinity, Infinity);
+       ctx.setTransform(0, 0, Infinity, 0, 0, Infinity);
+       ctx.setTransform(0, 0, 0, Infinity, Infinity, 0);
+       ctx.setTransform(0, 0, 0, Infinity, Infinity, Infinity);
+       ctx.setTransform(0, 0, 0, Infinity, 0, Infinity);
+       ctx.setTransform(0, 0, 0, 0, Infinity, Infinity);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-100, -10, 100, 50);
+
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       ctx.reset();
+
+       // Create green with a red square ring inside it
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(20, 10, 60, 30);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(40, 20, 20, 10);
+
+       // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+       ctx.setTransform(1,4, 2,3, 5,6);
+       // Post-transform coordinates:
+       //   [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+       // Hence pre-transform coordinates:
+       var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+                [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+                [-7.4,11.2]];
+       ctx.beginPath();
+       ctx.moveTo(pts[0][0], pts[0][1]);
+       for (var i = 0; i < pts.length; ++i)
+           ctx.lineTo(pts[i][0], pts[i][1]);
+       ctx.fill();
+       /*
+        //FIXME:
+       comparePixel(ctx,  21,11, 0,255,0,255);
+       comparePixel(ctx,  79,11, 0,255,0,255);
+       comparePixel(ctx,  21,39, 0,255,0,255);
+       comparePixel(ctx,  79,39, 0,255,0,255);
+       comparePixel(ctx,  39,19, 0,255,0,255);
+       comparePixel(ctx,  61,19, 0,255,0,255);
+       comparePixel(ctx,  39,31, 0,255,0,255);
+       comparePixel(ctx,  61,31, 0,255,0,255);
+       */
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.transform(1,0, 0,1, 0,0);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       canvas.destroy()
+  }
+   function test_transform(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.transform(1,2, 3,4, 5,6);
+       ctx.transform(-2,1, 3/2,-1/2, 1,-2);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.translate(100, 10);
+       ctx.transform(Infinity, 0, 0, 0, 0, 0);
+       ctx.transform(-Infinity, 0, 0, 0, 0, 0);
+       ctx.transform(NaN, 0, 0, 0, 0, 0);
+       ctx.transform(0, Infinity, 0, 0, 0, 0);
+       ctx.transform(0, -Infinity, 0, 0, 0, 0);
+       ctx.transform(0, NaN, 0, 0, 0, 0);
+       ctx.transform(0, 0, Infinity, 0, 0, 0);
+       ctx.transform(0, 0, -Infinity, 0, 0, 0);
+       ctx.transform(0, 0, NaN, 0, 0, 0);
+       ctx.transform(0, 0, 0, Infinity, 0, 0);
+       ctx.transform(0, 0, 0, -Infinity, 0, 0);
+       ctx.transform(0, 0, 0, NaN, 0, 0);
+       ctx.transform(0, 0, 0, 0, Infinity, 0);
+       ctx.transform(0, 0, 0, 0, -Infinity, 0);
+       ctx.transform(0, 0, 0, 0, NaN, 0);
+       ctx.transform(0, 0, 0, 0, 0, Infinity);
+       ctx.transform(0, 0, 0, 0, 0, -Infinity);
+       ctx.transform(0, 0, 0, 0, 0, NaN);
+       ctx.transform(Infinity, Infinity, 0, 0, 0, 0);
+       ctx.transform(Infinity, Infinity, Infinity, 0, 0, 0);
+       ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+       ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+       ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+       ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+       ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.transform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+       ctx.transform(Infinity, Infinity, 0, Infinity, 0, 0);
+       ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+       ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.transform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+       ctx.transform(Infinity, Infinity, 0, 0, Infinity, 0);
+       ctx.transform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+       ctx.transform(Infinity, Infinity, 0, 0, 0, Infinity);
+       ctx.transform(Infinity, 0, Infinity, 0, 0, 0);
+       ctx.transform(Infinity, 0, Infinity, Infinity, 0, 0);
+       ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+       ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+       ctx.transform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+       ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0);
+       ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0);
+       ctx.transform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+       ctx.transform(Infinity, 0, Infinity, 0, 0, Infinity);
+       ctx.transform(Infinity, 0, 0, Infinity, 0, 0);
+       ctx.transform(Infinity, 0, 0, Infinity, Infinity, 0);
+       ctx.transform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+       ctx.transform(Infinity, 0, 0, Infinity, 0, Infinity);
+       ctx.transform(Infinity, 0, 0, 0, Infinity, 0);
+       ctx.transform(Infinity, 0, 0, 0, Infinity, Infinity);
+       ctx.transform(Infinity, 0, 0, 0, 0, Infinity);
+       ctx.transform(0, Infinity, Infinity, 0, 0, 0);
+       ctx.transform(0, Infinity, Infinity, Infinity, 0, 0);
+       ctx.transform(0, Infinity, Infinity, Infinity, Infinity, 0);
+       ctx.transform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+       ctx.transform(0, Infinity, Infinity, Infinity, 0, Infinity);
+       ctx.transform(0, Infinity, Infinity, 0, Infinity, 0);
+       ctx.transform(0, Infinity, Infinity, 0, Infinity, Infinity);
+       ctx.transform(0, Infinity, Infinity, 0, 0, Infinity);
+       ctx.transform(0, Infinity, 0, Infinity, 0, 0);
+       ctx.transform(0, Infinity, 0, Infinity, Infinity, 0);
+       ctx.transform(0, Infinity, 0, Infinity, Infinity, Infinity);
+       ctx.transform(0, Infinity, 0, Infinity, 0, Infinity);
+       ctx.transform(0, Infinity, 0, 0, Infinity, 0);
+       ctx.transform(0, Infinity, 0, 0, Infinity, Infinity);
+       ctx.transform(0, Infinity, 0, 0, 0, Infinity);
+       ctx.transform(0, 0, Infinity, Infinity, 0, 0);
+       ctx.transform(0, 0, Infinity, Infinity, Infinity, 0);
+       ctx.transform(0, 0, Infinity, Infinity, Infinity, Infinity);
+       ctx.transform(0, 0, Infinity, Infinity, 0, Infinity);
+       ctx.transform(0, 0, Infinity, 0, Infinity, 0);
+       ctx.transform(0, 0, Infinity, 0, Infinity, Infinity);
+       ctx.transform(0, 0, Infinity, 0, 0, Infinity);
+       ctx.transform(0, 0, 0, Infinity, Infinity, 0);
+       ctx.transform(0, 0, 0, Infinity, Infinity, Infinity);
+       ctx.transform(0, 0, 0, Infinity, 0, Infinity);
+       ctx.transform(0, 0, 0, 0, Infinity, Infinity);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-100, -10, 100, 50);
+
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       ctx.reset();
+
+       // Create green with a red square ring inside it
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(0, 0, 100, 50);
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(20, 10, 60, 30);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(40, 20, 20, 10);
+
+       // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+       ctx.transform(1,4, 2,3, 5,6);
+       // Post-transform coordinates:
+       //   [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+       // Hence pre-transform coordinates:
+       var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+                [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+                [-7.4,11.2]];
+       ctx.beginPath();
+       ctx.moveTo(pts[0][0], pts[0][1]);
+       for (var i = 0; i < pts.length; ++i)
+           ctx.lineTo(pts[i][0], pts[i][1]);
+       ctx.fill();
+       /*
+         //FIXME:
+       comparePixel(ctx,  21,11, 0,255,0,255);
+       comparePixel(ctx,  79,11, 0,255,0,255);
+       comparePixel(ctx,  21,39, 0,255,0,255);
+       comparePixel(ctx,  79,39, 0,255,0,255);
+       comparePixel(ctx,  39,19, 0,255,0,255);
+       comparePixel(ctx,  61,19, 0,255,0,255);
+       comparePixel(ctx,  39,31, 0,255,0,255);
+       comparePixel(ctx,  61,31, 0,255,0,255);
+       */
+       canvas.destroy()
+  }
+   function test_translate(row) {
+       var canvas = createCanvasObject(row);
+       var ctx = canvas.getContext('2d');
+       ctx.reset();
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.translate(100, 50);
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-100, -50, 100, 50);
+       comparePixel(ctx,  90,40, 0,255,0,255);
+       ctx.reset();
+
+       ctx.fillStyle = '#f00';
+       ctx.fillRect(0, 0, 100, 50);
+
+       ctx.translate(100, 10);
+       ctx.translate(Infinity, 0.1);
+       ctx.translate(-Infinity, 0.1);
+       ctx.translate(NaN, 0.1);
+       ctx.translate(0.1, Infinity);
+       ctx.translate(0.1, -Infinity);
+       ctx.translate(0.1, NaN);
+       ctx.translate(Infinity, Infinity);
+
+       ctx.fillStyle = '#0f0';
+       ctx.fillRect(-100, -10, 100, 50);
+
+       comparePixel(ctx,  50,25, 0,255,0,255);
+       canvas.destroy()
+  }
 }