<commit_before>var FeatureDotsView = require('../Feature/Dots');


/**@class An output in dots format for Runner events.
*/
var RunnerDots = new Class({
	Extends: require('../PromiseView'),

	features	: [],
	startTime	: null,
	readyTime	: null,

	events: {
		/** Informs the user that the emitting Runner is waiting for the browser.
		*/
		driverInit: function onDriverInit() {
			this.startTime = new Date();
			process.stdout.write(this.model + '\n');
		},

		/** Informs the user that the emitting Runner is ready to start.
		*/
		ready: function onReady() {
			this.readyTime = new Date();
			process.stdout.write('Browser ready\n');
		},

		feature: function onFeature(feature) {
			this.features.push(new FeatureDotsView(feature));
		}
	},

	/** Presents a summary of the test procedure to the user.
	*/
	showEnd: function showEnd() {
		var featuresCount = this.features.length,
			failuresCount = 0;

		process.stdout.write('\n');

		this.features.each(function(feature) {
			if (feature.model.promise.isRejected()) {
				failuresCount++;
				feature.showFailureDetails();
			}
		});

		var successCount = (featuresCount - failuresCount);

		process.stdout.write('\nFinished in '
							 + getDurationString(this.startTime, new Date())
							 + ': '
							 + pluralize(featuresCount, 'failure')
							 + ', '
							 + successCount + ' success' + (successCount > 1 ? 'es' : '')
							 + ', '
							 + pluralize(failuresCount, 'failure')
							 + '\n');
	}
});


/** Displays an amount, postfixed with an 's' if needed.
*
*@param {Number} count	The number used to pluralize the string.
*@returns {String} string	The string to pluralize based on the count.
*@private
*/
var pluralize = function pluralize(count, string) {
	return count + ' ' + string + (count == 1 ? '' : 's');
}


/** Computes the duration between two dates.
* The order of the two dates does not matter, a duration is always positive
*
*@param {Date} first	The first date.
*@param {Date} second	The other date.
*@returns {String} A human-readable duration string, of the form "h hours m minutes s seconds".
*@private
*/
var getDurationString = function getDurationString(first, second) {
	var result = '',
		durationSeconds = Math.abs(second - first) / 1000,
		durations = {
			hour	: Math.floor(durationSeconds / 3600),
			minute	: Math.floor(durationSeconds / 60) % 60,
			second	: Math.floor(durationSeconds) % 60
		};	// don't you remove this semicolon

	['hour', 'minute', 'second'].forEach(function(unit) {
		var value = durations[unit];
		if (value > 0)
			result += pluralize(value, unit) + ' ';
	});

	return result.trim();
}

module.exports = RunnerDots;	// CommonJS export
<commit_msg>Fix "failure" -> "feature" in Dots view<commit_after>var FeatureDotsView = require('../Feature/Dots');


/**@class An output in dots format for Runner events.
*/
var RunnerDots = new Class({
	Extends: require('../PromiseView'),

	features	: [],
	startTime	: null,
	readyTime	: null,

	events: {
		/** Informs the user that the emitting Runner is waiting for the browser.
		*/
		driverInit: function onDriverInit() {
			this.startTime = new Date();
			process.stdout.write(this.model + '\n');
		},

		/** Informs the user that the emitting Runner is ready to start.
		*/
		ready: function onReady() {
			this.readyTime = new Date();
			process.stdout.write('Browser ready\n');
		},

		feature: function onFeature(feature) {
			this.features.push(new FeatureDotsView(feature));
		}
	},

	/** Presents a summary of the test procedure to the user.
	*/
	showEnd: function showEnd() {
		var featuresCount = this.features.length,
			failuresCount = 0;

		process.stdout.write('\n');

		this.features.each(function(feature) {
			if (feature.model.promise.isRejected()) {
				failuresCount++;
				feature.showFailureDetails();
			}
		});

		var successCount = (featuresCount - failuresCount);

		process.stdout.write('\nFinished in '
							 + getDurationString(this.startTime, new Date())
							 + ': '
							 + pluralize(featuresCount, 'feature')
							 + ', '
							 + successCount + ' success' + (successCount > 1 ? 'es' : '')
							 + ', '
							 + pluralize(failuresCount, 'failure')
							 + '\n');
	}
});


/** Displays an amount, postfixed with an 's' if needed.
*
*@param {Number} count	The number used to pluralize the string.
*@returns {String} string	The string to pluralize based on the count.
*@private
*/
var pluralize = function pluralize(count, string) {
	return count + ' ' + string + (count == 1 ? '' : 's');
}


/** Computes the duration between two dates.
* The order of the two dates does not matter, a duration is always positive
*
*@param {Date} first	The first date.
*@param {Date} second	The other date.
*@returns {String} A human-readable duration string, of the form "h hours m minutes s seconds".
*@private
*/
var getDurationString = function getDurationString(first, second) {
	var result = '',
		durationSeconds = Math.abs(second - first) / 1000,
		durations = {
			hour	: Math.floor(durationSeconds / 3600),
			minute	: Math.floor(durationSeconds / 60) % 60,
			second	: Math.floor(durationSeconds) % 60
		};	// don't you remove this semicolon

	['hour', 'minute', 'second'].forEach(function(unit) {
		var value = durations[unit];
		if (value > 0)
			result += pluralize(value, unit) + ' ';
	});

	return result.trim();
}

module.exports = RunnerDots;	// CommonJS export

{'fraction_non_alphanumeric': 0.14317590182223874, 'fraction_numerical': 0.00669393826701376, 'mean_word_length': 3.394607843137255, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5289843', 'n_tokens_mistral': 1936, 'n_tokens_neox': 1645, 'n_words': 497}