diff --git a/test/WarnHandlersTest.js b/test/WarnHandlersTest.js new file mode 100644 index 0000000..0c62f83 --- /dev/null +++ b/test/WarnHandlersTest.js @@ -0,0 +1,174 @@ +/** + * Tests core warning handlers + * + * Copyright (C) 2011, 2013 Mike Gerwitz + * + * This file is part of GNU ease.js. + * + * ease.js is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +if ( typeof console === 'undefined' ) console = undefined; + +require( 'common' ).testCase( +{ + caseSetUp: function() + { + // XXX: this has global state + this.Sut = this.require( 'warn' ); + }, + + + setUp: function() + { + this.stubwarn = this.Sut.Warning( Error( 'gninraw' ) ); + }, + + + /** + * The log warning handler should log warnings to the console + */ + '`log\' warning handler logs messages to console': function() + { + var _self = this, + logged = false; + + // mock console + this.Sut.setConsole( { + warn: function( message ) + { + // should prefix with `Warning: ' + _self.assertEqual( + ( 'Warning: ' + _self.stubwarn.message ), + message + ); + + logged = true; + }, + } ); + + // call handler with the warning + this.Sut.handlers.log( this.stubwarn ); + + this.assertOk( logged, true, + "Message should be logged to console" + ); + + // restore console (TODO: will not be necessary once global state is + // removed) + this.Sut.setConsole( console ); + }, + + + /** + * Some environments may not have a console reference, or they may not + * have console.warn. In this case, we just want to make sure we don't + * throw an error when attempting to invoke undefined, or access a + * property of undefined. + */ + '`log\' warning handler handles missing console': function() + { + var Sut = this.Sut; + + // destroy it + Sut.setConsole( undefined ); + + // attempt to log + this.assertDoesNotThrow( function() + { + Sut.handlers.log( this.warnstub ); + }, Error ); + + // restore console + Sut.setConsole( console ); + }, + + + /** + * Furthermore, an environment may implement console.log(), but not + * console.warn(). By default, we use warn(), so let's ensure we can + * fall back to log() if warn() is unavailable. + */ + '`log\' warning handler falls back to log if warn is missing': + function() + { + var given = ''; + + this.Sut.setConsole( { + log: function( message ) + { + given = message; + } + } ); + + // attempt to log + this.Sut.handlers.log( this.stubwarn ); + + this.assertEqual( ( 'Warning: ' + this.stubwarn.message ), given, + "Should fall back to log() and log proper message" + ); + + // restore console + this.Sut.setConsole( console ); + }, + + + /** + * The throwError warning handler should throw the wrapped error as an + * exception + */ + '`throwError\' warning handler throws wrapped error': function() + { + try + { + this.Sut.handlers.throwError( this.stubwarn ); + } + catch ( e ) + { + this.assertStrictEqual( e, this.stubwarn.getError(), + "Wrapped exception should be thrown" + ); + + return; + } + + this.assertFail( "Wrapped exception should be thrown" ); + }, + + + /** + * The 'dismiss' error handler is a pretty basic concept: simply do + * nothing. We don't want to log, we don't want to throw anything, we + * just want to pretend nothing ever happened and move on our merry way. + * This is intended for use in production environments where such + * warnings are expected to already have been worked out and would only + * confuse/concern the user. + */ + '`dismiss\' warning handler does nothing': function() + { + var Sut = this.Sut; + + // destroy the console to ensure nothing is logged + Sut.setConsole( undefined ); + + // no errors should occur because it should not do anything. + this.assertDoesNotThrow( function() + { + Sut.handlers.dismiss( this.warnstub ); + }, Error ); + + // restore console + Sut.setConsole( console ); + }, +} ); diff --git a/test/WarnTest.js b/test/WarnTest.js new file mode 100644 index 0000000..7a8f2b4 --- /dev/null +++ b/test/WarnTest.js @@ -0,0 +1,79 @@ +/** + * Tests warning system implementation + * + * Copyright (C) 2011, 2013 Mike Gerwitz + * + * This file is part of GNU ease.js. + * + * ease.js is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +if ( typeof console === 'undefined' ) console = undefined; + +require( 'common' ).testCase( +{ + setUp: function() + { + // XXX: this uses global state; remove that requirement. + this.Sut = this.require( 'warn' ); + }, + + + /** + * The default warning handler should be the 'log' handler; this is a + * friendly compromise that will allow the developer to be warned of + * potential issues without affecting program execution. + */ + 'Default warning handler is `log\'': function() + { + var called = false; + + // stub it + this.Sut.setConsole( { + warn: function() + { + called = true; + }, + } ); + + this.Sut.handle( this.Sut.Warning( Error( 'foo' ) ) ); + this.assertOk( called ); + + // restore console (TODO: this will not be necessary once reliance + // on global state is removed) + this.Sut.setConsole( console ); + }, + + + /** + * The warning handler can be altered at runtime; ensure we can set it + * and call it appropriately. We do not need to use one of the + * pre-defined handlers. + */ + 'Can set and call arbitrary warning handler': function() + { + var given, + warning = this.Sut.Warning( Error( 'foo' ) ); + + // set a stub warning handler + this.Sut.setHandler( function( warn ) + { + given = warn; + } ); + + // trigger the handler + this.Sut.handle( warning ); + this.assertDeepEqual( given, warning ); + }, +} ); diff --git a/test/WarningTest.js b/test/WarningTest.js new file mode 100644 index 0000000..65d6552 --- /dev/null +++ b/test/WarningTest.js @@ -0,0 +1,115 @@ +/** + * Tests the Warning prototype + * + * Copyright (C) 2011, 2013 Mike Gerwitz + * + * This file is part of GNU ease.js. + * + * ease.js is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +require( 'common' ).testCase( +{ + caseSetUp: function() + { + this.Sut = this.require( 'warn' ).Warning; + }, + + + /** + * Warning should be a subtype of Error in an effort to ensure + * consistency and proper handling where Error is expected + */ + 'Warning has Error prototype': function() + { + this.assertOk( new this.Sut( Error() ) instanceof Error ); + }, + + + /** + * Make clear that we're working with a warning + */ + 'Warning should alter Error name': function() + { + this.assertEqual( this.Sut( Error() ).name, 'Warning' ); + }, + + + /** + * Just as with the other Error classes, as well as all ease.js classes, + * the 'new' operator should be optional when instantiating the class + */ + '`new\' operator is not necessary to instantiate Warning': function() + { + this.assertOk( this.Sut( Error( '' ) ) instanceof this.Sut ); + }, + + + /** + * Warning message should be taken from the exception passed to it + */ + 'Warning message is set from wrapped exception': function() + { + var err = Error( 'oshit' ); + + // bug in FF (tested with 8.0) where, without accessing the message + // property in this test before passing it to Warning, err.message + // === "" within the Warning ctor. (Assignment is to silence Closure + // compiler warning.) + var _ = err.message; + + var warning = this.Sut( err ); + + this.assertEqual( warning.message, err.message ); + + // this little trick prevents the compiler from optimizing away the + // assignment, which would break the test in certain versions of FF. + return _; + }, + + + /** + * The whole point of Warning is to wrap an exception; so, ensure that + * one is wrapped. + */ + 'Throws exception if no exception is wrapped': function() + { + var Sut = this.Sut; + + this.assertThrows( function() + { + Sut( /* nothing provided to wrap */ ); + }, TypeError ); + + this.assertThrows( function() + { + Sut( 'not an exception' ); + }, TypeError ); + }, + + + /** + * We must provide access to the wrapped exception so that it can be + * properly handled; warning is only intended to provide additional + * information so that ease.js may handle it differently than other + * Error instances. + */ + 'Can retrieve wrapped exception': function() + { + var err = Error( 'foo' ), + warning = this.Sut( err ); + + this.assertStrictEqual( err, warning.getError() ); + }, +} ); diff --git a/test/test-warn-exception.js b/test/test-warn-exception.js deleted file mode 100644 index 5535d75..0000000 --- a/test/test-warn-exception.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Tests the Warning prototype - * - * Copyright (C) 2011, 2013 Mike Gerwitz - * - * This file is part of GNU ease.js. - * - * ease.js is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -var common = require( './common' ), - assert = require( 'assert' ), - Warning = common.require( 'warn' ).Warning -; - - -/** - * Warning should be a subtype of Error - */ -( function testWarningIsAvailableAndHasErrorPrototype() -{ - assert.ok( ( Warning( Error() ) instanceof Error ), - "Warning should be an instance of Error" - ); -} )(); - - -/** - * Make clear that we're working with a warning - */ -( function testWarningShouldAlterErrorName() -{ - assert.equal( Warning( Error() ).name, 'Warning', - "Warning name should be properly set" - ); -} )(); - - -/** - * Just as with the other Error classes, as well as all ease.js classes, the - * 'new' keyword should be optional when instantiating the class - */ -( function testNewKeywordIsNotRequiredForInstantiation() -{ - assert.ok( Warning( Error( '' ) ) instanceof Warning, - "'new' keyword should not be necessary to instantiate Warning" - ); -} )(); - - -/** - * Warning message should be taken from the exception passed to it - */ -( function testCanWarningMessageIsSetFromWrappedException() -{ - var err = Error( 'oshit' ); - - // bug in FF (tested with 8.0) where, without accessing the message property - // in this test before passing it to Warning, err.message === "" within the - // Warning ctor. (Assignment is to silence Closure compiler warning.) - var _ = err.message; - - var warning = Warning( err ); - - assert.equal( warning.message, err.message, - "Warning message should be taken from wrapped exception" - ); - - // this little trick prevents the compiler from optimizing away the - // assignment, which would break the test in certain versions of FF. - return _; -} )(); - - -/** - * The whole point of Warning is to wrap an exception. So, ensure that one is - * wrapped. - */ -( function testThrowsExceptionIfNoExceptionIsWrapped() -{ - assert['throws']( function() - { - Warning( /* nothing provided to wrap */ ); - }, TypeError, "Exception should be thrown if no exception is provided" ); - - assert['throws']( function() - { - Warning( 'not an exception' ); - }, TypeError, "Exception should be thrown if given value is not an Error" ); -} )(); - - -/** - * We must provide access to the wrapped exception so that it can be properly - * handled. Warning is only intended to provide additional information so that - * ease.js may handle it differently than other Error instances. - */ -( function testCanRetrieveWrappedException() -{ - var err = Error( 'foo' ), - warning = Warning( err ); - - assert.deepEqual( err, warning.getError(), - "Can retrieve wrapped exception" - ); -} )(); - diff --git a/test/test-warn-handlers.js b/test/test-warn-handlers.js deleted file mode 100644 index 0eda73a..0000000 --- a/test/test-warn-handlers.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Tests core warning handlers - * - * Copyright (C) 2011, 2013 Mike Gerwitz - * - * This file is part of GNU ease.js. - * - * ease.js is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -var common = require( './common' ), - assert = require( 'assert' ), - warn = common.require( 'warn' ), - Warning = warn.Warning, - - warning = Warning( Error( 'gninraw' ) ) -; - -if ( typeof console === 'undefined' ) console = undefined; - - -/** - * The log warning handler should log warnings to the console - */ -( function testLogWarningHandlerLogsMessageToConsole() -{ - var logged = false; - - // mock console - warn.setConsole( { - warn: function( message ) - { - assert.equal( ( 'Warning: ' + warning.message ), message, - "Should log proper message to console, prefixed with 'Warning'" - ); - - logged = true; - }, - } ); - - // call handler with the warning - warn.handlers.log( warning ); - - assert.equal( logged, true, - "Message should be logged to console" - ); - - // restore console - warn.setConsole( console ); -} )(); - - -/** - * Some environments may not have a console reference, or they may not have - * console.warn. In this case, we just want to make sure we don't throw an error - * when attempting to invoke undefined, or access a property of undefined. - */ -( function testLogWarningHandlerHandlesMissingConsole() -{ - // destroy it - warn.setConsole( undefined ); - - // attempt to log - warn.handlers.log( warning ); - - // restore console - warn.setConsole( console ); -} )(); - - -/** - * Furthermore, an environment may implement console.log(), but not - * console.warn(). By default, we use warn(), so let's ensure we can fall back - * to log() if warn() is unavailable. - */ -( function testLogWarningHandlerWillFallBackToLogMethodIfWarnIsMissing() -{ - var given = ''; - - warn.setConsole( { - log: function( message ) - { - given = message; - } - } ); - - // attempt to log - warn.handlers.log( warning ); - - assert.equal( ( 'Warning: ' + warning.message ), given, - "Should fall back to log() and log proper message" - ); - - // restore console - warn.setConsole( console ); -} )(); - - -/** - * The throwError warning handler should throw the wrapped error as an exception - */ -( function testThrowErrorWarningHandlerThrowsWrappedError() -{ - try - { - warn.handlers.throwError( warning ); - } - catch ( e ) - { - assert.deepEqual( e, warning.getError(), - "Wrapped exception should be thrown" - ); - - return; - } - - assert.fail( "Wrapped exception should be thrown" ); -} )(); - - -/** - * The 'dismiss' error handler is a pretty basic concept. Simply do nothing. We - * don't want to log, we don't want to throw anything, we just want to pretend - * nothing ever happened and move on our merry way. This is intended for use in - * production environments where providing warnings may provide too much insight - * into the software. - */ -( function testDismissWarningHandlerShouldDoNothing() -{ - // destroy the console to ensure nothing is logged - warn.setConsole( undefined ); - - // don't catch anything, to ensure no errors occur and that no exceptions - // are thrown - warn.handlers.dismiss( warning ); - - // restore console - warn.setConsole( console ); -} )(); - diff --git a/test/test-warn-impl.js b/test/test-warn-impl.js deleted file mode 100644 index 0e5bf43..0000000 --- a/test/test-warn-impl.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Tests warning system implementation - * - * Copyright (C) 2011, 2013 Mike Gerwitz - * - * This file is part of GNU ease.js. - * - * ease.js is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -var common = require( './common' ), - assert = require( 'assert' ), - warn = common.require( 'warn' ) -; - -if ( typeof console === 'undefined' ) console = undefined; - - -/** - * The default warning handler should be the 'log' handler. This is a friendly - * compromise that will allow the developer to be warned of potential issues - * without affecting program execution. - */ -( function testDefaultHandlerIsLogger() -{ - var called = false; - - // stub it - warn.setConsole( { - warn: function() - { - called = true; - }, - } ); - - warn.handle( warn.Warning( Error( 'foo' ) ) ); - - assert.ok( called, - "Default handler will log to console" - ); - - // restore console - warn.setConsole( console ); -} )(); - - -/** - * The warning handler can be altered at runtime. Ensure we can set it and call - * it appropriately. We do not need to use one of the pre-defined handlers. - */ -( function testCanSetAndCallWarningHandler() -{ - var given, - warning = warn.Warning( Error( 'foo' ) ); - - // set a stub warning handler - warn.setHandler( function( warn ) - { - given = warn; - } ); - - // trigger the handler - warn.handle( warning ); - - assert.deepEqual( given, warning, - "Set warning handler should be called with given Warning" - ); -} )(); -