+ " and " + p2 + " with attributes " + toString(predicate));
+};
+
+/**
+ * Return the lines drawn with specific attributes.
+ *
+ * This merely looks for one of these four possibilities:
+ * moveTo(p1) -> lineTo(p2)
+ * moveTo(p2) -> lineTo(p1)
+ * lineTo(p1) -> lineTo(p2)
+ * lineTo(p2) -> lineTo(p1)
+ *
+ * attrs is meant to be used when you want to track things like
+ * color and stroke width.
+ */
+CanvasAssertions.getLinesDrawn = function(proxy, predicate) {
+ var lastCall;
+ var lines = [];
+ for (var i = 0; i < proxy.calls__.length; i++) {
+ var call = proxy.calls__[i];
+
+ if (call.name == "lineTo") {
+ if (lastCall != null) {
+ if (CanvasAssertions.match(predicate, call)) {
+ lines.push([lastCall, call]);
+ }
+ }
+ }
+
+ lastCall = (call.name === "lineTo" || call.name === "moveTo") ? call : null;
+ }
+ return lines;
+};
+
+/**
+ * Verifies that every call to context.save() has a matching call to
+ * context.restore().
+ */
+CanvasAssertions.assertBalancedSaveRestore = function(proxy) {
+ var depth = 0;
+ for (var i = 0; i < proxy.calls__.length; i++) {
+ var call = proxy.calls__[i];
+ if (call.name == "save") depth++
+ if (call.name == "restore") {
+ if (depth == 0) {
+ fail("Too many calls to restore()");
+ }
+ depth--;
+ }
+ }
+
+ if (depth > 0) {
+ fail("Missing matching 'context.restore()' calls.");
+ }
+};
+
+/**
+ * Checks how many lines of the given color have been drawn.
+ * @return {Integer} The number of lines of the given color.
+ */
+// TODO(konigsberg): change 'color' to predicate? color is the
+// common case. Possibly allow predicate to be function, hash, or
+// string representing color?
+CanvasAssertions.numLinesDrawn = function(proxy, color) {
+ var num_lines = 0;
+ for (var i = 0; i < proxy.calls__.length; i++) {
+ var call = proxy.calls__[i];
+ if (call.name == "lineTo" && call.properties.strokeStyle == color) {
+ num_lines++;
+ }
+ }
+ return num_lines;
+};
+
+/**
+ * Asserts that a series of lines are connected. For example,
+ * assertConsecutiveLinesDrawn(proxy, [[x1, y1], [x2, y2], [x3, y3]], predicate)
+ * is shorthand for
+ * assertLineDrawn(proxy, [x1, y1], [x2, y2], predicate)
+ * assertLineDrawn(proxy, [x2, y2], [x3, y3], predicate)
+ */
+CanvasAssertions.assertConsecutiveLinesDrawn = function(proxy, segments, predicate) {
+ for (var i = 0; i < segments.length - 1; i++) {
+ CanvasAssertions.assertLineDrawn(proxy, segments[i], segments[i+1], predicate);
+ }