dom/tests/mochitest/ajax/scriptaculous/src/unittest.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/tests/mochitest/ajax/scriptaculous/src/unittest.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,586 @@
     1.4 +// script.aculo.us unittest.js v1.7.1_beta2, Tue May 15 15:15:45 EDT 2007
     1.5 +
     1.6 +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     1.7 +//           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
     1.8 +//           (c) 2005-2007 Michael Schuerig (http://www.schuerig.de/michael/)
     1.9 +//
    1.10 +// script.aculo.us is freely distributable under the terms of an MIT-style license.
    1.11 +// For details, see the script.aculo.us web site: http://script.aculo.us/
    1.12 +
    1.13 +// experimental, Firefox-only
    1.14 +Event.simulateMouse = function(element, eventName) {
    1.15 +  var options = Object.extend({
    1.16 +    pointerX: 0,
    1.17 +    pointerY: 0,
    1.18 +    buttons:  0,
    1.19 +    ctrlKey:  false,
    1.20 +    altKey:   false,
    1.21 +    shiftKey: false,
    1.22 +    metaKey:  false
    1.23 +  }, arguments[2] || {});
    1.24 +  var oEvent = document.createEvent("MouseEvents");
    1.25 +  oEvent.initMouseEvent(eventName, true, true, document.defaultView, 
    1.26 +    options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, 
    1.27 +    options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element));
    1.28 +  
    1.29 +  if(this.mark) Element.remove(this.mark);
    1.30 +  this.mark = document.createElement('div');
    1.31 +  this.mark.appendChild(document.createTextNode(" "));
    1.32 +  document.body.appendChild(this.mark);
    1.33 +  this.mark.style.position = 'absolute';
    1.34 +  this.mark.style.top = options.pointerY + "px";
    1.35 +  this.mark.style.left = options.pointerX + "px";
    1.36 +  this.mark.style.width = "5px";
    1.37 +  this.mark.style.height = "5px;";
    1.38 +  this.mark.style.borderTop = "1px solid red;"
    1.39 +  this.mark.style.borderLeft = "1px solid red;"
    1.40 +  
    1.41 +  if(this.step)
    1.42 +    alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
    1.43 +  
    1.44 +  $(element).dispatchEvent(oEvent);
    1.45 +};
    1.46 +
    1.47 +// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
    1.48 +// You need to downgrade to 1.0.4 for now to get this working
    1.49 +// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
    1.50 +Event.simulateKey = function(element, eventName) {
    1.51 +  var options = Object.extend({
    1.52 +    ctrlKey: false,
    1.53 +    altKey: false,
    1.54 +    shiftKey: false,
    1.55 +    metaKey: false,
    1.56 +    keyCode: 0,
    1.57 +    charCode: 0
    1.58 +  }, arguments[2] || {});
    1.59 +
    1.60 +  var oEvent = document.createEvent("KeyEvents");
    1.61 +  oEvent.initKeyEvent(eventName, true, true, window, 
    1.62 +    options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
    1.63 +    options.keyCode, options.charCode );
    1.64 +  $(element).dispatchEvent(oEvent);
    1.65 +};
    1.66 +
    1.67 +Event.simulateKeys = function(element, command) {
    1.68 +  for(var i=0; i<command.length; i++) {
    1.69 +    Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
    1.70 +  }
    1.71 +};
    1.72 +
    1.73 +var Test = {}
    1.74 +Test.Unit = {};
    1.75 +
    1.76 +// security exception workaround
    1.77 +Test.Unit.inspect = Object.inspect;
    1.78 +
    1.79 +Test.Unit.Logger = Class.create();
    1.80 +Test.Unit.Logger.prototype = {
    1.81 +  initialize: function(log) {
    1.82 +    this.log = $(log);
    1.83 +    if (this.log) {
    1.84 +      this._createLogTable();
    1.85 +    }
    1.86 +  },
    1.87 +  start: function(testName) {
    1.88 +    if (!this.log) return;
    1.89 +    this.testName = testName;
    1.90 +    this.lastLogLine = document.createElement('tr');
    1.91 +    this.statusCell = document.createElement('td');
    1.92 +    this.nameCell = document.createElement('td');
    1.93 +    this.nameCell.className = "nameCell";
    1.94 +    this.nameCell.appendChild(document.createTextNode(testName));
    1.95 +    this.messageCell = document.createElement('td');
    1.96 +    this.lastLogLine.appendChild(this.statusCell);
    1.97 +    this.lastLogLine.appendChild(this.nameCell);
    1.98 +    this.lastLogLine.appendChild(this.messageCell);
    1.99 +    this.loglines.appendChild(this.lastLogLine);
   1.100 +  },
   1.101 +  finish: function(status, summary) {
   1.102 +    if (!this.log) return;
   1.103 +    this.lastLogLine.className = status;
   1.104 +    this.statusCell.innerHTML = status;
   1.105 +    this.messageCell.innerHTML = this._toHTML(summary);
   1.106 +    this.addLinksToResults();
   1.107 +  },
   1.108 +  message: function(message) {
   1.109 +    if (!this.log) return;
   1.110 +    this.messageCell.innerHTML = this._toHTML(message);
   1.111 +  },
   1.112 +  summary: function(summary) {
   1.113 +    if (!this.log) return;
   1.114 +    this.logsummary.innerHTML = this._toHTML(summary);
   1.115 +  },
   1.116 +  _createLogTable: function() {
   1.117 +    this.log.innerHTML =
   1.118 +    '<div id="logsummary"></div>' +
   1.119 +    '<table id="logtable">' +
   1.120 +    '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
   1.121 +    '<tbody id="loglines"></tbody>' +
   1.122 +    '</table>';
   1.123 +    this.logsummary = $('logsummary')
   1.124 +    this.loglines = $('loglines');
   1.125 +  },
   1.126 +  _toHTML: function(txt) {
   1.127 +    return txt.escapeHTML().replace(/\n/g,"<br/>");
   1.128 +  },
   1.129 +  addLinksToResults: function(){ 
   1.130 +    $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log
   1.131 +      td.title = "Run only this test"
   1.132 +      Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;});
   1.133 +    });
   1.134 +    $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log
   1.135 +      td.title = "Run all tests"
   1.136 +      Event.observe(td, 'click', function(){ window.location.search = "";});
   1.137 +    });
   1.138 +  }
   1.139 +}
   1.140 +
   1.141 +Test.Unit.Runner = Class.create();
   1.142 +Test.Unit.Runner.prototype = {
   1.143 +  initialize: function(testcases) {
   1.144 +    this.options = Object.extend({
   1.145 +      testLog: 'testlog'
   1.146 +    }, arguments[1] || {});
   1.147 +    this.options.resultsURL = this.parseResultsURLQueryParameter();
   1.148 +    this.options.tests      = this.parseTestsQueryParameter();
   1.149 +    if (this.options.testLog) {
   1.150 +      this.options.testLog = $(this.options.testLog) || null;
   1.151 +    }
   1.152 +    if(this.options.tests) {
   1.153 +      this.tests = [];
   1.154 +      for(var i = 0; i < this.options.tests.length; i++) {
   1.155 +        if(/^test/.test(this.options.tests[i])) {
   1.156 +          this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
   1.157 +        }
   1.158 +      }
   1.159 +    } else {
   1.160 +      if (this.options.test) {
   1.161 +        this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
   1.162 +      } else {
   1.163 +        this.tests = [];
   1.164 +        for(var testcase in testcases) {
   1.165 +          if(/^test/.test(testcase)) {
   1.166 +            this.tests.push(
   1.167 +               new Test.Unit.Testcase(
   1.168 +                 this.options.context ? ' -> ' + this.options.titles[testcase] : testcase, 
   1.169 +                 testcases[testcase], testcases["setup"], testcases["teardown"]
   1.170 +               ));
   1.171 +          }
   1.172 +        }
   1.173 +      }
   1.174 +    }
   1.175 +    this.currentTest = 0;
   1.176 +    this.logger = new Test.Unit.Logger(this.options.testLog);
   1.177 +    setTimeout(this.runTests.bind(this), 1000);
   1.178 +  },
   1.179 +  parseResultsURLQueryParameter: function() {
   1.180 +    return window.location.search.parseQuery()["resultsURL"];
   1.181 +  },
   1.182 +  parseTestsQueryParameter: function(){
   1.183 +    if (window.location.search.parseQuery()["tests"]){
   1.184 +        return window.location.search.parseQuery()["tests"].split(',');
   1.185 +    };
   1.186 +  },
   1.187 +  // Returns:
   1.188 +  //  "ERROR" if there was an error,
   1.189 +  //  "FAILURE" if there was a failure, or
   1.190 +  //  "SUCCESS" if there was neither
   1.191 +  getResult: function() {
   1.192 +    var hasFailure = false;
   1.193 +    for(var i=0;i<this.tests.length;i++) {
   1.194 +      if (this.tests[i].errors > 0) {
   1.195 +        return "ERROR";
   1.196 +      }
   1.197 +      if (this.tests[i].failures > 0) {
   1.198 +        hasFailure = true;
   1.199 +      }
   1.200 +    }
   1.201 +    if (hasFailure) {
   1.202 +      return "FAILURE";
   1.203 +    } else {
   1.204 +      return "SUCCESS";
   1.205 +    }
   1.206 +  },
   1.207 +  postResults: function() {
   1.208 +    if (this.options.resultsURL) {
   1.209 +      new Ajax.Request(this.options.resultsURL, 
   1.210 +        { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
   1.211 +    }
   1.212 +  },
   1.213 +  runTests: function() {
   1.214 +    var test = this.tests[this.currentTest];
   1.215 +    if (!test) {
   1.216 +      // finished!
   1.217 +      this.postResults();
   1.218 +      this.logger.summary(this.summary());
   1.219 +      return;
   1.220 +    }
   1.221 +    if(!test.isWaiting) {
   1.222 +      this.logger.start(test.name);
   1.223 +    }
   1.224 +    test.run();
   1.225 +    if(test.isWaiting) {
   1.226 +      this.logger.message("Waiting for " + test.timeToWait + "ms");
   1.227 +      setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
   1.228 +    } else {
   1.229 +      this.logger.finish(test.status(), test.summary());
   1.230 +      this.currentTest++;
   1.231 +      // tail recursive, hopefully the browser will skip the stackframe
   1.232 +      this.runTests();
   1.233 +    }
   1.234 +  },
   1.235 +  summary: function() {
   1.236 +    var assertions = 0;
   1.237 +    var failures = 0;
   1.238 +    var errors = 0;
   1.239 +    var messages = [];
   1.240 +    for(var i=0;i<this.tests.length;i++) {
   1.241 +      assertions +=   this.tests[i].assertions;
   1.242 +      failures   +=   this.tests[i].failures;
   1.243 +      errors     +=   this.tests[i].errors;
   1.244 +    }
   1.245 +    return (
   1.246 +      (this.options.context ? this.options.context + ': ': '') + 
   1.247 +      this.tests.length + " tests, " + 
   1.248 +      assertions + " assertions, " + 
   1.249 +      failures   + " failures, " +
   1.250 +      errors     + " errors");
   1.251 +  }
   1.252 +}
   1.253 +
   1.254 +Test.Unit.Assertions = Class.create();
   1.255 +Test.Unit.Assertions.prototype = {
   1.256 +  initialize: function() {
   1.257 +    this.assertions = 0;
   1.258 +    this.failures   = 0;
   1.259 +    this.errors     = 0;
   1.260 +    this.messages   = [];
   1.261 +  },
   1.262 +  summary: function() {
   1.263 +    return (
   1.264 +      this.assertions + " assertions, " + 
   1.265 +      this.failures   + " failures, " +
   1.266 +      this.errors     + " errors" + "\n" +
   1.267 +      this.messages.join("\n"));
   1.268 +  },
   1.269 +  pass: function() {
   1.270 +    this.assertions++;
   1.271 +  },
   1.272 +  fail: function(message) {
   1.273 +    this.failures++;
   1.274 +    this.messages.push("Failure: " + message);
   1.275 +  },
   1.276 +  info: function(message) {
   1.277 +    this.messages.push("Info: " + message);
   1.278 +  },
   1.279 +  error: function(error) {
   1.280 +    this.errors++;
   1.281 +    this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")");
   1.282 +  },
   1.283 +  status: function() {
   1.284 +    if (this.failures > 0) return 'failed';
   1.285 +    if (this.errors > 0) return 'error';
   1.286 +    return 'passed';
   1.287 +  },
   1.288 +  assert: function(expression) {
   1.289 +    var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
   1.290 +    try { expression ? this.pass() : 
   1.291 +      this.fail(message); }
   1.292 +    catch(e) { this.error(e); }
   1.293 +  },
   1.294 +  assertEqual: function(expected, actual) {
   1.295 +    var message = arguments[2] || "assertEqual";
   1.296 +    try { (expected == actual) ? this.pass() :
   1.297 +      this.fail(message + ': expected "' + Test.Unit.inspect(expected) + 
   1.298 +        '", actual "' + Test.Unit.inspect(actual) + '"'); }
   1.299 +    catch(e) { this.error(e); }
   1.300 +  },
   1.301 +  assertInspect: function(expected, actual) {
   1.302 +    var message = arguments[2] || "assertInspect";
   1.303 +    try { (expected == actual.inspect()) ? this.pass() :
   1.304 +      this.fail(message + ': expected "' + Test.Unit.inspect(expected) + 
   1.305 +        '", actual "' + Test.Unit.inspect(actual) + '"'); }
   1.306 +    catch(e) { this.error(e); }
   1.307 +  },
   1.308 +  assertEnumEqual: function(expected, actual) {
   1.309 +    var message = arguments[2] || "assertEnumEqual";
   1.310 +    try { $A(expected).length == $A(actual).length && 
   1.311 +      expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ?
   1.312 +        this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + 
   1.313 +          ', actual ' + Test.Unit.inspect(actual)); }
   1.314 +    catch(e) { this.error(e); }
   1.315 +  },
   1.316 +  assertNotEqual: function(expected, actual) {
   1.317 +    var message = arguments[2] || "assertNotEqual";
   1.318 +    try { (expected != actual) ? this.pass() : 
   1.319 +      this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
   1.320 +    catch(e) { this.error(e); }
   1.321 +  },
   1.322 +  assertIdentical: function(expected, actual) { 
   1.323 +    var message = arguments[2] || "assertIdentical"; 
   1.324 +    try { (expected === actual) ? this.pass() : 
   1.325 +      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
   1.326 +        '", actual "' + Test.Unit.inspect(actual) + '"'); } 
   1.327 +    catch(e) { this.error(e); } 
   1.328 +  },
   1.329 +  assertNotIdentical: function(expected, actual) { 
   1.330 +    var message = arguments[2] || "assertNotIdentical"; 
   1.331 +    try { !(expected === actual) ? this.pass() : 
   1.332 +      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
   1.333 +        '", actual "' + Test.Unit.inspect(actual) + '"'); } 
   1.334 +    catch(e) { this.error(e); } 
   1.335 +  },
   1.336 +  assertNull: function(obj) {
   1.337 +    var message = arguments[1] || 'assertNull'
   1.338 +    try { (obj==null) ? this.pass() : 
   1.339 +      this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
   1.340 +    catch(e) { this.error(e); }
   1.341 +  },
   1.342 +  assertMatch: function(expected, actual) {
   1.343 +    var message = arguments[2] || 'assertMatch';
   1.344 +    var regex = new RegExp(expected);
   1.345 +    try { (regex.exec(actual)) ? this.pass() :
   1.346 +      this.fail(message + ' : regex: "' +  Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); }
   1.347 +    catch(e) { this.error(e); }
   1.348 +  },
   1.349 +  assertHidden: function(element) {
   1.350 +    var message = arguments[1] || 'assertHidden';
   1.351 +    this.assertEqual("none", element.style.display, message);
   1.352 +  },
   1.353 +  assertNotNull: function(object) {
   1.354 +    var message = arguments[1] || 'assertNotNull';
   1.355 +    this.assert(object != null, message);
   1.356 +  },
   1.357 +  assertType: function(expected, actual) {
   1.358 +    var message = arguments[2] || 'assertType';
   1.359 +    try { 
   1.360 +      (actual.constructor == expected) ? this.pass() : 
   1.361 +      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
   1.362 +        '", actual "' + (actual.constructor) + '"'); }
   1.363 +    catch(e) { this.error(e); }
   1.364 +  },
   1.365 +  assertNotOfType: function(expected, actual) {
   1.366 +    var message = arguments[2] || 'assertNotOfType';
   1.367 +    try { 
   1.368 +      (actual.constructor != expected) ? this.pass() : 
   1.369 +      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
   1.370 +        '", actual "' + (actual.constructor) + '"'); }
   1.371 +    catch(e) { this.error(e); }
   1.372 +  },
   1.373 +  assertInstanceOf: function(expected, actual) {
   1.374 +    var message = arguments[2] || 'assertInstanceOf';
   1.375 +    try { 
   1.376 +      (actual instanceof expected) ? this.pass() : 
   1.377 +      this.fail(message + ": object was not an instance of the expected type"); }
   1.378 +    catch(e) { this.error(e); } 
   1.379 +  },
   1.380 +  assertNotInstanceOf: function(expected, actual) {
   1.381 +    var message = arguments[2] || 'assertNotInstanceOf';
   1.382 +    try { 
   1.383 +      !(actual instanceof expected) ? this.pass() : 
   1.384 +      this.fail(message + ": object was an instance of the not expected type"); }
   1.385 +    catch(e) { this.error(e); } 
   1.386 +  },
   1.387 +  assertRespondsTo: function(method, obj) {
   1.388 +    var message = arguments[2] || 'assertRespondsTo';
   1.389 +    try {
   1.390 +      (obj[method] && typeof obj[method] == 'function') ? this.pass() : 
   1.391 +      this.fail(message + ": object doesn't respond to [" + method + "]"); }
   1.392 +    catch(e) { this.error(e); }
   1.393 +  },
   1.394 +  assertReturnsTrue: function(method, obj) {
   1.395 +    var message = arguments[2] || 'assertReturnsTrue';
   1.396 +    try {
   1.397 +      var m = obj[method];
   1.398 +      if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
   1.399 +      m() ? this.pass() : 
   1.400 +      this.fail(message + ": method returned false"); }
   1.401 +    catch(e) { this.error(e); }
   1.402 +  },
   1.403 +  assertReturnsFalse: function(method, obj) {
   1.404 +    var message = arguments[2] || 'assertReturnsFalse';
   1.405 +    try {
   1.406 +      var m = obj[method];
   1.407 +      if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
   1.408 +      !m() ? this.pass() : 
   1.409 +      this.fail(message + ": method returned true"); }
   1.410 +    catch(e) { this.error(e); }
   1.411 +  },
   1.412 +  assertRaise: function(exceptionName, method) {
   1.413 +    var message = arguments[2] || 'assertRaise';
   1.414 +    try { 
   1.415 +      method();
   1.416 +      this.fail(message + ": exception expected but none was raised"); }
   1.417 +    catch(e) {
   1.418 +      ((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e); 
   1.419 +    }
   1.420 +  },
   1.421 +  assertElementsMatch: function() {
   1.422 +    var expressions = $A(arguments), elements = $A(expressions.shift());
   1.423 +    if (elements.length != expressions.length) {
   1.424 +      this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
   1.425 +      return false;
   1.426 +    }
   1.427 +    elements.zip(expressions).all(function(pair, index) {
   1.428 +      var element = $(pair.first()), expression = pair.last();
   1.429 +      if (element.match(expression)) return true;
   1.430 +      this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
   1.431 +    }.bind(this)) && this.pass();
   1.432 +  },
   1.433 +  assertElementMatches: function(element, expression) {
   1.434 +    this.assertElementsMatch([element], expression);
   1.435 +  },
   1.436 +  benchmark: function(operation, iterations) {
   1.437 +    var startAt = new Date();
   1.438 +    (iterations || 1).times(operation);
   1.439 +    var timeTaken = ((new Date())-startAt);
   1.440 +    this.info((arguments[2] || 'Operation') + ' finished ' + 
   1.441 +       iterations + ' iterations in ' + (timeTaken/1000)+'s' );
   1.442 +    return timeTaken;
   1.443 +  },
   1.444 +  _isVisible: function(element) {
   1.445 +    element = $(element);
   1.446 +    if(!element.parentNode) return true;
   1.447 +    this.assertNotNull(element);
   1.448 +    if(element.style && Element.getStyle(element, 'display') == 'none')
   1.449 +      return false;
   1.450 +    
   1.451 +    return this._isVisible(element.parentNode);
   1.452 +  },
   1.453 +  assertNotVisible: function(element) {
   1.454 +    this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
   1.455 +  },
   1.456 +  assertVisible: function(element) {
   1.457 +    this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
   1.458 +  },
   1.459 +  benchmark: function(operation, iterations) {
   1.460 +    var startAt = new Date();
   1.461 +    (iterations || 1).times(operation);
   1.462 +    var timeTaken = ((new Date())-startAt);
   1.463 +    this.info((arguments[2] || 'Operation') + ' finished ' + 
   1.464 +       iterations + ' iterations in ' + (timeTaken/1000)+'s' );
   1.465 +    return timeTaken;
   1.466 +  }
   1.467 +}
   1.468 +
   1.469 +Test.Unit.Testcase = Class.create();
   1.470 +Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
   1.471 +  initialize: function(name, test, setup, teardown) {
   1.472 +    Test.Unit.Assertions.prototype.initialize.bind(this)();
   1.473 +    this.name           = name;
   1.474 +    
   1.475 +    if(typeof test == 'string') {
   1.476 +      test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
   1.477 +      test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
   1.478 +      this.test = function() {
   1.479 +        eval('with(this){'+test+'}');
   1.480 +      }
   1.481 +    } else {
   1.482 +      this.test = test || function() {};
   1.483 +    }
   1.484 +    
   1.485 +    this.setup          = setup || function() {};
   1.486 +    this.teardown       = teardown || function() {};
   1.487 +    this.isWaiting      = false;
   1.488 +    this.timeToWait     = 1000;
   1.489 +  },
   1.490 +  wait: function(time, nextPart) {
   1.491 +    this.isWaiting = true;
   1.492 +    this.test = nextPart;
   1.493 +    this.timeToWait = time;
   1.494 +  },
   1.495 +  run: function() {
   1.496 +    try {
   1.497 +      try {
   1.498 +        if (!this.isWaiting) this.setup.bind(this)();
   1.499 +        this.isWaiting = false;
   1.500 +        this.test.bind(this)();
   1.501 +      } finally {
   1.502 +        if(!this.isWaiting) {
   1.503 +          this.teardown.bind(this)();
   1.504 +        }
   1.505 +      }
   1.506 +    }
   1.507 +    catch(e) { this.error(e); }
   1.508 +  }
   1.509 +});
   1.510 +
   1.511 +// *EXPERIMENTAL* BDD-style testing to please non-technical folk
   1.512 +// This draws many ideas from RSpec http://rspec.rubyforge.org/
   1.513 +
   1.514 +Test.setupBDDExtensionMethods = function(){
   1.515 +  var METHODMAP = {
   1.516 +    shouldEqual:     'assertEqual',
   1.517 +    shouldNotEqual:  'assertNotEqual',
   1.518 +    shouldEqualEnum: 'assertEnumEqual',
   1.519 +    shouldBeA:       'assertType',
   1.520 +    shouldNotBeA:    'assertNotOfType',
   1.521 +    shouldBeAn:      'assertType',
   1.522 +    shouldNotBeAn:   'assertNotOfType',
   1.523 +    shouldBeNull:    'assertNull',
   1.524 +    shouldNotBeNull: 'assertNotNull',
   1.525 +    
   1.526 +    shouldBe:        'assertReturnsTrue',
   1.527 +    shouldNotBe:     'assertReturnsFalse',
   1.528 +    shouldRespondTo: 'assertRespondsTo'
   1.529 +  };
   1.530 +  Test.BDDMethods = {};
   1.531 +  for(m in METHODMAP) {
   1.532 +    Test.BDDMethods[m] = eval(
   1.533 +      'function(){'+
   1.534 +      'var args = $A(arguments);'+
   1.535 +      'var scope = args.shift();'+
   1.536 +      'scope.'+METHODMAP[m]+'.apply(scope,(args || []).concat([this])); }');
   1.537 +  }
   1.538 +  [Array.prototype, String.prototype, Number.prototype].each(
   1.539 +    function(p){ Object.extend(p, Test.BDDMethods) }
   1.540 +  );
   1.541 +}
   1.542 +
   1.543 +Test.context = function(name, spec, log){
   1.544 +  Test.setupBDDExtensionMethods();
   1.545 +  
   1.546 +  var compiledSpec = {};
   1.547 +  var titles = {};
   1.548 +  for(specName in spec) {
   1.549 +    switch(specName){
   1.550 +      case "setup":
   1.551 +      case "teardown":
   1.552 +        compiledSpec[specName] = spec[specName];
   1.553 +        break;
   1.554 +      default:
   1.555 +        var testName = 'test'+specName.gsub(/\s+/,'-').camelize();
   1.556 +        var body = spec[specName].toString().split('\n').slice(1);
   1.557 +        if(/^\{/.test(body[0])) body = body.slice(1);
   1.558 +        body.pop();
   1.559 +        body = body.map(function(statement){ 
   1.560 +          return statement.strip()
   1.561 +        });
   1.562 +        compiledSpec[testName] = body.join('\n');
   1.563 +        titles[testName] = specName;
   1.564 +    }
   1.565 +  }
   1.566 +  new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name });
   1.567 +};
   1.568 +
   1.569 +if ( parent.SimpleTest && parent.runAJAXTest ) (function(){
   1.570 +        var finish = Test.Unit.Logger.prototype.finish;
   1.571 +        Test.Unit.Logger.prototype.finish = function(status,summary){
   1.572 +		var match = summary.match(/(\d+).*(\d+).*(\d+)/)
   1.573 +		var fail = parseInt(match[2]) + parseInt(match[3]);
   1.574 +		var pass = match[1] - fail;
   1.575 +
   1.576 +		for ( var i = 0; i < pass; i++ )
   1.577 +                	parent.SimpleTest.ok( true, this.testName, summary );
   1.578 +
   1.579 +		for ( var i = 0; i < fail; i++ )
   1.580 +                	parent.SimpleTest.ok( false, this.testName, summary );
   1.581 +
   1.582 +                return finish.apply( this, arguments );
   1.583 +        };
   1.584 +
   1.585 +        // Intentionally overwrite (to stop the Ajax request)
   1.586 +        Test.Unit.Runner.prototype.postResults = parent.runAJAXTest;
   1.587 +
   1.588 +	Ajax.InPlaceEditor.prototype.onFailure = function(){};
   1.589 +})();

mercurial