123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- // Copyright 2008 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /**
- * @fileoverview Helper class to allow for expected unit test failures.
- *
- * @author robbyw@google.com (Robby Walker)
- */
- goog.setTestOnly('goog.testing.ExpectedFailures');
- goog.provide('goog.testing.ExpectedFailures');
- goog.require('goog.asserts');
- goog.require('goog.debug.DivConsole');
- goog.require('goog.dom');
- goog.require('goog.dom.TagName');
- goog.require('goog.events');
- goog.require('goog.events.EventType');
- goog.require('goog.log');
- goog.require('goog.style');
- goog.require('goog.testing.JsUnitException');
- goog.require('goog.testing.TestCase');
- goog.require('goog.testing.asserts');
- /**
- * Helper class for allowing some unit tests to fail, particularly designed to
- * mark tests that should be fixed on a given browser.
- *
- * <pre>
- * var expectedFailures = new goog.testing.ExpectedFailures();
- *
- * function tearDown() {
- * expectedFailures.handleTearDown();
- * }
- *
- * function testSomethingThatBreaksInWebKit() {
- * expectedFailures.expectFailureFor(goog.userAgent.WEBKIT);
- *
- * try {
- * ...
- * assert(somethingThatFailsInWebKit);
- * ...
- * } catch (e) {
- * expectedFailures.handleException(e);
- * }
- * }
- * </pre>
- *
- * @constructor
- * @final
- */
- goog.testing.ExpectedFailures = function() {
- goog.testing.ExpectedFailures.setUpConsole_();
- this.reset_();
- };
- /**
- * The lazily created debugging console.
- * @type {goog.debug.DivConsole?}
- * @private
- */
- goog.testing.ExpectedFailures.console_ = null;
- /**
- * Logger for the expected failures.
- * @type {goog.log.Logger}
- * @private
- */
- goog.testing.ExpectedFailures.prototype.logger_ =
- goog.log.getLogger('goog.testing.ExpectedFailures');
- /**
- * Whether or not we are expecting failure.
- * @type {boolean}
- * @private
- */
- goog.testing.ExpectedFailures.prototype.expectingFailure_;
- /**
- * The string to emit upon an expected failure.
- * @type {string}
- * @private
- */
- goog.testing.ExpectedFailures.prototype.failureMessage_;
- /**
- * An array of suppressed failures.
- * @type {Array<!Error>}
- * @private
- */
- goog.testing.ExpectedFailures.prototype.suppressedFailures_;
- /**
- * Sets up the debug console, if it isn't already set up.
- * @private
- */
- goog.testing.ExpectedFailures.setUpConsole_ = function() {
- if (!goog.testing.ExpectedFailures.console_) {
- var xButton = goog.dom.createDom(
- goog.dom.TagName.DIV, {
- 'style': 'position: absolute; border-left:1px solid #333;' +
- 'border-bottom:1px solid #333; right: 0; top: 0; width: 1em;' +
- 'height: 1em; cursor: pointer; background-color: #cde;' +
- 'text-align: center; color: black'
- },
- 'X');
- var div = goog.dom.createDom(
- goog.dom.TagName.DIV, {
- 'style': 'position: absolute; border: 1px solid #333; right: 10px;' +
- 'top : 10px; width: 400px; display: none'
- },
- xButton);
- document.body.appendChild(div);
- goog.events.listen(xButton, goog.events.EventType.CLICK, function() {
- goog.style.setElementShown(div, false);
- });
- goog.testing.ExpectedFailures.console_ = new goog.debug.DivConsole(div);
- goog.log.addHandler(
- goog.testing.ExpectedFailures.prototype.logger_,
- goog.bind(goog.style.setElementShown, null, div, true));
- goog.log.addHandler(
- goog.testing.ExpectedFailures.prototype.logger_,
- goog.bind(
- goog.testing.ExpectedFailures.console_.addLogRecord,
- goog.testing.ExpectedFailures.console_));
- }
- };
- /**
- * Register to expect failure for the given condition. Multiple calls to this
- * function act as a boolean OR. The first applicable message will be used.
- * @param {boolean} condition Whether to expect failure.
- * @param {string=} opt_message Descriptive message of this expected failure.
- */
- goog.testing.ExpectedFailures.prototype.expectFailureFor = function(
- condition, opt_message) {
- this.expectingFailure_ = this.expectingFailure_ || condition;
- if (condition) {
- this.failureMessage_ = this.failureMessage_ || opt_message || '';
- }
- };
- /**
- * Determines if the given exception was expected.
- * @param {Object} ex The exception to check.
- * @return {boolean} Whether the exception was expected.
- */
- goog.testing.ExpectedFailures.prototype.isExceptionExpected = function(ex) {
- return this.expectingFailure_ && ex instanceof goog.testing.JsUnitException;
- };
- /**
- * Handle an exception, suppressing it if it is a unit test failure that we
- * expected.
- * @param {Error} ex The exception to handle.
- */
- goog.testing.ExpectedFailures.prototype.handleException = function(ex) {
- if (this.isExceptionExpected(ex)) {
- goog.asserts.assertInstanceof(ex, goog.testing.JsUnitException);
- goog.log.info(
- this.logger_, 'Suppressing test failure in ' +
- goog.testing.TestCase.currentTestName + ':' +
- (this.failureMessage_ ? '\n(' + this.failureMessage_ + ')' : ''),
- ex);
- this.suppressedFailures_.push(ex);
- goog.testing.TestCase.invalidateAssertionException(ex);
- return;
- }
- // Rethrow the exception if we weren't expecting it or if it is a normal
- // exception.
- throw ex;
- };
- /**
- * Run the given function, catching any expected failures.
- * @param {Function} func The function to run.
- * @param {boolean=} opt_lenient Whether to ignore if the expected failures
- * didn't occur. In this case a warning will be logged in handleTearDown.
- */
- goog.testing.ExpectedFailures.prototype.run = function(func, opt_lenient) {
- try {
- func();
- } catch (ex) {
- this.handleException(ex);
- }
- if (!opt_lenient && this.expectingFailure_ &&
- !this.suppressedFailures_.length) {
- fail(this.getExpectationMessage_());
- }
- };
- /**
- * @return {string} A warning describing an expected failure that didn't occur.
- * @private
- */
- goog.testing.ExpectedFailures.prototype.getExpectationMessage_ = function() {
- return 'Expected a test failure in \'' +
- goog.testing.TestCase.currentTestName + '\' but the test passed.';
- };
- /**
- * Handle the tearDown phase of a test, alerting the user if an expected test
- * was not suppressed.
- */
- goog.testing.ExpectedFailures.prototype.handleTearDown = function() {
- if (this.expectingFailure_ && !this.suppressedFailures_.length) {
- goog.log.warning(this.logger_, this.getExpectationMessage_());
- }
- this.reset_();
- };
- /**
- * Reset internal state.
- * @private
- */
- goog.testing.ExpectedFailures.prototype.reset_ = function() {
- this.expectingFailure_ = false;
- this.failureMessage_ = '';
- this.suppressedFailures_ = [];
- };
|