Commit | Line | Data |
---|---|---|
718ad8e2 | 1 | // Copyright (c) 2011 Google, Inc. |
644eff8b RK |
2 | // |
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy | |
4 | // of this software and associated documentation files (the "Software"), to deal | |
5 | // in the Software without restriction, including without limitation the rights | |
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
7 | // copies of the Software, and to permit persons to whom the Software is | |
8 | // furnished to do so, subject to the following conditions: | |
9 | // | |
10 | // The above copyright notice and this permission notice shall be included in | |
11 | // all copies or substantial portions of the Software. | |
12 | // | |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
19 | // THE SOFTWARE. | |
20 | ||
21 | /** | |
22 | * @fileoverview Assertions and other code used to test a canvas proxy. | |
23 | * | |
24 | * @author konigsberg@google.com (Robert Konigsberg) | |
25 | */ | |
26 | ||
27 | var CanvasAssertions = {}; | |
28 | ||
29 | /** | |
30 | * Assert that a line is drawn between the two points | |
31 | * | |
32 | * This merely looks for one of these four possibilities: | |
33 | * moveTo(p1) -> lineTo(p2) | |
34 | * moveTo(p2) -> lineTo(p1) | |
35 | * lineTo(p1) -> lineTo(p2) | |
36 | * lineTo(p2) -> lineTo(p1) | |
37 | * | |
38 | * attrs is meant to be used when you want to track things like | |
39 | * color and stroke width. | |
40 | */ | |
41 | CanvasAssertions.assertLineDrawn = function(proxy, p1, p2, attrs) { | |
42 | // found = 1 when prior loop found p1. | |
43 | // found = 2 when prior loop found p2. | |
44 | var priorFound = 0; | |
7165f97b RK |
45 | for (var i = 0; i < proxy.calls__.length; i++) { |
46 | var call = proxy.calls__[i]; | |
644eff8b RK |
47 | |
48 | // This disables lineTo -> moveTo pairs. | |
49 | if (call.name == "moveTo" && priorFound > 0) { | |
50 | priorFound = 0; | |
51 | } | |
52 | ||
53 | var found = 0; | |
54 | if (call.name == "moveTo" || call.name == "lineTo") { | |
55 | var matchp1 = CanvasAssertions.matchPixels(p1, call.args); | |
56 | var matchp2 = CanvasAssertions.matchPixels(p2, call.args); | |
57 | if (matchp1 || matchp2) { | |
58 | if (priorFound == 1 && matchp2) { | |
59 | // TODO -- add property test here CanvasAssertions.matchAttributes(attrs, call.properties) | |
60 | return; | |
61 | } | |
62 | if (priorFound == 2 && matchp1) { | |
63 | // TODO -- add property test here CanvasAssertions.matchAttributes(attrs, call.properties) | |
64 | return; | |
65 | } | |
66 | found = matchp1 ? 1 : 2; | |
67 | } | |
68 | } | |
69 | priorFound = found; | |
70 | } | |
71 | ||
72 | var toString = function(x) { | |
73 | var s = "{"; | |
74 | for (var prop in x) { | |
75 | if (x.hasOwnProperty(prop)) { | |
76 | if (s.length > 1) { | |
77 | s = s + ", "; | |
78 | } | |
79 | s = s + prop + ": " + x[prop]; | |
80 | } | |
81 | } | |
82 | return s + "}"; | |
83 | }; | |
84 | fail("Can't find a line drawn between " + p1 + | |
85 | " and " + p2 + " with attributes " + toString(attrs)); | |
6278f6fe DV |
86 | }; |
87 | ||
88 | /** | |
8337da0a RK |
89 | * Return the lines drawn with specific attributes. |
90 | * | |
91 | * This merely looks for one of these four possibilities: | |
92 | * moveTo(p1) -> lineTo(p2) | |
93 | * moveTo(p2) -> lineTo(p1) | |
94 | * lineTo(p1) -> lineTo(p2) | |
95 | * lineTo(p2) -> lineTo(p1) | |
96 | * | |
97 | * attrs is meant to be used when you want to track things like | |
98 | * color and stroke width. | |
99 | */ | |
100 | CanvasAssertions.getLinesDrawn = function(proxy) { | |
101 | var lastCall; | |
102 | var lines = []; | |
103 | for (var i = 0; i < proxy.calls__.length; i++) { | |
104 | var call = proxy.calls__[i]; | |
105 | ||
106 | if (call.name == "lineTo") { | |
107 | if (lastCall != null) { | |
108 | lines.push([lastCall, call]); | |
109 | } | |
110 | } | |
111 | ||
112 | lastCall = (call.name === "lineTo" || call.name === "moveTo") ? call : null; | |
113 | } | |
114 | return lines; | |
115 | }; | |
116 | ||
117 | /** | |
6278f6fe DV |
118 | * Verifies that every call to context.save() has a matching call to |
119 | * context.restore(). | |
120 | */ | |
121 | CanvasAssertions.assertBalancedSaveRestore = function(proxy) { | |
122 | var depth = 0; | |
123 | for (var i = 0; i < proxy.calls__.length; i++) { | |
124 | var call = proxy.calls__[i]; | |
125 | if (call.name == "save") depth++ | |
126 | if (call.name == "restore") { | |
127 | if (depth == 0) { | |
128 | fail("Too many calls to restore()"); | |
129 | } | |
130 | depth--; | |
131 | } | |
132 | } | |
133 | ||
134 | if (depth > 0) { | |
135 | fail("Missing matching 'context.restore()' calls."); | |
136 | } | |
137 | }; | |
644eff8b | 138 | |
063e83ba DV |
139 | /** |
140 | * Checks how many lines of the given color have been drawn. | |
141 | * @return {Integer} The number of lines of the given color. | |
142 | */ | |
143 | CanvasAssertions.numLinesDrawn = function(proxy, color) { | |
144 | var num_lines = 0; | |
145 | for (var i = 0; i < proxy.calls__.length; i++) { | |
146 | var call = proxy.calls__[i]; | |
147 | if (call.name == "lineTo" && call.properties.strokeStyle == color) { | |
148 | num_lines++; | |
149 | } | |
150 | } | |
151 | return num_lines; | |
6278f6fe | 152 | }; |
063e83ba | 153 | |
644eff8b RK |
154 | CanvasAssertions.matchPixels = function(expected, actual) { |
155 | // Expect array of two integers. Assuming the values are within one | |
156 | // integer unit of each other. This should be tightened down by someone | |
157 | // who knows what pixel a value of 5.8888 results in. | |
158 | return Math.abs(expected[0] - actual[0]) < 1 && | |
159 | Math.abs(expected[1] - actual[1]) < 1; | |
6278f6fe | 160 | }; |
644eff8b RK |
161 | |
162 | CanvasAssertions.matchAttributes = function(expected, actual) { | |
163 | for (var attr in expected) { | |
164 | if (expected.hasOwnProperty(attr) && expected[attr] != actual[attr]) { | |
165 | return false; | |
166 | } | |
167 | } | |
168 | return true; | |
6278f6fe | 169 | }; |