Commit d6282d43 d6282d43177b3e1d63f6ed68d1721c2308997aa7 by Nicolas Perriault

finished refactor of Tester.assert*() methods

1 parent 6c726eeb
...@@ -80,6 +80,9 @@ var Tester = function Tester(casper, options) { ...@@ -80,6 +80,9 @@ var Tester = function Tester(casper, options) {
80 this.exporter.addFailure(fs.absolute(failure.file), failure.message, failure.details || "test failed", failure.type || "unknown"); 80 this.exporter.addFailure(fs.absolute(failure.file), failure.message, failure.details || "test failed", failure.type || "unknown");
81 this.testResults.failures.push(failure); 81 this.testResults.failures.push(failure);
82 // special printing 82 // special printing
83 if (failure.details) {
84 this.comment(' details: ' + failure.details);
85 }
83 switch (failure.type) { 86 switch (failure.type) {
84 case 'assertEquals': 87 case 'assertEquals':
85 case 'assertEvalEquals': 88 case 'assertEvalEquals':
...@@ -97,15 +100,16 @@ var Tester = function Tester(casper, options) { ...@@ -97,15 +100,16 @@ var Tester = function Tester(casper, options) {
97 /** 100 /**
98 * Asserts that a condition strictly resolves to true. 101 * Asserts that a condition strictly resolves to true.
99 * 102 *
100 * @param Boolean subject 103 * @param Boolean subject The condition to test
101 * @param String message Test description 104 * @param String message Test description
102 * @param Object|null context Assertion context object 105 * @param Object|null context Assertion context object
106 * @return Object An assertion result object
103 */ 107 */
104 this.assert = this.assertTrue = function assert(subject, message, context) { 108 this.assert = this.assertTrue = function assert(subject, message, context) {
105 this.processAssertionResult(utils.mergeObjects({ 109 this.processAssertionResult(utils.mergeObjects({
106 success: subject === true, 110 success: subject === true,
107 type: "assert", 111 type: "assert",
108 details: "test failed", 112 details: "Subject's not a strict boolean true",
109 message: message, 113 message: message,
110 file: this.currentTestFile, 114 file: this.currentTestFile,
111 values: { 115 values: {
...@@ -121,12 +125,13 @@ var Tester = function Tester(casper, options) { ...@@ -121,12 +125,13 @@ var Tester = function Tester(casper, options) {
121 * @param Mixed expected The expected value 125 * @param Mixed expected The expected value
122 * @param String message Test description (Optional) 126 * @param String message Test description (Optional)
123 * @param Object|null context Assertion context object (Optional) 127 * @param Object|null context Assertion context object (Optional)
128 * @return Object An assertion result object
124 */ 129 */
125 this.assertEquals = this.assertEqual = function assertEquals(subject, expected, message, context) { 130 this.assertEquals = this.assertEqual = function assertEquals(subject, expected, message, context) {
126 return this.processAssertionResult(utils.mergeObjects({ 131 return this.processAssertionResult(utils.mergeObjects({
127 success: this.testEquals(subject, expected), 132 success: this.testEquals(subject, expected),
128 type: "assertEquals", 133 type: "assertEquals",
129 details: f("test failed; expected: %s; got: %s", expected, subject), 134 details: "Subject didn't equal the expected value",
130 message: message, 135 message: message,
131 file: this.currentTestFile, 136 file: this.currentTestFile,
132 values: { 137 values: {
...@@ -143,12 +148,13 @@ var Tester = function Tester(casper, options) { ...@@ -143,12 +148,13 @@ var Tester = function Tester(casper, options) {
143 * @param Mixed expected The unwanted value 148 * @param Mixed expected The unwanted value
144 * @param String|null message Test description (Optional) 149 * @param String|null message Test description (Optional)
145 * @param Object|null context Assertion context object (Optional) 150 * @param Object|null context Assertion context object (Optional)
151 * @return Object An assertion result object
146 */ 152 */
147 this.assertNotEquals = function assertNotEquals(subject, shouldnt, message, context) { 153 this.assertNotEquals = function assertNotEquals(subject, shouldnt, message, context) {
148 return this.processAssertionResult(utils.mergeObjects({ 154 return this.processAssertionResult(utils.mergeObjects({
149 success: !this.testEquals(subject, shouldnt), 155 success: !this.testEquals(subject, shouldnt),
150 type: "assertNotEquals", 156 type: "assertNotEquals",
151 details: f("test failed; shouldn't be %s, but was.", shouldnt), 157 details: "Subject actually equals to what it shouldn't be",
152 message: message, 158 message: message,
153 file: this.currentTestFile, 159 file: this.currentTestFile,
154 values: { 160 values: {
...@@ -165,19 +171,13 @@ var Tester = function Tester(casper, options) { ...@@ -165,19 +171,13 @@ var Tester = function Tester(casper, options) {
165 * @param String message Test description 171 * @param String message Test description
166 * @param Object params Object containing the parameters to inject into the function (optional) 172 * @param Object params Object containing the parameters to inject into the function (optional)
167 * @param Object|null context Assertion context object (Optional) 173 * @param Object|null context Assertion context object (Optional)
174 * @return Object An assertion result object
168 */ 175 */
169 this.assertEval = this.assertEvaluate = function assertEval(fn, message, params, context) { 176 this.assertEval = this.assertEvaluate = function assertEval(fn, message, params, context) {
170 return this.processAssertionResult(utils.mergeObjects({ 177 return this.assert(casper.evaluate(fn, params), message, {
171 success: casper.evaluate(fn, params),
172 type: "assertEval", 178 type: "assertEval",
173 details: "function didn't evaluate to true", 179 details: "Function didn't evaluate to true"
174 message: message, 180 });
175 file: this.currentTestFile,
176 values: {
177 fn: fn,
178 params: params
179 }
180 }, context || {}));
181 }; 181 };
182 182
183 /** 183 /**
...@@ -189,19 +189,18 @@ var Tester = function Tester(casper, options) { ...@@ -189,19 +189,18 @@ var Tester = function Tester(casper, options) {
189 * @param String|null message Test description 189 * @param String|null message Test description
190 * @param Object|null params Object containing the parameters to inject into the function (optional) 190 * @param Object|null params Object containing the parameters to inject into the function (optional)
191 * @param Object|null context Assertion context object (Optional) 191 * @param Object|null context Assertion context object (Optional)
192 * @return Object An assertion result object
192 */ 193 */
193 this.assertEvalEquals = this.assertEvalEqual = function assertEvalEquals(fn, expected, message, params, context) { 194 this.assertEvalEquals = this.assertEvalEqual = function assertEvalEquals(fn, expected, message, params, context) {
194 return this.processAssertionResult(utils.mergeObjects({ 195 var subject = casper.evaluate(fn, params);
195 success: this.testEquals(casper.evaluate(fn, params), expected), 196 return this.assertEquals(subject, expected, message, {
196 type: "assertEvalEquals", 197 type: "assertEvalEquals",
197 details: f("test failed; expected: %s; got: %s", expected, subject), 198 details: "Evaluated function didn't return the expected value",
198 message: message,
199 file: this.currentTestFile,
200 values: { 199 values: {
201 subject: subject, 200 subject: subject,
202 expected: expected 201 expected: expected
203 } 202 }
204 }, context || {})); 203 });
205 }; 204 };
206 205
207 /** 206 /**
...@@ -210,9 +209,16 @@ var Tester = function Tester(casper, options) { ...@@ -210,9 +209,16 @@ var Tester = function Tester(casper, options) {
210 * 209 *
211 * @param String selector Selector expression 210 * @param String selector Selector expression
212 * @param String message Test description 211 * @param String message Test description
212 * @return Object An assertion result object
213 */ 213 */
214 this.assertExists = this.assertExist = function assertExists(selector, message) { 214 this.assertExists = this.assertExist = function assertExists(selector, message) {
215 return this.assert(casper.exists(selector), message); 215 return this.assert(casper.exists(selector), message, {
216 type: "assertExists",
217 details: f("No element matching selector %s was found", selector),
218 values: {
219 selector: selector
220 }
221 });
216 }; 222 };
217 223
218 /** 224 /**
...@@ -221,9 +227,16 @@ var Tester = function Tester(casper, options) { ...@@ -221,9 +227,16 @@ var Tester = function Tester(casper, options) {
221 * 227 *
222 * @param String selector Selector expression 228 * @param String selector Selector expression
223 * @param String message Test description 229 * @param String message Test description
230 * @return Object An assertion result object
224 */ 231 */
225 this.assertDoesntExist = this.assertNotExists = function assertDoesntExist(selector, message) { 232 this.assertDoesntExist = this.assertNotExists = function assertDoesntExist(selector, message) {
226 return this.assertNot(casper.exists(selector), message); 233 return this.assertNot(casper.exists(selector), message, {
234 type: "assertDoesntExist",
235 details: f("At least one element matching selector %s was found", selector),
236 values: {
237 selector: selector
238 }
239 });
227 }; 240 };
228 241
229 /** 242 /**
...@@ -231,9 +244,18 @@ var Tester = function Tester(casper, options) { ...@@ -231,9 +244,18 @@ var Tester = function Tester(casper, options) {
231 * 244 *
232 * @param Number status HTTP status code 245 * @param Number status HTTP status code
233 * @param String message Test description 246 * @param String message Test description
247 * @return Object An assertion result object
234 */ 248 */
235 this.assertHttpStatus = function assertHttpStatus(status, message) { 249 this.assertHttpStatus = function assertHttpStatus(status, message) {
236 return this.assertEquals(casper.currentHTTPStatus, status, message || f("HTTP status code is %d", status)); 250 var currentHTTPStatus = casper.currentHTTPStatus;
251 return this.assertEquals(casper.currentHTTPStatus, status, message, {
252 type: "assertHttpStatus",
253 details: f("HTTP status code is not %d, but %d", status, currentHTTPStatus),
254 values: {
255 current: currentHTTPStatus,
256 expected: status
257 }
258 });
237 }; 259 };
238 260
239 /** 261 /**
...@@ -242,25 +264,12 @@ var Tester = function Tester(casper, options) { ...@@ -242,25 +264,12 @@ var Tester = function Tester(casper, options) {
242 * @param String subject The string to test 264 * @param String subject The string to test
243 * @param RegExp pattern A RegExp object instance 265 * @param RegExp pattern A RegExp object instance
244 * @param String message Test description 266 * @param String message Test description
267 * @return Object An assertion result object
245 */ 268 */
246 this.assertMatch = this.assertMatches = function assertMatch(subject, pattern, message) { 269 this.assertMatch = this.assertMatches = function assertMatch(subject, pattern, message) {
247 var eventName; 270 return this.assert(pattern.test(subject), message, {
248 if (pattern.test(subject)) { 271 type: "assertMatch",
249 eventName = "success"; 272 details: "Subject didn't match the provided pattern",
250 casper.echo(this.colorize(this.options.passText, 'INFO') + ' ' + this.formatMessage(message));
251 this.testResults.passed++;
252 } else {
253 eventName = "fail";
254 casper.echo(this.colorize(this.options.failText, 'RED_BAR') + ' ' + this.formatMessage(message, 'WARNING'));
255 this.comment(' subject: ' + subject);
256 this.comment(' pattern: ' + pattern.toString());
257 this.testResults.failed++;
258 }
259 this.emit(eventName, {
260 type: "assertMatch",
261 message: message,
262 details: f("test failed; subject: %s; pattern: %s", subject, pattern.toString()),
263 file: this.currentTestFile,
264 values: { 273 values: {
265 subject: subject, 274 subject: subject,
266 pattern: pattern 275 pattern: pattern
...@@ -271,11 +280,18 @@ var Tester = function Tester(casper, options) { ...@@ -271,11 +280,18 @@ var Tester = function Tester(casper, options) {
271 /** 280 /**
272 * Asserts a condition resolves to false. 281 * Asserts a condition resolves to false.
273 * 282 *
274 * @param Boolean condition 283 * @param Boolean condition The condition to test
275 * @param String message Test description 284 * @param String message Test description
285 * @return Object An assertion result object
276 */ 286 */
277 this.assertNot = function assertNot(condition, message) { 287 this.assertNot = function assertNot(condition, message) {
278 return this.assert(!condition, message); 288 return this.assert(!condition, message, {
289 type: "assertNot",
290 details: "The condition is not falsy",
291 values: {
292 condition: condition
293 }
294 });
279 }; 295 };
280 296
281 /** 297 /**
...@@ -285,24 +301,40 @@ var Tester = function Tester(casper, options) { ...@@ -285,24 +301,40 @@ var Tester = function Tester(casper, options) {
285 * @param Function fn The function to test 301 * @param Function fn The function to test
286 * @param Array args The arguments to pass to the function 302 * @param Array args The arguments to pass to the function
287 * @param String message Test description 303 * @param String message Test description
304 * @return Object An assertion result object
288 */ 305 */
289 this.assertRaises = this.assertRaise = function assertRaises(fn, args, message) { 306 this.assertRaises = this.assertRaise = this.assertThrow = this.assertThrows = function assertRaises(fn, args, message) {
307 var context = {
308 type: "assertRaises",
309 details: "Function didn't raise any error"
310 };
290 try { 311 try {
291 fn.apply(null, args); 312 fn.apply(null, args);
292 this.fail(message); 313 this.fail(message, context);
293 } catch (e) { 314 } catch (error) {
294 this.pass(message); 315 this.pass(message, utils.mergeObjects(context, {
316 values: {
317 error: error
318 }
319 }));
295 } 320 }
296 }; 321 };
297 322
298 /** 323 /**
299 * Asserts that the current page has a resource that matches the provided test 324 * Asserts that the current page has a resource that matches the provided test
300 * 325 *
301 * @param Function/String test A test function that is called with every response 326 * @param Function/String test A test function that is called with every response
302 * @param String message Test description 327 * @param String message Test description
328 * @return Object An assertion result object
303 */ 329 */
304 this.assertResourceExists = this.assertResourceExist = function assertResourceExists(test, message) { 330 this.assertResourceExists = this.assertResourceExist = function assertResourceExists(test, message) {
305 return this.assert(casper.resourceExists(test), message); 331 return this.assert(casper.resourceExists(test), message, {
332 type: "assertResourceExists",
333 details: "Resource was not found",
334 values: {
335 test: test
336 }
337 });
306 }; 338 };
307 339
308 /** 340 /**
...@@ -311,9 +343,16 @@ var Tester = function Tester(casper, options) { ...@@ -311,9 +343,16 @@ var Tester = function Tester(casper, options) {
311 * 343 *
312 * @param String selector A selector expression string 344 * @param String selector A selector expression string
313 * @param String message Test description 345 * @param String message Test description
346 * @return Object An assertion result object
314 */ 347 */
315 this.assertSelectorExists = this.assertSelectorExist = function assertSelectorExists(selector, message) { 348 this.assertSelectorExists = this.assertSelectorExist = function assertSelectorExists(selector, message) {
316 return this.assert(casper.exists(selector), message); 349 return this.assert(casper.exists(selector), message, {
350 type: "assertSelectorExists",
351 details: f("No element matching selector %s was found", selector),
352 values: {
353 selector: selector
354 }
355 });
317 }; 356 };
318 357
319 /** 358 /**
...@@ -321,11 +360,19 @@ var Tester = function Tester(casper, options) { ...@@ -321,11 +360,19 @@ var Tester = function Tester(casper, options) {
321 * 360 *
322 * @param String text Text to be found 361 * @param String text Text to be found
323 * @param String message Test description 362 * @param String message Test description
363 * @return Object An assertion result object
324 */ 364 */
325 this.assertTextExists = this.assertTextExist = function assertTextExists(text, message) { 365 this.assertTextExists = this.assertTextExist = function assertTextExists(text, message) {
326 return this.assert((casper.evaluate(function _evaluate() { 366 var textFound = (casper.evaluate(function _evaluate() {
327 return document.body.innerText; 367 return document.body.innerText;
328 }).indexOf(text) != -1), message); 368 }).indexOf(text) != -1);
369 return this.assert(textFound, message, {
370 type: "assertTextExists",
371 details: "Text was not found within the document body textual contents",
372 values: {
373 text: text
374 }
375 });
329 }; 376 };
330 377
331 /** 378 /**
...@@ -333,9 +380,18 @@ var Tester = function Tester(casper, options) { ...@@ -333,9 +380,18 @@ var Tester = function Tester(casper, options) {
333 * 380 *
334 * @param String expected The expected title string 381 * @param String expected The expected title string
335 * @param String message Test description 382 * @param String message Test description
383 * @return Object An assertion result object
336 */ 384 */
337 this.assertTitle = function assertTitle(expected, message) { 385 this.assertTitle = function assertTitle(expected, message) {
338 return this.assertEquals(casper.getTitle(), expected, message); 386 var currentTitle = casper.getTitle();
387 return this.assertEquals(casper.getTitle(), expected, message, {
388 type: "assertTitle",
389 details: f("Page title is not %s", expected),
390 values: {
391 expected: expected,
392 current: currentTitle
393 }
394 });
339 }; 395 };
340 396
341 /** 397 /**
...@@ -344,9 +400,19 @@ var Tester = function Tester(casper, options) { ...@@ -344,9 +400,19 @@ var Tester = function Tester(casper, options) {
344 * @param mixed input The value to test 400 * @param mixed input The value to test
345 * @param String type The javascript type name 401 * @param String type The javascript type name
346 * @param String message Test description 402 * @param String message Test description
403 * @return Object An assertion result object
347 */ 404 */
348 this.assertType = function assertType(input, type, message) { 405 this.assertType = function assertType(input, type, message) {
349 return this.assertEquals(utils.betterTypeOf(input), type, message); 406 var actual = utils.betterTypeOf(input);
407 return this.assertEquals(actual, type, message, {
408 type: "assertType",
409 details: f("Expected type %s, got %s", typeof input, actual),
410 values: {
411 input: input,
412 type: type,
413 actual: actual
414 }
415 });
350 }; 416 };
351 417
352 /** 418 /**
...@@ -355,11 +421,24 @@ var Tester = function Tester(casper, options) { ...@@ -355,11 +421,24 @@ var Tester = function Tester(casper, options) {
355 * 421 *
356 * @param RegExp pattern A RegExp object instance 422 * @param RegExp pattern A RegExp object instance
357 * @param String message Test description 423 * @param String message Test description
424 * @return Object An assertion result object
358 */ 425 */
359 this.assertUrlMatch = this.assertUrlMatches = function assertUrlMatch(pattern, message) { 426 this.assertUrlMatch = this.assertUrlMatches = function assertUrlMatch(pattern, message) {
360 return this.assertMatch(casper.getCurrentUrl(), pattern, message); 427 var currentUrl = casper.getCurrentUrl();
428 return this.assertMatch(currentUrl, pattern, message, {
429 type: "assertUrlMatch",
430 details: "Current url did not match the provided pattern",
431 values: {
432 currentUrl: currentUrl,
433 pattern: pattern
434 }
435 });
361 }; 436 };
362 437
438 /**
439 * Prints out a colored bar onto the console.
440 *
441 */
363 this.bar = function bar(text, style) { 442 this.bar = function bar(text, style) {
364 casper.echo(text, style, this.options.pad); 443 casper.echo(text, style, this.options.pad);
365 }; 444 };
......
...@@ -42,7 +42,7 @@ var expected = [ ...@@ -42,7 +42,7 @@ var expected = [
42 ].map(function(entry) { 42 ].map(function(entry) {
43 return fs.pathJoin.apply(fs, [testDirRoot].concat(entry.split('/'))); 43 return fs.pathJoin.apply(fs, [testDirRoot].concat(entry.split('/')));
44 }); 44 });
45 t.assertEquals(files, [], 'findTestFiles() find test files and sort them'); 45 t.assertEquals(files, expected, 'findTestFiles() find test files and sort them');
46 46
47 t.comment('Tester.assertTextExists()'); 47 t.comment('Tester.assertTextExists()');
48 casper.start('tests/site/index.html', function() { 48 casper.start('tests/site/index.html', function() {
......