]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Introduce unit test based on image comparison (#3988)
authorSimon Brunel <simonbrunel@users.noreply.github.com>
Sun, 5 Mar 2017 16:49:12 +0000 (17:49 +0100)
committerTanner Linsley <tannerlinsley@gmail.com>
Sun, 5 Mar 2017 16:49:12 +0000 (09:49 -0700)
Attempt to make easier the creation of unit tests that check the drawing output. Until now, this was done by checking calls on a 'fake' context, which is hard to maintain (need to update pixel values by hands) and also not reliable when optimizing code (i.e. different calls sequence but same result).

As of now, it's possible to define 'auto' tests based on JSON/PNG fixtures: chart is generated from the JSON file and compared to the associated PNG image. The image diff is done using `pixelmatch`. As an example (and in preparation of the `filler` plugin), add auto tests for the line element `fill` options.

30 files changed:
gulpfile.js
package.json
test/fixtures/element.line/fill-line-bottom-span.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-bottom-span.png [new file with mode: 0644]
test/fixtures/element.line/fill-line-bottom.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-bottom.png [new file with mode: 0644]
test/fixtures/element.line/fill-line-spline-span.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-spline-span.png [new file with mode: 0644]
test/fixtures/element.line/fill-line-spline.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-spline.png [new file with mode: 0644]
test/fixtures/element.line/fill-line-stepped-span.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-stepped-span.png [new file with mode: 0644]
test/fixtures/element.line/fill-line-stepped.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-stepped.png [new file with mode: 0644]
test/fixtures/element.line/fill-line-top-span.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-top-span.png [new file with mode: 0644]
test/fixtures/element.line/fill-line-top.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-top.png [new file with mode: 0644]
test/fixtures/element.line/fill-line-zero-span.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-zero-span.png [new file with mode: 0644]
test/fixtures/element.line/fill-line-zero.json [new file with mode: 0644]
test/fixtures/element.line/fill-line-zero.png [new file with mode: 0644]
test/fixtures/element.line/fill-radar-spline.json [new file with mode: 0644]
test/fixtures/element.line/fill-radar-spline.png [new file with mode: 0644]
test/fixtures/element.line/fill-radar-zero.json [new file with mode: 0644]
test/fixtures/element.line/fill-radar-zero.png [new file with mode: 0644]
test/jasmine.index.js
test/jasmine.matchers.js
test/jasmine.utils.js
test/specs/element.line.tests.js

index 86800169631b1c214488772805f097d46310baa6..c9d60471333ca6d7ed60f0705d10e57174468b46 100644 (file)
@@ -171,6 +171,8 @@ function validHTMLTask() {
 
 function startTest() {
   return [
+    {pattern: './test/fixtures/**/*.json', included: false},
+    {pattern: './test/fixtures/**/*.png', included: false},
     './node_modules/moment/min/moment.min.js',
     './test/jasmine.index.js',
     './src/**/*.js',
index 374f90d17a578514e79e73647b287cfbf7d77018..24a313f4b29a604950d5df6caefec08416fff261 100644 (file)
@@ -37,6 +37,7 @@
     "karma-jasmine": "^1.1.0",
     "karma-jasmine-html-reporter": "^0.2.2",
     "merge-stream": "^1.0.0",
+    "pixelmatch": "^4.0.2",
     "vinyl-source-stream": "^1.1.0",
     "watchify": "^3.7.0",
     "yargs": "^5.0.0"
diff --git a/test/fixtures/element.line/fill-line-bottom-span.json b/test/fixtures/element.line/fill-line-bottom-span.json
new file mode 100644 (file)
index 0000000..ec6bb4b
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 255, 0.25)",
+                "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+            }, {
+                "backgroundColor": "rgba(0, 255, 0, 0.25)",
+                "data": [6, 2, null, 4, 5, null, null, 2, 1]
+            }, {
+                "backgroundColor": "rgba(255, 0, 0, 0.25)",
+                "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+            }, {
+                "backgroundColor": "rgba(0, 0, 255, 0.25)",
+                "data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": true,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "fill": "bottom",
+                    "tension": 0
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-bottom-span.png b/test/fixtures/element.line/fill-line-bottom-span.png
new file mode 100644 (file)
index 0000000..45e4992
Binary files /dev/null and b/test/fixtures/element.line/fill-line-bottom-span.png differ
diff --git a/test/fixtures/element.line/fill-line-bottom.json b/test/fixtures/element.line/fill-line-bottom.json
new file mode 100644 (file)
index 0000000..a0557fe
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 255, 0.25)",
+                "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+            }, {
+                "backgroundColor": "rgba(0, 255, 0, 0.25)",
+                "data": [6, 2, null, 4, 5, null, null, 2, 1]
+            }, {
+                "backgroundColor": "rgba(255, 0, 0, 0.25)",
+                "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+            }, {
+                "backgroundColor": "rgba(0, 0, 255, 0.25)",
+                "data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": false,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "fill": "bottom",
+                    "tension": 0
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-bottom.png b/test/fixtures/element.line/fill-line-bottom.png
new file mode 100644 (file)
index 0000000..1cd05e6
Binary files /dev/null and b/test/fixtures/element.line/fill-line-bottom.png differ
diff --git a/test/fixtures/element.line/fill-line-spline-span.json b/test/fixtures/element.line/fill-line-spline-span.json
new file mode 100644 (file)
index 0000000..c87833b
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+            }, {
+                "backgroundColor": "rgba(128, 0, 128, 0.25)",
+                "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": true,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "cubicInterpolationMode": "monotone",
+                    "borderColor": "transparent",
+                    "fill": "zero"
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-spline-span.png b/test/fixtures/element.line/fill-line-spline-span.png
new file mode 100644 (file)
index 0000000..01aae5a
Binary files /dev/null and b/test/fixtures/element.line/fill-line-spline-span.png differ
diff --git a/test/fixtures/element.line/fill-line-spline.json b/test/fixtures/element.line/fill-line-spline.json
new file mode 100644 (file)
index 0000000..543b8cd
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+            }, {
+                "backgroundColor": "rgba(128, 0, 128, 0.25)",
+                "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": false,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "cubicInterpolationMode": "monotone",
+                    "borderColor": "transparent",
+                    "fill": "zero"
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-spline.png b/test/fixtures/element.line/fill-line-spline.png
new file mode 100644 (file)
index 0000000..b2ec179
Binary files /dev/null and b/test/fixtures/element.line/fill-line-spline.png differ
diff --git a/test/fixtures/element.line/fill-line-stepped-span.json b/test/fixtures/element.line/fill-line-stepped-span.json
new file mode 100644 (file)
index 0000000..c6f24e1
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+            }, {
+                "backgroundColor": "rgba(128, 0, 128, 0.25)",
+                "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": true,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "cubicInterpolationMode": "monotone",
+                    "borderColor": "transparent",
+                    "stepped": true,
+                    "fill": "zero"
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-stepped-span.png b/test/fixtures/element.line/fill-line-stepped-span.png
new file mode 100644 (file)
index 0000000..9f7c15b
Binary files /dev/null and b/test/fixtures/element.line/fill-line-stepped-span.png differ
diff --git a/test/fixtures/element.line/fill-line-stepped.json b/test/fixtures/element.line/fill-line-stepped.json
new file mode 100644 (file)
index 0000000..3fbdd76
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+            }, {
+                "backgroundColor": "rgba(128, 0, 128, 0.25)",
+                "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": false,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "cubicInterpolationMode": "monotone",
+                    "borderColor": "transparent",
+                    "stepped": true,
+                    "fill": "zero"
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-stepped.png b/test/fixtures/element.line/fill-line-stepped.png
new file mode 100644 (file)
index 0000000..19f5a8d
Binary files /dev/null and b/test/fixtures/element.line/fill-line-stepped.png differ
diff --git a/test/fixtures/element.line/fill-line-top-span.json b/test/fixtures/element.line/fill-line-top-span.json
new file mode 100644 (file)
index 0000000..b74b1f5
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [5.5, 2, null, 4, 5, null, null, 2, 1]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+            }, {
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [8, 7, 6.5, -6, -4, -6, 4, 5, 8]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": true,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "fill": "top",
+                    "tension": 0
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-top-span.png b/test/fixtures/element.line/fill-line-top-span.png
new file mode 100644 (file)
index 0000000..83519b0
Binary files /dev/null and b/test/fixtures/element.line/fill-line-top-span.png differ
diff --git a/test/fixtures/element.line/fill-line-top.json b/test/fixtures/element.line/fill-line-top.json
new file mode 100644 (file)
index 0000000..e0696ba
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [5.5, 2, null, 4, 5, null, null, 2, 1]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+            }, {
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [8, 7, 6.5, -6, -4, -6, 4, 5, 8]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": false,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "fill": "top",
+                    "tension": 0
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-top.png b/test/fixtures/element.line/fill-line-top.png
new file mode 100644 (file)
index 0000000..25c8f13
Binary files /dev/null and b/test/fixtures/element.line/fill-line-top.png differ
diff --git a/test/fixtures/element.line/fill-line-zero-span.json b/test/fixtures/element.line/fill-line-zero-span.json
new file mode 100644 (file)
index 0000000..64fbbb3
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [6, 2, null, 4, 5, null, null, 2, 1]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+            }, {
+                "backgroundColor": "rgba(0, 64, 192, 0.25)",
+                "data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": true,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "fill": "zero",
+                    "tension": 0
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-zero-span.png b/test/fixtures/element.line/fill-line-zero-span.png
new file mode 100644 (file)
index 0000000..727cc03
Binary files /dev/null and b/test/fixtures/element.line/fill-line-zero-span.png differ
diff --git a/test/fixtures/element.line/fill-line-zero.json b/test/fixtures/element.line/fill-line-zero.json
new file mode 100644 (file)
index 0000000..1958fc5
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [6, 2, null, 4, 5, null, null, 2, 1]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+            }, {
+                "backgroundColor": "rgba(0, 64, 192, 0.25)",
+                "data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": false,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "xAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }],
+                "yAxes": [{
+                    "ticks": {
+                        "display": false
+                    }
+                }]
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "fill": "zero",
+                    "tension": 0
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-line-zero.png b/test/fixtures/element.line/fill-line-zero.png
new file mode 100644 (file)
index 0000000..f8f0208
Binary files /dev/null and b/test/fixtures/element.line/fill-line-zero.png differ
diff --git a/test/fixtures/element.line/fill-radar-spline.json b/test/fixtures/element.line/fill-radar-spline.json
new file mode 100644 (file)
index 0000000..c22d8a6
--- /dev/null
@@ -0,0 +1,50 @@
+{
+    "config": {
+        "type": "radar",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+            }, {
+                "backgroundColor": "rgba(128, 0, 128, 0.25)",
+                "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "legend": false,
+            "title": false,
+            "scale": {
+                "pointLabels": {
+                    "fontSize": 0
+                },
+                "ticks": {
+                    "display": false
+                }
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "tension": 0.5,
+                    "fill": "zero"
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 256
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-radar-spline.png b/test/fixtures/element.line/fill-radar-spline.png
new file mode 100644 (file)
index 0000000..29b6c8e
Binary files /dev/null and b/test/fixtures/element.line/fill-radar-spline.png differ
diff --git a/test/fixtures/element.line/fill-radar-zero.json b/test/fixtures/element.line/fill-radar-zero.json
new file mode 100644 (file)
index 0000000..1720079
--- /dev/null
@@ -0,0 +1,49 @@
+{
+    "config": {
+        "type": "radar",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+            }, {
+                "backgroundColor": "rgba(0, 192, 0, 0.25)",
+                "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+            }, {
+                "backgroundColor": "rgba(192, 0, 0, 0.25)",
+                "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+            }, {
+                "backgroundColor": "rgba(128, 0, 128, 0.25)",
+                "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "legend": false,
+            "title": false,
+            "scale": {
+                "pointLabels": {
+                    "fontSize": 0
+                },
+                "ticks": {
+                    "display": false
+                }
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "fill": "zero"
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 256
+        }
+    }
+}
diff --git a/test/fixtures/element.line/fill-radar-zero.png b/test/fixtures/element.line/fill-radar-zero.png
new file mode 100644 (file)
index 0000000..5ede186
Binary files /dev/null and b/test/fixtures/element.line/fill-radar-zero.png differ
index aeaee77c6c41cf83b15ebf35572dda3d303bcad7..55c587ab0a246c5d608b210384c3f23c443176c6 100644 (file)
@@ -37,6 +37,8 @@ var utils = require('./jasmine.utils');
                        'position: absolute' +
                '}');
 
+       jasmine.specsFromFixtures = utils.specsFromFixtures;
+
        beforeEach(function() {
                jasmine.addMatchers(matchers);
        });
index abb90d7789edd767506a9a69b47663a5a47f480b..8a3c9e121a3cee7d0fa36eb7892db2b240d8957e 100644 (file)
@@ -1,5 +1,56 @@
 'use strict';
 
+var pixelmatch = require('pixelmatch');
+var utils = require('./jasmine.utils');
+
+function toPercent(value) {
+       return Math.round(value * 10000) / 100;
+}
+
+function createImageData(w, h) {
+       var canvas = utils.createCanvas(w, h);
+       var context = canvas.getContext('2d');
+       return context.getImageData(0, 0, w, h);
+}
+
+function canvasFromImageData(data) {
+       var canvas = utils.createCanvas(data.width, data.height);
+       var context = canvas.getContext('2d');
+       context.putImageData(data, 0, 0);
+       return canvas;
+}
+
+function buildPixelMatchPreview(actual, expected, diff, threshold, tolerance, count) {
+       var ratio = count / (actual.width * actual.height);
+       var wrapper = document.createElement('div');
+
+       wrapper.style.cssText = 'display: flex; overflow-y: auto';
+
+       [
+               {data: actual, label: 'Actual'},
+               {data: expected, label: 'Expected'},
+               {data: diff, label:
+                       'diff: ' + count + 'px ' +
+                       '(' + toPercent(ratio) + '%)<br/>' +
+                       'thr: ' + toPercent(threshold) + '%, ' +
+                       'tol: '+ toPercent(tolerance) + '%'
+               }
+       ].forEach(function(values) {
+               var item = document.createElement('div');
+               item.style.cssText = 'text-align: center; font: 12px monospace; line-height: 1.4; margin: 8px';
+               item.innerHTML = '<div style="margin: 8px; height: 32px">' + values.label + '</div>';
+               item.appendChild(canvasFromImageData(values.data));
+               wrapper.appendChild(item);
+       });
+
+       // WORKAROUND: https://github.com/karma-runner/karma-jasmine/issues/139
+       wrapper.indexOf = function() {
+               return -1;
+       };
+
+       return wrapper;
+}
+
 function toBeCloseToPixel() {
        return {
                compare: function(actual, expected) {
@@ -105,9 +156,50 @@ function toBeChartOfSize() {
        };
 }
 
+function toEqualImageData() {
+       return {
+               compare: function(actual, expected, opts) {
+                       var message = null;
+                       var debug = opts.debug || false;
+                       var tolerance = opts.tolerance === undefined? 0.001 : opts.tolerance;
+                       var threshold = opts.threshold === undefined? 0.1 : opts.threshold;
+                       var ctx, idata, ddata, w, h, count, ratio;
+
+                       if (actual instanceof Chart) {
+                               ctx = actual.ctx;
+                       } else if (actual instanceof HTMLCanvasElement) {
+                               ctx = actual.getContext('2d');
+                       } else if (actual instanceof CanvasRenderingContext2D) {
+                               ctx = actual;
+                       }
+
+                       if (ctx) {
+                               h = expected.height;
+                               w = expected.width;
+                               idata = ctx.getImageData(0, 0, w, h);
+                               ddata = createImageData(w, h);
+                               count = pixelmatch(idata.data, expected.data, ddata.data, w, h, {threshold: threshold});
+                               ratio = count / (w * h);
+
+                               if ((ratio > tolerance) || debug) {
+                                       message = buildPixelMatchPreview(idata, expected, ddata, threshold, tolerance, count);
+                               }
+                       } else {
+                               message = 'Input value is not a valid image source.';
+                       }
+
+                       return {
+                               message: message,
+                               pass: !message
+                       };
+               }
+       };
+}
+
 module.exports = {
        toBeCloseToPixel: toBeCloseToPixel,
        toEqualOneOf: toEqualOneOf,
        toBeValidChart: toBeValidChart,
-       toBeChartOfSize: toBeChartOfSize
+       toBeChartOfSize: toBeChartOfSize,
+       toEqualImageData: toEqualImageData
 };
index 77f05c6e008856fbee5d97960087cd7d5b70e48e..f5ead49ec09a348783c17b57bd3cef0f7190d348 100644 (file)
@@ -1,3 +1,40 @@
+/* global __karma__ */
+
+function loadJSON(url, callback) {
+       var request = new XMLHttpRequest();
+       request.onreadystatechange = function() {
+               if (request.readyState === 4) {
+                       return callback(JSON.parse(request.responseText));
+               }
+       };
+
+       request.overrideMimeType('application/json');
+       request.open('GET', url, true);
+       request.send(null);
+}
+
+function createCanvas(w, h) {
+       var canvas = document.createElement('canvas');
+       canvas.width = w;
+       canvas.height = h;
+       return canvas;
+}
+
+function readImageData(url, callback) {
+       var image = new Image();
+
+       image.onload = function() {
+               var h = image.height;
+               var w = image.width;
+               var canvas = createCanvas(w, h);
+               var ctx = canvas.getContext('2d');
+               ctx.drawImage(image, 0, 0, w, h);
+               callback(ctx.getImageData(0, 0, w, h));
+       };
+
+       image.src = url;
+}
+
 /**
  * Injects a new canvas (and div wrapper) and creates teh associated Chart instance
  * using the given config. Additional options allow tweaking elements generation.
@@ -69,8 +106,53 @@ function injectCSS(css) {
        head.appendChild(style);
 }
 
+function specFromFixture(description, inputs) {
+       it(inputs.json, function(done) {
+               loadJSON(inputs.json, function(json) {
+                       var chart = acquireChart(json.config, json.options);
+                       if (!inputs.png) {
+                               fail('Missing PNG comparison file for ' + inputs.json);
+                               if (!json.debug) {
+                                       releaseChart(chart);
+                               }
+                               done();
+                       }
+
+                       readImageData(inputs.png, function(expected) {
+                               expect(chart).toEqualImageData(expected, json);
+                               releaseChart(chart);
+                               done();
+                       });
+               });
+       });
+}
+
+function specsFromFixtures(path) {
+       var regex = new RegExp('(^/base/test/fixtures/' + path + '.+)\\.(png|json)');
+       var inputs = {};
+
+       Object.keys(__karma__.files || {}).forEach(function(file) {
+               var matches = file.match(regex);
+               var name = matches && matches[1];
+               var type = matches && matches[2];
+
+               if (name && type) {
+                       inputs[name] = inputs[name] || {};
+                       inputs[name][type] = file;
+               }
+       });
+
+       return function() {
+               Object.keys(inputs).forEach(function(key) {
+                       specFromFixture(key, inputs[key]);
+               });
+       };
+}
+
 module.exports = {
        injectCSS: injectCSS,
+       createCanvas: createCanvas,
        acquireChart: acquireChart,
-       releaseChart: releaseChart
+       releaseChart: releaseChart,
+       specsFromFixtures: specsFromFixtures
 };
index 0a2a6eced5690dfc76d12647b20e6f66ca78a87c..52d94cd377cddc81f7280b38d9bd29b17c1b25b8 100644 (file)
@@ -1,5 +1,7 @@
 // Tests for the line element
-describe('Line element tests', function() {
+describe('Chart.elements.Line', function() {
+       describe('auto', jasmine.specsFromFixtures('element.line'));
+
        it('should be constructed', function() {
                var line = new Chart.elements.Line({
                        _datasetindex: 2,