var
	SIGN_SUCCESS = String.fromCharCode(0x2714).green,
	SIGN_FAILED = String.fromCharCode(0x2613).red
;

module.exports = function(grunt) {
	grunt.config('qunit', {
		all: {
			options: {
				timeout: 10000,
				console: true,
				urls: ['http://localhost:9000/.grunt/testrunner.html']
			}
		}
	});

	var
		report = '',
		cases = 0
	;

	function addReport(message) {
		report += '\n' + message;
	}

	grunt.event.on('qunit.spawn', function (url) {
		addReport('Running test: '.green + url);
	});

	grunt.event.on('qunit.moduleStart', function (name) {
		addReport(name.green);
	});

	grunt.event.on('qunit.testDone', function (name, failed, passed, total) {
		addReport(
			'    ' +
			(failed === 0 ? SIGN_SUCCESS : SIGN_FAILED) + ' ' +
			name + ' (' + total + ')'
		);
		cases++;
	});

	grunt.event.on('qunit.done', function(failed, passed, total, runtime) {
		grunt.log.writeln(report);
		report = '';

		grunt.log.writeln((
			' Ran '.gray +
			cases.toString().bold.blue +
			' in '.gray +
			runtime.toString().bold.blue +
			'ms '.bold.blue
		).bgWhite);
	});

	grunt.loadNpmTasks('grunt-contrib-qunit');
};

@@ -1058,24 +1058,443 @@
 ite);%0A%09%7D);%0A%0A
+%09grunt.event.on('qunit.fail.load', function(url) %7B%0A%09%09grunt.log.writeln();%0A%09%09grunt.log.writeln('Failed to load: ' + url.yellow);%0A%09%7D);%0A%0A%09grunt.event.on('qunit.error.onError', function(message, stackTrace) %7B%0A%09%09grunt.log.writeln();%0A%09%09grunt.log.errorlns(message);%0A%09%09(stackTrace %7C%7C %5B%5D).forEach(function(trace) %7B%0A%09%09%09grunt.log.error(%0A%09%09%09%09'%22' + trace.function +%0A%09%09%09%09'%22 in ' + trace.file +%0A%09%09%09%09':' + trace.line%0A%09%09%09);%0A%09%09%7D);%0A%09%7D);%0A%0A
 %09grunt.loadN

Update error reporting in qunit tests