| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
Event.simulateMouse = function(element, eventName) { |
|---|
| 10 |
var options = Object.extend({ |
|---|
| 11 |
pointerX: 0, |
|---|
| 12 |
pointerY: 0, |
|---|
| 13 |
buttons: 0, |
|---|
| 14 |
ctrlKey: false, |
|---|
| 15 |
altKey: false, |
|---|
| 16 |
shiftKey: false, |
|---|
| 17 |
metaKey: false |
|---|
| 18 |
}, arguments[2] || {}); |
|---|
| 19 |
var oEvent = document.createEvent("MouseEvents"); |
|---|
| 20 |
oEvent.initMouseEvent(eventName, true, true, document.defaultView, |
|---|
| 21 |
options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, |
|---|
| 22 |
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element)); |
|---|
| 23 |
|
|---|
| 24 |
if(this.mark) Element.remove(this.mark); |
|---|
| 25 |
this.mark = document.createElement('div'); |
|---|
| 26 |
this.mark.appendChild(document.createTextNode(" ")); |
|---|
| 27 |
document.body.appendChild(this.mark); |
|---|
| 28 |
this.mark.style.position = 'absolute'; |
|---|
| 29 |
this.mark.style.top = options.pointerY + "px"; |
|---|
| 30 |
this.mark.style.left = options.pointerX + "px"; |
|---|
| 31 |
this.mark.style.width = "5px"; |
|---|
| 32 |
this.mark.style.height = "5px;"; |
|---|
| 33 |
this.mark.style.borderTop = "1px solid red;" |
|---|
| 34 |
this.mark.style.borderLeft = "1px solid red;" |
|---|
| 35 |
|
|---|
| 36 |
if(this.step) |
|---|
| 37 |
alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options)); |
|---|
| 38 |
|
|---|
| 39 |
$(element).dispatchEvent(oEvent); |
|---|
| 40 |
}; |
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
Event.simulateKey = function(element, eventName) { |
|---|
| 46 |
var options = Object.extend({ |
|---|
| 47 |
ctrlKey: false, |
|---|
| 48 |
altKey: false, |
|---|
| 49 |
shiftKey: false, |
|---|
| 50 |
metaKey: false, |
|---|
| 51 |
keyCode: 0, |
|---|
| 52 |
charCode: 0 |
|---|
| 53 |
}, arguments[2] || {}); |
|---|
| 54 |
|
|---|
| 55 |
var oEvent = document.createEvent("KeyEvents"); |
|---|
| 56 |
oEvent.initKeyEvent(eventName, true, true, window, |
|---|
| 57 |
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, |
|---|
| 58 |
options.keyCode, options.charCode ); |
|---|
| 59 |
$(element).dispatchEvent(oEvent); |
|---|
| 60 |
}; |
|---|
| 61 |
|
|---|
| 62 |
Event.simulateKeys = function(element, command) { |
|---|
| 63 |
for(var i=0; i<command.length; i++) { |
|---|
| 64 |
Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)}); |
|---|
| 65 |
} |
|---|
| 66 |
}; |
|---|
| 67 |
|
|---|
| 68 |
var Test = {} |
|---|
| 69 |
Test.Unit = {}; |
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
Test.Unit.inspect = Object.inspect; |
|---|
| 73 |
|
|---|
| 74 |
Test.Unit.Logger = Class.create(); |
|---|
| 75 |
Test.Unit.Logger.prototype = { |
|---|
| 76 |
initialize: function(log) { |
|---|
| 77 |
this.log = $(log); |
|---|
| 78 |
if (this.log) { |
|---|
| 79 |
this._createLogTable(); |
|---|
| 80 |
} |
|---|
| 81 |
}, |
|---|
| 82 |
start: function(testName) { |
|---|
| 83 |
if (!this.log) return; |
|---|
| 84 |
this.testName = testName; |
|---|
| 85 |
this.lastLogLine = document.createElement('tr'); |
|---|
| 86 |
this.statusCell = document.createElement('td'); |
|---|
| 87 |
this.nameCell = document.createElement('td'); |
|---|
| 88 |
this.nameCell.className = "nameCell"; |
|---|
| 89 |
this.nameCell.appendChild(document.createTextNode(testName)); |
|---|
| 90 |
this.messageCell = document.createElement('td'); |
|---|
| 91 |
this.lastLogLine.appendChild(this.statusCell); |
|---|
| 92 |
this.lastLogLine.appendChild(this.nameCell); |
|---|
| 93 |
this.lastLogLine.appendChild(this.messageCell); |
|---|
| 94 |
this.loglines.appendChild(this.lastLogLine); |
|---|
| 95 |
}, |
|---|
| 96 |
finish: function(status, summary) { |
|---|
| 97 |
if (!this.log) return; |
|---|
| 98 |
this.lastLogLine.className = status; |
|---|
| 99 |
this.statusCell.innerHTML = status; |
|---|
| 100 |
this.messageCell.innerHTML = this._toHTML(summary); |
|---|
| 101 |
this.addLinksToResults(); |
|---|
| 102 |
}, |
|---|
| 103 |
message: function(message) { |
|---|
| 104 |
if (!this.log) return; |
|---|
| 105 |
this.messageCell.innerHTML = this._toHTML(message); |
|---|
| 106 |
}, |
|---|
| 107 |
summary: function(summary) { |
|---|
| 108 |
if (!this.log) return; |
|---|
| 109 |
this.logsummary.innerHTML = this._toHTML(summary); |
|---|
| 110 |
}, |
|---|
| 111 |
_createLogTable: function() { |
|---|
| 112 |
this.log.innerHTML = |
|---|
| 113 |
'<div id="logsummary"></div>' + |
|---|
| 114 |
'<table id="logtable">' + |
|---|
| 115 |
'<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' + |
|---|
| 116 |
'<tbody id="loglines"></tbody>' + |
|---|
| 117 |
'</table>'; |
|---|
| 118 |
this.logsummary = $('logsummary') |
|---|
| 119 |
this.loglines = $('loglines'); |
|---|
| 120 |
}, |
|---|
| 121 |
_toHTML: function(txt) { |
|---|
| 122 |
return txt.escapeHTML().replace(/\n/g,"<br/>"); |
|---|
| 123 |
}, |
|---|
| 124 |
addLinksToResults: function(){ |
|---|
| 125 |
$$("tr.failed .nameCell").each( function(td){ |
|---|
| 126 |
td.title = "Run only this test" |
|---|
| 127 |
Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;}); |
|---|
| 128 |
}); |
|---|
| 129 |
$$("tr.passed .nameCell").each( function(td){ |
|---|
| 130 |
td.title = "Run all tests" |
|---|
| 131 |
Event.observe(td, 'click', function(){ window.location.search = "";}); |
|---|
| 132 |
}); |
|---|
| 133 |
} |
|---|
| 134 |
} |
|---|
| 135 |
|
|---|
| 136 |
Test.Unit.Runner = Class.create(); |
|---|
| 137 |
Test.Unit.Runner.prototype = { |
|---|
| 138 |
initialize: function(testcases) { |
|---|
| 139 |
this.options = Object.extend({ |
|---|
| 140 |
testLog: 'testlog' |
|---|
| 141 |
}, arguments[1] || {}); |
|---|
| 142 |
this.options.resultsURL = this.parseResultsURLQueryParameter(); |
|---|
| 143 |
this.options.tests = this.parseTestsQueryParameter(); |
|---|
| 144 |
if (this.options.testLog) { |
|---|
| 145 |
this.options.testLog = $(this.options.testLog) || null; |
|---|
| 146 |
} |
|---|
| 147 |
if(this.options.tests) { |
|---|
| 148 |
this.tests = []; |
|---|
| 149 |
for(var i = 0; i < this.options.tests.length; i++) { |
|---|
| 150 |
if(/^test/.test(this.options.tests[i])) { |
|---|
| 151 |
this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"])); |
|---|
| 152 |
} |
|---|
| 153 |
} |
|---|
| 154 |
} else { |
|---|
| 155 |
if (this.options.test) { |
|---|
| 156 |
this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])]; |
|---|
| 157 |
} else { |
|---|
| 158 |
this.tests = []; |
|---|
| 159 |
for(var testcase in testcases) { |
|---|
| 160 |
if(/^test/.test(testcase)) { |
|---|
| 161 |
this.tests.push( |
|---|
| 162 |
new Test.Unit.Testcase( |
|---|
| 163 |
this.options.context ? ' -> ' + this.options.titles[testcase] : testcase, |
|---|
| 164 |
testcases[testcase], testcases["setup"], testcases["teardown"] |
|---|
| 165 |
)); |
|---|
| 166 |
} |
|---|
| 167 |
} |
|---|
| 168 |
} |
|---|
| 169 |
} |
|---|
| 170 |
this.currentTest = 0; |
|---|
| 171 |
this.logger = new Test.Unit.Logger(this.options.testLog); |
|---|
| 172 |
setTimeout(this.runTests.bind(this), 1000); |
|---|
| 173 |
}, |
|---|
| 174 |
parseResultsURLQueryParameter: function() { |
|---|
| 175 |
return window.location.search.parseQuery()["resultsURL"]; |
|---|
| 176 |
}, |
|---|
| 177 |
parseTestsQueryParameter: function(){ |
|---|
| 178 |
if (window.location.search.parseQuery()["tests"]){ |
|---|
| 179 |
return window.location.search.parseQuery()["tests"].split(','); |
|---|
| 180 |
}; |
|---|
| 181 |
}, |
|---|
| 182 |
|
|---|
| 183 |
|
|---|
| 184 |
|
|---|
| 185 |
|
|---|
| 186 |
getResult: function() { |
|---|
| 187 |
var hasFailure = false; |
|---|
| 188 |
for(var i=0;i<this.tests.length;i++) { |
|---|
| 189 |
if (this.tests[i].errors > 0) { |
|---|
| 190 |
return "ERROR"; |
|---|
| 191 |
} |
|---|
| 192 |
if (this.tests[i].failures > 0) { |
|---|
| 193 |
hasFailure = true; |
|---|
| 194 |
} |
|---|
| 195 |
} |
|---|
| 196 |
if (hasFailure) { |
|---|
| 197 |
return "FAILURE"; |
|---|
| 198 |
} else { |
|---|
| 199 |
return "SUCCESS"; |
|---|
| 200 |
} |
|---|
| 201 |
}, |
|---|
| 202 |
postResults: function() { |
|---|
| 203 |
if (this.options.resultsURL) { |
|---|
| 204 |
new Ajax.Request(this.options.resultsURL, |
|---|
| 205 |
{ method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false }); |
|---|
| 206 |
} |
|---|
| 207 |
}, |
|---|
| 208 |
runTests: function() { |
|---|
| 209 |
var test = this.tests[this.currentTest]; |
|---|
| 210 |
if (!test) { |
|---|
| 211 |
|
|---|
| 212 |
this.postResults(); |
|---|
| 213 |
this.logger.summary(this.summary()); |
|---|
| 214 |
return; |
|---|
| 215 |
} |
|---|
| 216 |
if(!test.isWaiting) { |
|---|
| 217 |
this.logger.start(test.name); |
|---|
| 218 |
} |
|---|
| 219 |
test.run(); |
|---|
| 220 |
if(test.isWaiting) { |
|---|
| 221 |
this.logger.message("Waiting for " + test.timeToWait + "ms"); |
|---|
| 222 |
setTimeout(this.runTests.bind(this), test.timeToWait || 1000); |
|---|
| 223 |
} else { |
|---|
| 224 |
this.logger.finish(test.status(), test.summary()); |
|---|
| 225 |
this.currentTest++; |
|---|
| 226 |
|
|---|
| 227 |
this.runTests(); |
|---|
| 228 |
} |
|---|
| 229 |
}, |
|---|
| 230 |
summary: function() { |
|---|
| 231 |
var assertions = 0; |
|---|
| 232 |
var failures = 0; |
|---|
| 233 |
var errors = 0; |
|---|
| 234 |
var messages = []; |
|---|
| 235 |
for(var i=0;i<this.tests.length;i++) { |
|---|
| 236 |
assertions += this.tests[i].assertions; |
|---|
| 237 |
failures += this.tests[i].failures; |
|---|
| 238 |
errors += this.tests[i].errors; |
|---|
| 239 |
} |
|---|
| 240 |
return ( |
|---|
| 241 |
(this.options.context ? this.options.context + ': ': '') + |
|---|
| 242 |
this.tests.length + " tests, " + |
|---|
| 243 |
assertions + " assertions, " + |
|---|
| 244 |
failures + " failures, " + |
|---|
| 245 |
errors + " errors"); |
|---|
| 246 |
} |
|---|
| 247 |
} |
|---|
| 248 |
|
|---|
| 249 |
Test.Unit.Assertions = Class.create(); |
|---|
| 250 |
Test.Unit.Assertions.prototype = { |
|---|
| 251 |
initialize: function() { |
|---|
| 252 |
this.assertions = 0; |
|---|
| 253 |
this.failures = 0; |
|---|
| 254 |
this.errors = 0; |
|---|
| 255 |
this.messages = []; |
|---|
| 256 |
}, |
|---|
| 257 |
summary: function() { |
|---|
| 258 |
return ( |
|---|
| 259 |
this.assertions + " assertions, " + |
|---|
| 260 |
this.failures + " failures, " + |
|---|
| 261 |
this.errors + " errors" + "\n" + |
|---|
| 262 |
this.messages.join("\n")); |
|---|
| 263 |
}, |
|---|
| 264 |
pass: function() { |
|---|
| 265 |
this.assertions++; |
|---|
| 266 |
}, |
|---|
| 267 |
fail: function(message) { |
|---|
| 268 |
this.failures++; |
|---|
| 269 |
this.messages.push("Failure: " + message); |
|---|
| 270 |
}, |
|---|
| 271 |
info: function(message) { |
|---|
| 272 |
this.messages.push("Info: " + message); |
|---|
| 273 |
}, |
|---|
| 274 |
error: function(error) { |
|---|
| 275 |
this.errors++; |
|---|
| 276 |
this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")"); |
|---|
| 277 |
}, |
|---|
| 278 |
status: function() { |
|---|
| 279 |
if (this.failures > 0) return 'failed'; |
|---|
| 280 |
if (this.errors > 0) return 'error'; |
|---|
| 281 |
return 'passed'; |
|---|
| 282 |
}, |
|---|
| 283 |
assert: function(expression) { |
|---|
| 284 |
var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"'; |
|---|
| 285 |
try { expression ? this.pass() : |
|---|
| 286 |
this.fail(message); } |
|---|
| 287 |
catch(e) { this.error(e); } |
|---|
| 288 |
}, |
|---|
| 289 |
assertEqual: function(expected, actual) { |
|---|
| 290 |
var message = arguments[2] || "assertEqual"; |
|---|
| 291 |
try { (expected == actual) ? this.pass() : |
|---|
| 292 |
this.fail(message + ': expected "' + Test.Unit.inspect(expected) + |
|---|
| 293 |
'", actual "' + Test.Unit.inspect(actual) + '"'); } |
|---|
| 294 |
catch(e) { this.error(e); } |
|---|
| 295 |
}, |
|---|
| 296 |
assertInspect: function(expected, actual) { |
|---|
| 297 |
var message = arguments[2] || "assertInspect"; |
|---|
| 298 |
try { (expected == actual.inspect()) ? this.pass() : |
|---|
| 299 |
this.fail(message + ': expected "' + Test.Unit.inspect(expected) + |
|---|
| 300 |
'", actual "' + Test.Unit.inspect(actual) + '"'); } |
|---|
| 301 |
catch(e) { this.error(e); } |
|---|
| 302 |
}, |
|---|
| 303 |
assertEnumEqual: function(expected, actual) { |
|---|
| 304 |
var message = arguments[2] || "assertEnumEqual"; |
|---|
| 305 |
try { $A(expected).length == $A(actual).length && |
|---|
| 306 |
expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ? |
|---|
| 307 |
this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + |
|---|
| 308 |
', actual ' + Test.Unit.inspect(actual)); } |
|---|
| 309 |
catch(e) { this.error(e); } |
|---|
| 310 |
}, |
|---|
| 311 |
assertNotEqual: function(expected, actual) { |
|---|
| 312 |
var message = arguments[2] || "assertNotEqual"; |
|---|
| 313 |
try { (expected != actual) ? this.pass() : |
|---|
| 314 |
this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); } |
|---|
| 315 |
catch(e) { this.error(e); } |
|---|
| 316 |
}, |
|---|
| 317 |
assertIdentical: function(expected, actual) { |
|---|
| 318 |
var message = arguments[2] || "assertIdentical"; |
|---|
| 319 |
try { (expected === actual) ? this.pass() : |
|---|
| 320 |
this.fail(message + ': expected "' + Test.Unit.inspect(expected) + |
|---|
| 321 |
'", actual "' + Test.Unit.inspect(actual) + '"'); } |
|---|
| 322 |
catch(e) { this.error(e); } |
|---|
| 323 |
}, |
|---|
| 324 |
assertNotIdentical: function(expected, actual) { |
|---|
| 325 |
var message = arguments[2] || "assertNotIdentical"; |
|---|
| 326 |
try { !(expected === actual) ? this.pass() : |
|---|
| 327 |
this.fail(message + ': expected "' + Test.Unit.inspect(expected) + |
|---|
| 328 |
'", actual "' + Test.Unit.inspect(actual) + '"'); } |
|---|
| 329 |
catch(e) { this.error(e); } |
|---|
| 330 |
}, |
|---|
| 331 |
assertNull: function(obj) { |
|---|
| 332 |
var message = arguments[1] || 'assertNull' |
|---|
| 333 |
try { (obj==null) ? this.pass() : |
|---|
| 334 |
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } |
|---|
| 335 |
catch(e) { this.error(e); } |
|---|
| 336 |
}, |
|---|
| 337 |
assertMatch: function(expected, actual) { |
|---|
| 338 |
var message = arguments[2] || 'assertMatch'; |
|---|
| 339 |
var regex = new RegExp(expected); |
|---|
| 340 |
try { (regex.exec(actual)) ? this.pass() : |
|---|
| 341 |
this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); } |
|---|
| 342 |
catch(e) { this.error(e); } |
|---|
| 343 |
}, |
|---|
| 344 |
assertHidden: function(element) { |
|---|
| 345 |
var message = arguments[1] || 'assertHidden'; |
|---|
| 346 |
this.assertEqual("none", element.style.display, message); |
|---|
| 347 |
}, |
|---|
| 348 |
assertNotNull: function(object) { |
|---|
| 349 |
var message = arguments[1] || 'assertNotNull'; |
|---|
| 350 |
this.assert(object != null, message); |
|---|
| 351 |
}, |
|---|
| 352 |
assertType: function(expected, actual) { |
|---|
| 353 |
var message = arguments[2] || 'assertType'; |
|---|
| 354 |
try { |
|---|
| 355 |
(actual.constructor == expected) ? this.pass() : |
|---|
| 356 |
this.fail(message + ': expected "' + Test.Unit.inspect(expected) + |
|---|
| 357 |
'", actual "' + (actual.constructor) + '"'); } |
|---|
| 358 |
catch(e) { this.error(e); } |
|---|
| 359 |
}, |
|---|
| 360 |
assertNotOfType: function(expected, actual) { |
|---|
| 361 |
var message = arguments[2] || 'assertNotOfType'; |
|---|
| 362 |
try { |
|---|
| 363 |
(actual.constructor != expected) ? this.pass() : |
|---|
| 364 |
this.fail(message + ': expected "' + Test.Unit.inspect(expected) + |
|---|
| 365 |
'", actual "' + (actual.constructor) + '"'); } |
|---|
| 366 |
catch(e) { this.error(e); } |
|---|
| 367 |
}, |
|---|
| 368 |
assertInstanceOf: function(expected, actual) { |
|---|
| 369 |
var message = arguments[2] || 'assertInstanceOf'; |
|---|
| 370 |
try { |
|---|
| 371 |
(actual instanceof expected) ? this.pass() : |
|---|
| 372 |
this.fail(message + ": object was not an instance of the expected type"); } |
|---|
| 373 |
catch(e) { this.error(e); } |
|---|
| 374 |
}, |
|---|
| 375 |
assertNotInstanceOf: function(expected, actual) { |
|---|
| 376 |
var message = arguments[2] || 'assertNotInstanceOf'; |
|---|
| 377 |
try { |
|---|
| 378 |
!(actual instanceof expected) ? this.pass() : |
|---|
| 379 |
this.fail(message + ": object was an instance of the not expected type"); } |
|---|
| 380 |
catch(e) { this.error(e); } |
|---|
| 381 |
}, |
|---|
| 382 |
assertRespondsTo: function(method, obj) { |
|---|
| 383 |
var message = arguments[2] || 'assertRespondsTo'; |
|---|
| 384 |
try { |
|---|
| 385 |
(obj[method] && typeof obj[method] == 'function') ? this.pass() : |
|---|
| 386 |
this.fail(message + ": object doesn't respond to [" + method + "]"); } |
|---|
| 387 |
catch(e) { this.error(e); } |
|---|
| 388 |
}, |
|---|
| 389 |
assertReturnsTrue: function(method, obj) { |
|---|
| 390 |
var message = arguments[2] || 'assertReturnsTrue'; |
|---|
| 391 |
try { |
|---|
| 392 |
var m = obj[method]; |
|---|
| 393 |
if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; |
|---|
| 394 |
m() ? this.pass() : |
|---|
| 395 |
this.fail(message + ": method returned false"); } |
|---|
| 396 |
catch(e) { this.error(e); } |
|---|
| 397 |
}, |
|---|
| 398 |
assertReturnsFalse: function(method, obj) { |
|---|
| 399 |
var message = arguments[2] || 'assertReturnsFalse'; |
|---|
| 400 |
try { |
|---|
| 401 |
var m = obj[method]; |
|---|
| 402 |
if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; |
|---|
| 403 |
!m() ? this.pass() : |
|---|
| 404 |
this.fail(message + ": method returned true"); } |
|---|
| 405 |
catch(e) { this.error(e); } |
|---|
| 406 |
}, |
|---|
| 407 |
assertRaise: function(exceptionName, method) { |
|---|
| 408 |
var message = arguments[2] || 'assertRaise'; |
|---|
| 409 |
try { |
|---|
| 410 |
method(); |
|---|
| 411 |
this.fail(message + ": exception expected but none was raised"); } |
|---|
| 412 |
catch(e) { |
|---|
| 413 |
((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e); |
|---|
| 414 |
} |
|---|
| 415 |
}, |
|---|
| 416 |
assertElementsMatch: function() { |
|---|
| 417 |
var expressions = $A(arguments), elements = $A(expressions.shift()); |
|---|
| 418 |
if (elements.length != expressions.length) { |
|---|
| 419 |
this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions'); |
|---|
| 420 |
return false; |
|---|
| 421 |
} |
|---|
| 422 |
elements.zip(expressions).all(function(pair, index) { |
|---|
| 423 |
var element = $(pair.first()), expression = pair.last(); |
|---|
| 424 |
if (element.match(expression)) return true; |
|---|
| 425 |
this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect()); |
|---|
| 426 |
}.bind(this)) && this.pass(); |
|---|
| 427 |
}, |
|---|
| 428 |
assertElementMatches: function(element, expression) { |
|---|
| 429 |
this.assertElementsMatch([element], expression); |
|---|
| 430 |
}, |
|---|
| 431 |
benchmark: function(operation, iterations) { |
|---|
| 432 |
var startAt = new Date(); |
|---|
| 433 |
(iterations || 1).times(operation); |
|---|
| 434 |
var timeTaken = ((new Date())-startAt); |
|---|
| 435 |
this.info((arguments[2] || 'Operation') + ' finished ' + |
|---|
| 436 |
iterations + ' iterations in ' + (timeTaken/1000)+'s' ); |
|---|
| 437 |
return timeTaken; |
|---|
| 438 |
}, |
|---|
| 439 |
_isVisible: function(element) { |
|---|
| 440 |
element = $(element); |
|---|
| 441 |
if(!element.parentNode) return true; |
|---|
| 442 |
this.assertNotNull(element); |
|---|
| 443 |
if(element.style && Element.getStyle(element, 'display') == 'none') |
|---|
| 444 |
return false; |
|---|
| 445 |
|
|---|
| 446 |
return this._isVisible(element.parentNode); |
|---|
| 447 |
}, |
|---|
| 448 |
assertNotVisible: function(element) { |
|---|
| 449 |
this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1])); |
|---|
| 450 |
}, |
|---|
| 451 |
assertVisible: function(element) { |
|---|
| 452 |
this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1])); |
|---|
| 453 |
}, |
|---|
| 454 |
benchmark: function(operation, iterations) { |
|---|
| 455 |
var startAt = new Date(); |
|---|
| 456 |
(iterations || 1).times(operation); |
|---|
| 457 |
var timeTaken = ((new Date())-startAt); |
|---|
| 458 |
this.info((arguments[2] || 'Operation') + ' finished ' + |
|---|
| 459 |
iterations + ' iterations in ' + (timeTaken/1000)+'s' ); |
|---|
| 460 |
return timeTaken; |
|---|
| 461 |
} |
|---|
| 462 |
} |
|---|
| 463 |
|
|---|
| 464 |
Test.Unit.Testcase = Class.create(); |
|---|
| 465 |
Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), { |
|---|
| 466 |
initialize: function(name, test, setup, teardown) { |
|---|
| 467 |
Test.Unit.Assertions.prototype.initialize.bind(this)(); |
|---|
| 468 |
this.name = name; |
|---|
| 469 |
|
|---|
| 470 |
if(typeof test == 'string') { |
|---|
| 471 |
test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,'); |
|---|
| 472 |
test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)'); |
|---|
| 473 |
this.test = function() { |
|---|
| 474 |
eval('with(this){'+test+'}'); |
|---|
| 475 |
} |
|---|
| 476 |
} else { |
|---|
| 477 |
this.test = test || function() {}; |
|---|
| 478 |
} |
|---|
| 479 |
|
|---|
| 480 |
this.setup = setup || function() {}; |
|---|
| 481 |
this.teardown = teardown || function() {}; |
|---|
| 482 |
this.isWaiting = false; |
|---|
| 483 |
this.timeToWait = 1000; |
|---|
| 484 |
}, |
|---|
| 485 |
wait: function(time, nextPart) { |
|---|
| 486 |
this.isWaiting = true; |
|---|
| 487 |
this.test = nextPart; |
|---|
| 488 |
this.timeToWait = time; |
|---|
| 489 |
}, |
|---|
| 490 |
run: function() { |
|---|
| 491 |
try { |
|---|
| 492 |
try { |
|---|
| 493 |
if (!this.isWaiting) this.setup.bind(this)(); |
|---|
| 494 |
this.isWaiting = false; |
|---|
| 495 |
this.test.bind(this)(); |
|---|
| 496 |
} finally { |
|---|
| 497 |
if(!this.isWaiting) { |
|---|
| 498 |
this.teardown.bind(this)(); |
|---|
| 499 |
} |
|---|
| 500 |
} |
|---|
| 501 |
} |
|---|
| 502 |
catch(e) { this.error(e); } |
|---|
| 503 |
} |
|---|
| 504 |
}); |
|---|
| 505 |
|
|---|
| 506 |
|
|---|
| 507 |
|
|---|
| 508 |
|
|---|
| 509 |
Test.setupBDDExtensionMethods = function(){ |
|---|
| 510 |
var METHODMAP = { |
|---|
| 511 |
shouldEqual: 'assertEqual', |
|---|
| 512 |
shouldNotEqual: 'assertNotEqual', |
|---|
| 513 |
shouldEqualEnum: 'assertEnumEqual', |
|---|
| 514 |
shouldBeA: 'assertType', |
|---|
| 515 |
shouldNotBeA: 'assertNotOfType', |
|---|
| 516 |
shouldBeAn: 'assertType', |
|---|
| 517 |
shouldNotBeAn: 'assertNotOfType', |
|---|
| 518 |
shouldBeNull: 'assertNull', |
|---|
| 519 |
shouldNotBeNull: 'assertNotNull', |
|---|
| 520 |
|
|---|
| 521 |
shouldBe: 'assertReturnsTrue', |
|---|
| 522 |
shouldNotBe: 'assertReturnsFalse', |
|---|
| 523 |
shouldRespondTo: 'assertRespondsTo' |
|---|
| 524 |
}; |
|---|
| 525 |
var makeAssertion = function(assertion, args, object) { |
|---|
| 526 |
this[assertion].apply(this,(args || []).concat([object])); |
|---|
| 527 |
} |
|---|
| 528 |
|
|---|
| 529 |
Test.BDDMethods = {}; |
|---|
| 530 |
$H(METHODMAP).each(function(pair) { |
|---|
| 531 |
Test.BDDMethods[pair.key] = function() { |
|---|
| 532 |
var args = $A(arguments); |
|---|
| 533 |
var scope = args.shift(); |
|---|
| 534 |
makeAssertion.apply(scope, [pair.value, args, this]); }; |
|---|
| 535 |
}); |
|---|
| 536 |
|
|---|
| 537 |
[Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each( |
|---|
| 538 |
function(p){ Object.extend(p, Test.BDDMethods) } |
|---|
| 539 |
); |
|---|
| 540 |
} |
|---|
| 541 |
|
|---|
| 542 |
Test.context = function(name, spec, log){ |
|---|
| 543 |
Test.setupBDDExtensionMethods(); |
|---|
| 544 |
|
|---|
| 545 |
var compiledSpec = {}; |
|---|
| 546 |
var titles = {}; |
|---|
| 547 |
for(specName in spec) { |
|---|
| 548 |
switch(specName){ |
|---|
| 549 |
case "setup": |
|---|
| 550 |
case "teardown": |
|---|
| 551 |
compiledSpec[specName] = spec[specName]; |
|---|
| 552 |
break; |
|---|
| 553 |
default: |
|---|
| 554 |
var testName = 'test'+specName.gsub(/\s+/,'-').camelize(); |
|---|
| 555 |
var body = spec[specName].toString().split('\n').slice(1); |
|---|
| 556 |
if(/^\{/.test(body[0])) body = body.slice(1); |
|---|
| 557 |
body.pop(); |
|---|
| 558 |
body = body.map(function(statement){ |
|---|
| 559 |
return statement.strip() |
|---|
| 560 |
}); |
|---|
| 561 |
compiledSpec[testName] = body.join('\n'); |
|---|
| 562 |
titles[testName] = specName; |
|---|
| 563 |
} |
|---|
| 564 |
} |
|---|
| 565 |
new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name }); |
|---|
| 566 |
}; |
|---|