I've got this javascript function which was written a bit ad-hoc and I'm not really sure how to go about refactoring and improving it.It's basically an implementation of draft Unit-Testing/1.1 specification.// Runs the object as a test. The async paramater is an optional function// To be passed in if the test is to be run async.// notRoot is an internal paramatervar run = function(object, async, notRoot) {    // if its the root call then cache the async func for us in _pushTests    if (!notRoot) {        func = async;    }    // tests to run    var tests = [];    // Assert constructor to be used is either on the object or from assert    var Assert = object.Assert || assert.Assert;    var failures = 0;    // Push the tests to the tests array    _pushTests(object, tests);    var len = tests.length;    // function that runs the test    var testRunner;    // If async Do I have to document it? It's full of the hacks.    if (async) {        // results object stores the calls to pass/fail/error        var results = {};        results.passes = [];        results.fails = [];        results.errors = [];        // tests passed in the test object        var testsPassed = 0;        testRunner = function(val, key) {            // Local assert object            var _assert = new Assert;            // Forward the mute property to the assert            if (object.mute === true) {                _assert.mute = true;                }            // cache pass, fail & error            var _pass = _assert.pass;            var _fail = _assert.fail;            var _error = _assert.error;            // Wrap pass. Push the pass massge to the results object            _assert.pass = function(message) {                _pass.apply(_assert, arguments);                results.passes.push(message);                // If an assert passed after done then throw an error in                 // assert.error                if (doneCalled) {                    _assert.error(new Error(                        assertion passed after done was called +                         for test :  + key +  and message was :  +                        message                    ));                }            }            // Wrap fail. Push the fail message to the results object            _assert.fail = function(message) {                _fail.apply(_assert, arguments);                results.failures.push(message);                // Throw an error if assertion failed after done has been                // called                if (doneCalled) {                    _assert.error(new Error(                        assertion failed after done was called +                         for test :  + key +  and message was :  +                        message                    ));                }            }            // Wrap error. Log calls to error            _assert.error = function(error) {                _error.apply(_assert, arguments);                results.errors.push(error);            }            // Done has not been called            var doneCalled = false;            var done = function() {                // If its not been called then set it to be called                if (!doneCalled) {                    doneCalled = true;                    // Increment the number of tests that have passed                    // If we have passed all then call the async function                    // with the results                    if (++testsPassed === len) {                        async(results, object.name);                        };                } else {                    // Done has already been called thrown an error                    _assert.error(new Error(                        done already called for test :  + key                    ));                }            };            // Try running the test function.            try {                val(_assert, done);                } catch(e) {                // If a failure occurs log it when its an AssertionError                if (e instanceof assert.AssertionError) {                    console.log(failed :  + e.message);                } else {                    // and throw if its another error                    _assert.error(e);                }                failures++;            }        };    } else {        // the test runner takes the test function as a paramater        testRunner = function(val) {            // create a local assert            var _assert = new Assert;            // If we want to mute it then pass mute to the assert            if (object.mute === true) {                _assert.mute = true;                }            // Try the test            try {                val(_assert);            } catch(e) {                // If it throws an assertion error then log it                if (e instanceof assert.AssertionError) {                    console.log(failed :  + e.message);                } else {                    // Other error thrown so pass it to assert.error                    _assert.error(e);                    }                failures++;            }        };    }    // For each test run it.    _.each(tests, testRunner);    // If the object had a name and was not async then print a message    // saying we've finishe    if (object.name && !async) {        var string = Completed  + len +              tests. Finished :  + object.name +             with  + failures +  tests failing;        console.log(string);            }    // Return the count of failures (Kind of useless for async).    return failures;};For more information the full file can be found here. It also relies on assert object which is documented here.There are some (limited) unit tests and they can be run in the browser here.Please tell me if more information is needed. I was going to write some proper high level documentation on how to use it because the commonJS spec is a bit vague. I'll edit when that's done.
Unit-testing function
javascript;unit testing
I would start out by cleaning the code along these lines:Refactor variable names and functions so as to limit the use comments (code doesn't' lie, comments sometimes do)Use better descriptive names (fx key/val relates to test's in your code but has me thinking of object literals).Split the function in smaller functions so they are easier to test and comprehend by them self:i.e:testRunner = (async) ? asyncTestRunner : functionTestRunner;followed by the the functions them self // function asyncTestRunner(descriptiveParameterNames) {  :}// function functionTestRunner(anotherDescriptiveParameter) {  :}Try to build up your code as a series of progressions, each building logically on the former without needing to many commentary's along the way, in a similar manner as a well written textbook.