Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added anode wrapper for assert Node.js module; Improved logging in de…

…bug mode
  • Loading branch information...
commit 9c980c5779b2c638f90317fe8a7567ee9fc316ff 1 parent a867665
@tristanls authored
View
24 examples/assert.example.coffee
@@ -0,0 +1,24 @@
+#
+# assert.example.coffee : an example of built-in anode configuration assert
+#
+# (C) 2011 Tristan Slominski
+#
+anode = require '../lib/anode'
+
+cnf = new anode.Configuration debug : true
+
+thrower = ->
+ throw new Error( 'error' )
+
+ack = cnf.actor 'ack actor', anode.beh(
+
+ 'assert, #throws' : ->
+
+ @send( '#throws assertion passed' ).to cnf.console.log
+
+ # now assert something that will break
+ @send( @, @_, '#ok', false ).to cnf.assert
+
+)()
+
+cnf.send( ack, null, '#throws', thrower ).to cnf.assert
View
2  lib/anode/actor.js
@@ -111,6 +111,8 @@ var Actor = exports.Actor = function ( configuration ) {
to : function ( actors ) {
Array.prototype.unshift.call( _args, actors );
+ // add 'from' actor for debugging
+ Array.prototype.push.call( _args, self );
__configuration.__send.apply( __configuration, _args );
} // to
View
86 lib/anode/configuration.js
@@ -8,6 +8,10 @@
var Actor = require( './actor' ).Actor,
AsyncEventEmitter = require( 'async-events' ).AsyncEventEmitter,
util = require( 'util' );
+
+require( 'coffee-script' ); // enable requiring coffee modules directly
+
+var assert_beh = require( '../../src/assert' ).assert_beh;
//
// ### function Configuration ()
@@ -91,6 +95,9 @@ var Configuration = exports.Configuration = function ( options ) {
// get rid of the 'actors' param from the arguments
args.shift();
+ // get rid of the 'from' actor from the arguments
+ var fromActor = args.pop();
+
if ( actors instanceof Array ) {
// send message to each actor
@@ -101,7 +108,7 @@ var Configuration = exports.Configuration = function ( options ) {
// copy arguments for this message
var _args = Array.prototype.slice.call( args, 0 );
- if ( self.__debug ) _logMessage( actor, _args );
+ if ( self.__debug ) _logMessage( fromActor, actor, _args );
// add address of the actor
_args.unshift( actor.__uid + '::message' );
@@ -113,7 +120,7 @@ var Configuration = exports.Configuration = function ( options ) {
} // if actors is Array
else {
- if ( self.__debug ) _logMessage( actors, args );
+ if ( self.__debug ) _logMessage( fromActor, actors, args );
// add address of the actor
args.unshift( actors.__uid + '::message' );
@@ -161,50 +168,55 @@ var Configuration = exports.Configuration = function ( options ) {
//
self.console = {};
- var log = self.actor( function () {
+ var log = self.actor( 'console.log', function () {
console.log.apply( this, Array.prototype.slice.call( arguments ) );
});
self.console.log = log;
self.console.info = log;
- var warn = self.actor( function () {
+ var warn = self.actor( 'console.warn', function () {
console.warn.apply( this, Array.prototype.slice.call( arguments ) );
});
self.console.warn = warn;
self.console.error = warn;
- var dir = self.actor( function () {
+ var dir = self.actor( 'console.dir', function () {
console.dir.apply( this, Array.prototype.slice.call( arguments ) );
});
self.console.dir = dir;
- var time = self.actor( function () {
+ var time = self.actor( 'console.time', function () {
console.time.apply( this, Array.prototype.slice.call( arguments ) );
});
self.console.time = time;
- var timeEnd = self.actor( function () {
+ var timeEnd = self.actor( 'console.timeEnd', function () {
console.timeEnd.apply( this, Array.prototype.slice.call( arguments ) );
});
self.console.timeEnd = timeEnd;
- var trace = self.actor( function () {
+ var trace = self.actor( 'console.trace', function () {
console.trace.apply( this, Array.prototype.slice.call( arguments ) );
});
self.console.trace = trace;
- var assert = self.actor( function () {
+ var assert = self.actor( 'console.assert', function () {
console.assert.apply( this, Array.prototype.slice.call( arguments ) );
});
self.console.assert = assert;
+ //
+ // actor wrapper around node assert
+ //
+ self.assert = self.actor( 'assert', assert_beh() );
+
}; // Configuration
//
@@ -221,6 +233,8 @@ Configuration.prototype.send = function () {
to : function ( actors ) {
Array.prototype.unshift.call( _args, actors );
+ // add 'from' actor for debugging
+ Array.prototype.push.call( _args, self );
self.__send.apply( self, _args );
} // to
@@ -229,12 +243,40 @@ Configuration.prototype.send = function () {
}; // send
-var _logMessage = function ( to, message ) {
+var _actorToString = function ( actor ) {
+
+ var str = '[';
+
+ if ( actor instanceof Actor ) {
+
+ if ( actor.__name )
+ str += actor.__name + '::';
+
+ str += actor.__uid + ']';
+
+ } // if actor instanceof Actor
+ else if ( actor instanceof Configuration ) {
+
+ str += 'configuration]';
+
+ } // else if actor instanceof Configuration
+ else {
+
+ str += '?]';
+
+ } // else
+
+ return str;
+
+}; // _actorToString
+
+var _logMessage = function ( from, to, message ) {
+
+ var __from = 'FROM ' + _actorToString( from );
+
+ var __to = 'TO ' + _actorToString( to );
- var header = 'message to [';
- if ( to.__name )
- header += to.__name + '::';
- header += to.__uid + '] :'
+ var __send = 'SEND';
var msg = [];
@@ -255,7 +297,19 @@ var _logMessage = function ( to, message ) {
} // if portion instanceof Actor
else {
- partialMsg = portion ? portion.toString() : '';
+ if ( typeof portion === 'undefined' ) {
+
+ partialMsg = 'undefined';
+
+ } else if ( portion === null ) {
+
+ partialMsg = 'null'
+
+ } else {
+
+ partialMsg = portion.toString();
+
+ }
} // else
@@ -263,7 +317,7 @@ var _logMessage = function ( to, message ) {
} // for i in message.length
- console.log( header, msg );
+ console.log( __from, __to, __send, msg );
}; // _logMessage
View
157 src/assert.coffee
@@ -0,0 +1,157 @@
+#
+# assert.coffee : anode wrapper around Node.js 'assert' module
+#
+# (C) 2011 Tristan Slominski
+#
+anode = require '../lib/anode'
+nodeassert = require 'assert'
+nodeutil = require 'util'
+
+#
+# helper function to make the assertion failures more meaningful by displaying which
+# actor generated the failed assertion
+#
+processAssertionError = ( @cust, @msg, error ) ->
+
+ text = 'AssertionError'
+
+ if @cust
+ __name = if @cust.__name then @cust.__name + '::' else ''
+ text += ' in: [' + __name + @cust.__uid + ']'
+
+ if @msg
+ msgText = []
+
+ for element in @msg
+ do ( element ) ->
+
+ if element instanceof anode.Actor
+ __label = '['
+ if element.__name
+ __label += element.__name + '::'
+ __label += element.__uid + ']'
+
+ msgText.push __label
+
+ else
+
+ msgText.push element
+
+ text += ' on: ' + nodeutil.inspect msgText
+
+ console.error text
+
+ throw error
+
+assert_beh = anode.beh
+
+ 'cust, msg, #deepEqual, actual, expected, [message]' : ->
+
+ try
+ nodeassert.deepEqual @actual, @expected, @message
+ if @cust # ack requested
+ @send( @, '#deepEqual' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #doesNotThrow, block, [error], [message]' : ->
+
+ try
+ nodeassert.doesNotThrow @block, @error, @message
+ if @cust # ack requested
+ @send( @, '#doesNotThrow' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #equal, actual, expected, [message]' : ->
+
+ try
+ nodeassert.equal @actual, @expected, @message
+ if @cust # ack requested
+ @send( @, '#equal' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #fail, actual, expected, message, operator' : ->
+
+ try
+ nodeassert.fail @actual, @expected, @message, @operator
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #ifError, value' : ->
+
+ try
+ nodeassert.ifError @value
+ if @cust # ack requested
+ @send( @, '#ifError' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #notDeepEqual, actual, expected, [message]' : ->
+
+ try
+ nodeassert.notDeepEqual @actual, @expected, @message
+ if @cust # ack requested
+ @send( @, '#notDeepEqual' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #notStrictEqual, actual, expected, [message]' : ->
+
+ try
+ nodeassert.notStrictEqual @actual, @expected, @message
+ if @cust # ack requested
+ @send( @, '#notStrictEqual' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #notEqual, actual, expected, [message]' : ->
+
+ try
+ nodeassert.notEqual @actual, @expected, @message
+ if @cust # ack requested
+ @send( @, '#notEqual' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #ok, value, [message]' : ->
+
+ try
+ nodeassert.ok @value, @message
+ if @cust # ack requested
+ @send( @, '#ok' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #strictEqual, actual, expected, [message]' : ->
+
+ try
+ nodeassert.strictEqual @actual, @expected, @message
+ if @cust # ack requested
+ @send( @, '#strictEqual' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, #throws, block, [error], [message]' : ->
+
+ try
+ nodeassert.throws @block, @error, @message
+ if @cust # ack requested
+ @send( @, '#throws' ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+ 'cust, msg, value, message' : ->
+
+ try
+ nodeassert @value, @message
+ if @cust # ack requested
+ @send( @ ).to @cust
+ catch error
+ processAssertionError @cust, @msg, error
+
+#
+# export assert behavior
+#
+exports.assert_beh = assert_beh
Please sign in to comment.
Something went wrong with that request. Please try again.