Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 8643

Show
Ignore:
Timestamp:
01/14/08 14:16:27 (9 months ago)
Author:
tobie
Message:

prototype: Add Test.Unit.MessageTemplate class. Add flunk, buildMessage and assertBlock methods to Test.Unit.Assertions. Refactor accordingly.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • spinoffs/prototype/trunk/CHANGELOG

    r8640 r8643  
    11*SVN* 
     2 
     3* Add Test.Unit.MessageTemplate class. Add flunk, buildMessage and assertBlock methods to Test.Unit.Assertions. Refactor accordingly. [Tobie Langel] 
    24 
    35* Remove useless binding in Template#evaluate. [Tobie Langel] 
  • spinoffs/prototype/trunk/test/lib/unittest.js

    r8580 r8643  
    234234}); 
    235235 
     236Test.Unit.MessageTemplate = Class.create({ 
     237  initialize: function(string) { 
     238    var parts = []; 
     239    (string || '').scan(/(?=[^\\])\?|(?:\\\?|[^\?])+/, function(part) { 
     240      parts.push(part[0]); 
     241    }); 
     242    this.parts = parts; 
     243  }, 
     244   
     245  evaluate: function(params) { 
     246    return this.parts.map(function(part) { 
     247      return part == '?' ? Test.Unit.inspect(params.shift()) : part.replace(/\\\?/, '?'); 
     248    }).join(''); 
     249  } 
     250}); 
     251 
    236252Test.Unit.Assertions = { 
    237   assert: function(expression) { 
    238     var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"'; 
    239     try { expression ? this.pass() :  
    240       this.fail(message); } 
    241     catch(e) { this.error(e); } 
    242   }, 
    243   assertEqual: function(expected, actual) { 
    244     var message = arguments[2] || "assertEqual"; 
    245     try { (expected == actual) ? this.pass() : 
    246       this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
    247         '", actual "' + Test.Unit.inspect(actual) + '"'); } 
    248     catch(e) { this.error(e); } 
    249   }, 
    250   assertNotEqual: function(expected, actual) { 
    251     var message = arguments[2] || "assertNotEqual"; 
    252     try { (expected != actual) ? this.pass() :  
    253       this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); } 
    254     catch(e) { this.error(e); } 
    255   }, 
    256   assertEnumEqual: function(expected, actual) { 
    257     var message = arguments[2] || "assertEnumEqual"; 
     253  buildMessage: function(message, template) { 
     254    var args = $A(arguments).slice(2); 
     255    return (message ? message + '\n' : '') + new Test.Unit.MessageTemplate(template).evaluate(args); 
     256  }, 
     257   
     258  flunk: function(message) { 
     259    this.assertBlock(message || 'Flunked', function() { return false }); 
     260  }, 
     261   
     262  assertBlock: function(message, block) { 
     263    try { 
     264      block.call(this) ? this.pass() : this.fail(message); 
     265    } catch(e) { this.error(e) } 
     266  }, 
     267   
     268  assert: function(expression, message) { 
     269    message = this.buildMessage(message || 'assert', 'got <?>', expression); 
     270    this.assertBlock(message, function() { return expression }); 
     271  }, 
     272   
     273  assertEqual: function(expected, actual, message) { 
     274    message = this.buildMessage(message || 'assertEqual', 'expected <?>, actual: <?>', expected, actual); 
     275    this.assertBlock(message, function() { return expected == actual }); 
     276  }, 
     277   
     278  assertNotEqual: function(expected, actual, message) { 
     279    message = this.buildMessage(message || 'assertNotEqual', 'expected <?>, actual: <?>', expected, actual); 
     280    this.assertBlock(message, function() { return expected != actual }); 
     281  }, 
     282   
     283  assertEnumEqual: function(expected, actual, message) { 
    258284    expected = $A(expected); 
    259285    actual = $A(actual); 
    260     try { expected.length == actual.length &&  
    261       expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ? 
    262         this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +  
    263           ', actual ' + Test.Unit.inspect(actual)); } 
    264     catch(e) { this.error(e); } 
    265   }, 
    266   assertEnumNotEqual: function(expected, actual) { 
    267     var message = arguments[2] || "assertEnumEqual"; 
     286    message = this.buildMessage(message || 'assertEnumEqual', 'expected <?>, actual: <?>', expected, actual); 
     287    this.assertBlock(message, function() { 
     288      return expected.length == actual.length && expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }); 
     289    }); 
     290  }, 
     291   
     292  assertEnumNotEqual: function(expected, actual, message) { 
    268293    expected = $A(expected); 
    269294    actual = $A(actual); 
    270     try { expected.length != actual.length ||  
    271       expected.zip(actual).any(function(pair) { return pair[0] != pair[1] }) ? 
    272         this.pass() : this.fail(message + ': ' + Test.Unit.inspect(expected) +  
    273           ' was the same as ' + Test.Unit.inspect(actual)); } 
    274     catch(e) { this.error(e); } 
    275   }, 
    276   assertHashEqual: function(expected, actual) { 
    277     var message = arguments[2] || "assertHashEqual"; 
     295    message = this.buildMessage(message || 'assertEnumNotEqual', '<?> was the same as <?>', expected, actual); 
     296    this.assertBlock(message, function() { 
     297      return expected.length != actual.length || expected.zip(actual).any(function(pair) { return pair[0] != pair[1] }); 
     298    }); 
     299  }, 
     300   
     301  assertHashEqual: function(expected, actual, message) { 
    278302    expected = $H(expected); 
    279303    actual = $H(actual); 
    280304    var expected_array = expected.toArray().sort(), actual_array = actual.toArray().sort(); 
     305    message = this.buildMessage(message || 'assertHashEqual', 'expected <?>, actual: <?>', expected, actual); 
    281306    // from now we recursively zip & compare nested arrays 
    282     try { expected_array.length == actual_array.length &&  
    283       expected_array.zip(actual_array).all(function(pair) { 
    284         return pair.all(function(i){ return i && i.constructor == Array }) ? 
    285           pair[0].zip(pair[1]).all(arguments.callee) : pair[0] == pair[1]; 
    286       }) ? 
    287         this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +  
    288           ', actual ' + Test.Unit.inspect(actual)); } 
    289     catch(e) { this.error(e); } 
    290   }, 
    291   assertHashNotEqual: function(expected, actual) { 
    292     var message = arguments[2] || "assertHashEqual"; 
     307    var block = function() { 
     308      return expected_array.length == actual_array.length &&  
     309        expected_array.zip(actual_array).all(function(pair) { 
     310          return pair.all(Object.isArray) ? 
     311            pair[0].zip(pair[1]).all(arguments.callee) : pair[0] == pair[1]; 
     312        }); 
     313    }; 
     314    this.assertBlock(message, block); 
     315  }, 
     316   
     317  assertHashNotEqual: function(expected, actual, message) { 
    293318    expected = $H(expected); 
    294319    actual = $H(actual); 
    295320    var expected_array = expected.toArray().sort(), actual_array = actual.toArray().sort(); 
     321    message = this.buildMessage(message || 'assertHashNotEqual', '<?> was the same as <?>', expected, actual); 
    296322    // from now we recursively zip & compare nested arrays 
    297     try { !(expected_array.length == actual_array.length &&  
    298       expected_array.zip(actual_array).all(function(pair) { 
    299         return pair.all(function(i){ return i && i.constructor == Array }) ? 
    300           pair[0].zip(pair[1]).all(arguments.callee) : pair[0] == pair[1]; 
    301       })) ? 
    302         this.pass() : this.fail(message + ': ' + Test.Unit.inspect(expected) +  
    303           ' was the same as ' + Test.Unit.inspect(actual)); } 
    304     catch(e) { this.error(e); } 
    305   }, 
    306   assertIdentical: function(expected, actual) {  
    307     var message = arguments[2] || "assertIdentical";  
    308     try { (expected === actual) ? this.pass() :  
    309       this.fail(message + ': expected "' + Test.Unit.inspect(expected) +   
    310         '", actual "' + Test.Unit.inspect(actual) + '"'); }  
    311     catch(e) { this.error(e); }  
    312   }, 
    313   assertNotIdentical: function(expected, actual) {  
    314     var message = arguments[2] || "assertNotIdentical";  
    315     try { !(expected === actual) ? this.pass() :  
    316       this.fail(message + ': expected "' + Test.Unit.inspect(expected) +   
    317         '", actual "' + Test.Unit.inspect(actual) + '"'); }  
    318     catch(e) { this.error(e); }  
    319   }, 
    320   assertNull: function(obj) { 
    321     var message = arguments[1] || 'assertNull' 
    322     try { (obj===null) ? this.pass() :  
    323      this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } 
    324     catch(e) { this.error(e); } 
    325   }, 
    326   assertNotNull: function(obj) { 
    327     var message = arguments[1] || 'assertNotNull' 
    328     try { (obj!==null) ? this.pass() :  
    329      this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } 
    330     catch(e) { this.error(e); } 
    331   }, 
    332   assertUndefined: function(obj) { 
    333     var message = arguments[1] || 'assertUndefined' 
    334     try { (typeof obj=="undefined") ? this.pass() : 
    335       this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } 
    336     catch(e) { this.error(e); } 
    337   }, 
    338   assertNotUndefined: function(obj) { 
    339     var message = arguments[1] || 'assertNotUndefined' 
    340     try { (typeof obj != "undefined") ? this.pass() : 
    341       this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } 
    342     catch(e) { this.error(e); } 
    343   }, 
    344   assertNullOrUndefined: function(obj){ 
    345     var message = arguments[1] || 'assertNullOrUndefined' 
    346     try { (obj==null) ? this.pass() : 
    347       this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } 
    348     catch(e) { this.error(e); } 
    349   }, 
    350   assertNotNullOrUndefined: function(obj){ 
    351     var message = arguments[1] || 'assertNotNullOrUndefined' 
    352     try { (obj!=null) ? this.pass() : 
    353       this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } 
    354     catch(e) { this.error(e); } 
    355   }, 
    356   assertMatch: function(expected, actual) { 
    357     var message = arguments[2] || 'assertMatch'; 
    358     var regex = new RegExp(expected); 
    359     try { regex.exec(actual) ? this.pass() : 
    360       this.fail(message + ' : regex: "' +  Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); } 
    361     catch(e) { this.error(e); } 
    362   }, 
    363   assertNoMatch: function(expected, actual) { 
    364     var message = arguments[2] || 'assertMatch'; 
    365     var regex = new RegExp(expected); 
    366     try { !regex.exec(actual) ? this.pass() : 
    367       this.fail(message + ' : regex: "' +  Test.Unit.inspect(expected) + ' matched: ' + Test.Unit.inspect(actual) + '"'); } 
    368     catch(e) { this.error(e); } 
    369   }, 
    370   assertHidden: function(element) { 
    371     var message = arguments[1] || 'assertHidden'; 
    372     this.assertEqual("none", element.style.display, message); 
    373   }, 
    374   assertInstanceOf: function(expected, actual) { 
    375     var message = arguments[2] || 'assertInstanceOf'; 
    376     try {  
    377       (actual instanceof expected) ? this.pass() :  
    378       this.fail(message + ": object was not an instance of the expected type"); } 
    379     catch(e) { this.error(e); }  
    380   }, 
    381   assertNotInstanceOf: function(expected, actual) { 
    382     var message = arguments[2] || 'assertNotInstanceOf'; 
    383     try {  
    384       !(actual instanceof expected) ? this.pass() :  
    385       this.fail(message + ": object was an instance of the not expected type"); } 
    386     catch(e) { this.error(e); }  
    387   }, 
    388   assertRespondsTo: function(method, obj) { 
    389     var message = arguments[2] || 'assertRespondsTo'; 
    390     try { 
    391       (obj[method] && typeof obj[method] == 'function') ? this.pass() :  
    392       this.fail(message + ": object doesn't respond to [" + method + "]"); } 
    393     catch(e) { this.error(e); } 
    394   }, 
    395   assertRaise: function(exceptionName, method) { 
    396     var message = arguments[2] || 'assertRaise'; 
     323    var block = function() { 
     324      return !(expected_array.length == actual_array.length &&  
     325        expected_array.zip(actual_array).all(function(pair) { 
     326          return pair.all(Object.isArray) ? 
     327            pair[0].zip(pair[1]).all(arguments.callee) : pair[0] == pair[1]; 
     328        })); 
     329    }; 
     330    this.assertBlock(message, block); 
     331  }, 
     332   
     333  assertIdentical: function(expected, actual, message) { 
     334    message = this.buildMessage(message || 'assertIdentical', 'expected <?>, actual: <?>', expected, actual); 
     335    this.assertBlock(message, function() { return expected === actual }); 
     336  }, 
     337   
     338  assertNotIdentical: function(expected, actual, message) {  
     339    message = this.buildMessage(message || 'assertNotIdentical', 'expected <?>, actual: <?>', expected, actual); 
     340    this.assertBlock(message, function() { return expected !== actual }); 
     341  }, 
     342   
     343  assertNull: function(obj, message) { 
     344    message = this.buildMessage(message || 'assertNull', 'got <?>', obj); 
     345    this.assertBlock(message, function() { return obj === null }); 
     346  }, 
     347   
     348  assertNotNull: function(obj, message) { 
     349    message = this.buildMessage(message || 'assertNotNull', 'got <?>', obj); 
     350    this.assertBlock(message, function() { return obj !== null }); 
     351  }, 
     352   
     353  assertUndefined: function(obj, message) { 
     354    message = this.buildMessage(message || 'assertUndefined', 'got <?>', obj); 
     355    this.assertBlock(message, function() { return typeof obj == "undefined" }); 
     356  }, 
     357   
     358  assertNotUndefined: function(obj, message) { 
     359    message = this.buildMessage(message || 'assertNotUndefined', 'got <?>', obj); 
     360    this.assertBlock(message, function() { return typeof obj != "undefined" }); 
     361  }, 
     362   
     363  assertNullOrUndefined: function(obj, message) { 
     364    message = this.buildMessage(message || 'assertNullOrUndefined', 'got <?>', obj); 
     365    this.assertBlock(message, function() { return obj == null }); 
     366  }, 
     367   
     368  assertNotNullOrUndefined: function(obj, message) { 
     369    message = this.buildMessage(message || 'assertNotNullOrUndefined', 'got <?>', obj); 
     370    this.assertBlock(message, function() { return obj != null }); 
     371  }, 
     372   
     373  assertMatch: function(expected, actual, message) { 
     374    message = this.buildMessage(message || 'assertMatch', 'regex <?> did not match <?>', expected, actual); 
     375    this.assertBlock(message, function() { return new RegExp(expected).exec(actual) }); 
     376  }, 
     377   
     378  assertNoMatch: function(expected, actual, message) { 
     379    message = this.buildMessage(message || 'assertNoMatch', 'regex <?> matched <?>', expected, actual); 
     380    this.assertBlock(message, function() { return !(new RegExp(expected).exec(actual)) }); 
     381  }, 
     382   
     383  assertHidden: function(element, message) { 
     384    message = this.buildMessage(message || 'assertHidden', '? is displayed.', element, actual); 
     385    this.assertBlock(message, function() { return element.style.display == 'none' }); 
     386  }, 
     387   
     388  assertInstanceOf: function(expected, actual, message) { 
     389    message = this.buildMessage(message || 'assertInstanceOf', '<?> was not an instance of the expected type', actual); 
     390    this.assertBlock(message, function() { return actual instanceof expected }); 
     391  }, 
     392   
     393  assertNotInstanceOf: function(expected, actual, message) { 
     394    message = this.buildMessage(message || 'assertNotInstanceOf', '<?> was an instance of the expected type', actual); 
     395    this.assertBlock(message, function() { return !(actual instanceof expected) }); 
     396  }, 
     397   
     398  assertRespondsTo: function(method, obj, message) { 
     399    message = this.buildMessage(message || 'assertRespondsTo', 'object doesn\'t respond to <?>', method); 
     400    this.assertBlock(message, function() { return (method in obj && typeof obj[method] == 'function') }); 
     401  }, 
     402 
     403  assertRaise: function(exceptionName, method, message) { 
     404    message = this.buildMessage(message || 'assertRaise', '<?> exception expected but none was raised', exceptionName); 
     405    var block = function() { 
     406      try {  
     407        method(); 
     408        return false; 
     409      } catch(e) { 
     410        if (e.name == exceptionName) return true; 
     411        else throw e; 
     412      } 
     413    }; 
     414    this.assertBlock(message, block); 
     415  }, 
     416   
     417  assertNothingRaised: function(method, message) { 
    397418    try {  
    398419      method(); 
    399       this.fail(message + ": exception expected but none was raised"); } 
    400     catch(e) { 
    401       (e.name==exceptionName) ? this.pass() : this.error(e);  
    402     } 
    403   }, 
    404   assertNothingRaised: function(method) { 
    405     var message = arguments[1] || 'assertNothingRaised'; 
    406     try { 
    407       method(); 
    408       this.pass(); 
    409     } catch (e) { 
    410       this.fail(message + ": " + e.toString()); 
    411     } 
    412   }, 
     420      this.assert(true, "Expected nothing to be thrown"); 
     421    } catch(e) { 
     422      message = this.buildMessage(message || 'assertNothingRaised', '<?> was thrown when nothing was expected.', e); 
     423      this.flunk(message); 
     424    } 
     425  }, 
     426   
    413427  _isVisible: function(element) { 
    414428    element = $(element); 
     
    418432      return false; 
    419433     
    420     return this._isVisible(element.parentNode); 
    421   }, 
    422   assertNotVisible: function(element) { 
    423     this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1])); 
    424   }, 
    425   assertVisible: function(element) { 
    426     this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1])); 
    427   }, 
     434    return arguments.callee.call(this, element.parentNode); 
     435  }, 
     436   
     437  assertVisible: function(element, message) { 
     438    message = this.buildMessage(message, '? was not visible.', element); 
     439    this.assertBlock(message, function() { return this._isVisible(element) }); 
     440  }, 
     441   
     442  assertNotVisible: function(element, message) { 
     443    message = this.buildMessage(message, '? was not hidden and didn\'t have a hidden parent either.', element); 
     444    this.assertBlock(message, function() { return !this._isVisible(element) }); 
     445  }, 
     446   
    428447  assertElementsMatch: function() { 
    429     var expressions = $A(arguments), elements = $A(expressions.shift()); 
     448    var pass = true, expressions = $A(arguments), elements = $A(expressions.shift()); 
    430449    if (elements.length != expressions.length) { 
    431       this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions (' + expressions.inspect() + ')'); 
    432       return false; 
     450      message = this.buildMessage('assertElementsMatch', 'size mismatch: ? elements, ? expressions (?).', elements.length, expressions.length, expressions); 
     451      this.flunk(message); 
     452      pass = false; 
    433453    } 
    434454    elements.zip(expressions).all(function(pair, index) { 
    435455      var element = $(pair.first()), expression = pair.last(); 
    436456      if (element.match(expression)) return true; 
    437       this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect()); 
    438     }.bind(this)) && this.pass(); 
    439   }, 
    440   assertElementMatches: function(element, expression) { 
     457      message = this.buildMessage('assertElementsMatch', 'In index <?>: expected <?> but got ?', index, expression, element); 
     458      this.flunk(message); 
     459      pass = false; 
     460    }.bind(this)) 
     461     
     462    if (pass) this.assert(true, "Expected all elements to match."); 
     463  }, 
     464   
     465  assertElementMatches: function(element, expression, message) { 
    441466    this.assertElementsMatch([element], expression); 
    442467  } 
  • spinoffs/prototype/trunk/test/unit/unit_tests.html

    r8572 r8643  
    6666      } 
    6767    }}, 
     68 
     69    testBuildMessage:  function() { 
     70      this.assertEqual("'foo' 'bar'", this.buildMessage('', '? ?', 'foo', 'bar')) 
     71    }, 
    6872     
    6973    testAssertEqual: function() { with(this) { 
     
    173177      Element.hide('testcss1'); 
    174178      assertNotVisible('testcss1_span'); // hidden by parent 
     179    }}, 
     180 
     181    testAssertElementsMatch: function() { with(this) { 
     182      assertElementsMatch($$('#tlist'), '#tlist');    
     183      assertElementMatches($('tlist'), '#tlist');    
    175184    }} 
    176185