var assert = require('assert');

var Pending = require('./exceptions').Pending;

exports.Example = Example;

function Example(description, options, block) {
    this.description = description;
    this.options = options;
    if (block)
        this.block = block;
    else
        this.is_pending = true;
}

Example.prototype.assert = assert;

Example.prototype.pending = function(reason) {
    throw new Pending(reason);
}

Example.prototype.exec = function(callback) {
    var data = {result: 'pending'};
    if (this.is_pending) {
        callback(null, data);
        return;
    }
    this.done = function(err) {
        if (err) {
            this._handle_error(err, data, callback);
            return;
        }
        data.result = 'passed';
        callback(null, data);
    }.bind(this);
    catcher = function(err) {
        this._handle_error(err, data, clear_catcher);
    }.bind(this);
    process.once('uncaughtException', catcher);
    clear_catcher = function() {
        process.removeListener('uncaughtException', catcher);
        callback.apply(null, arguments);
    };
    try {
        var retval = this.block.call(this, this);
        if (retval !== undefined) {
            data.result = 'passed';
            callback(null, data);
        }
    } catch (ex) {
        this._handle_error(ex, data, callback);
    }
}

Example.prototype._handle_error = function(ex, data, callback) {
    if (ex instanceof Pending) {
        data.result = 'pending';
    } else if (ex instanceof assert.AssertionError) {
        data.result = 'failed';
    } else {
        data.result = 'errored';
    }
    console.error(ex.toString());
    data.error = ex;
    callback(null, data);
}

@@ -500,16 +500,48 @@
 ding'%7D;%0A
+    // No block, bail out early%0A
     if (
@@ -619,221 +619,69 @@
     
-this.done = function(err) %7B%0A        if (err) %7B%0A            this._handle_error(err, data, callback);%0A            return;%0A        %7D%0A        data.result = 'passed';%0A        callback(null, data);%0A    %7D.bind(this);%0A   
+// Use the process hook to capture any uncaught error%0A    var
  cat
@@ -827,16 +827,87 @@
 r);%0A    
+// Make sure we don't leave the hook around after the test run%0A    var 
 clear_ca
@@ -1037,16 +1037,287 @@
 %0A    %7D;%0A
+    // Setup the test.done() callback for the block%0A    this.done = function(err) %7B%0A        if (err) %7B%0A            this._handle_error(err, data, callback);%0A            return;%0A        %7D%0A        data.result = 'passed';%0A        clear_catcher(null, data);%0A    %7D.bind(this);%0A
     try 
@@ -1445,39 +1445,44 @@
 ';%0A            c
-allback
+lear_catcher
 (null, data);%0A  
@@ -1542,31 +1542,36 @@
 (ex, data, c
-allback
+lear_catcher
 );%0A    %7D%0A%7D%0A%0A

Tidy up the async spec handling a tad