API Docs for: 0.9.3
Show:

File: lib/abstractTask.js

// Copyright 2014, Yahoo! Inc.
// Copyrights licensed under the Mit License. See the accompanying LICENSE file for terms.

var Base = require('preceptor-core').Base;
var utils = require('preceptor-core').utils;
var logger = require('log4js').getLogger(__filename);
var Promise = require('promise');
var _ = require('underscore');
var uuid = require('uuid');

var defaultTask = require('./defaults/defaultTask');

/**
 * @class AbstractTask
 * @extends Base
 *
 * @property {ReportManager} _reportManager
 * @property {object} _plugins
 * @property {object} _options
 * @property {object} _config
 * @property {Collector} _coverageCollector
 */
var AbstractTask = Base.extend(

	/**
	 * Abstract task constructor
	 *
	 * @param {object} config
	 * @param {Collector} coverageCollector
	 * @param {ReportManager} reportManager
	 * @param {object} plugins
	 * @param {object} plugins.taskDecorator
	 * @param {object} plugins.clientDecorator
	 * @param {object} plugins.task
	 * @param {object} options
	 * @constructor
	 */
	function (config, coverageCollector, reportManager, plugins, options) {
		this.__super();

		this._config = config;
		this._coverageCollector = coverageCollector;
		this._reportManager = reportManager;
		this._plugins = plugins;
		this._options = utils.deepExtend({}, [defaultTask, plugins.sharedOptions || {}, options || {}]);

		this.initialize();
	},

	{
		/**
		 * Initializes the instance
		 *
		 * @method initialize
		 */
		initialize: function () {

			// Make sure the configuration has the correct structure
			this.validate();

			// Augment options with outside data
			this.augment();
		},


		/**
		 * Validates the given data
		 *
		 * @method validate
		 */
		validate: function () {
			if (!_.isObject(this.getOptions())) {
				throw new Error('The options parameter is not an object.');
			}
			if (!_.isObject(this.getConfiguration())) {
				throw new Error('The "configuration" parameter is not an object.');
			}
			if (!_.isObject(this.getDecorators())) {
				throw new Error('The "decorators" parameter is not an object.');
			}
			if (!_.isString(this.getType())) {
				throw new Error('The "type" parameter is not a string.');
			}
			if (!_.isString(this.getTaskId())) {
				throw new Error('The "taskId" parameter is not a string.');
			}
			if (!_.isString(this.getName())) {
				throw new Error('The "name" parameter is not a string.');
			}
			if (!_.isString(this.getTitle())) {
				throw new Error('The "title" parameter is not a string.');
			}
			if (!_.isBoolean(this.isSuite())) {
				throw new Error('The "suite" parameter is not a boolean.');
			}
			if (!_.isBoolean(this.isActive())) {
				throw new Error('The "active" parameter is not a boolean.');
			}
			if (!_.isBoolean(this.isVerbose())) {
				throw new Error('The "verbose" parameter is not a boolean.');
			}
			if (!_.isBoolean(this.shouldReport())) {
				throw new Error('The "report" parameter is not a boolean.');
			}
			if (!_.isBoolean(this.shouldEchoStdOut())) {
				throw new Error('The "echoStdOut" parameter is not a boolean.');
			}
			if (!_.isBoolean(this.shouldEchoStdErr())) {
				throw new Error('The "echoStdErr" parameter is not a boolean.');
			}
		},

		/**
		 * Augments the data with default values
		 *
		 * @method augment
		 */
		augment: function () {
			// Nothing yet
		},


		/**
		 * Gets the options
		 *
		 * @method getOptions
		 * @return {object}
		 */
		getOptions: function () {
			return this._options;
		},

		/**
		 * Gets the client configuration
		 *
		 * @method getConfiguration
		 * @return {object}
		 */
		getConfiguration: function () {
			return this.getOptions().configuration;
		},

		/**
		 * Gets the decorator list
		 *
		 * @method getDecorators
		 * @return {object[]}
		 */
		getDecorators: function () {
			return this.getOptions().decorators;
		},

		/**
		 * Gets the global configuration
		 *
		 * @method getGlobalConfig
		 * @returns {Object}
		 */
		getGlobalConfig: function () {
			return this._config;
		},

		/**
		 * Gets the coverage collector
		 *
		 * @method getCoverageCollector
		 * @returns {Collector}
		 */
		getCoverageCollector: function () {
			return this._coverageCollector;
		},

		/**
		 * Gets the type of the preceptor task
		 *
		 * @method getType
		 * @return {string}
		 */
		getType: function () {
			return this.getOptions().type;
		},

		/**
		 * Gets a unique id for the task
		 *
		 * @method getTaskId
		 * @return {string}
		 */
		getTaskId: function () {
			return this.getOptions().taskId;
		},

		/**
		 * Gets the name of the preceptor task
		 *
		 * @method getName
		 * @return {string}
		 */
		getName: function () {
			return this.getOptions().name;
		},

		/**
		 * Gets the title of the preceptor task
		 *
		 * @method getTitle
		 * @return {string}
		 */
		getTitle: function () {
			return this.getOptions().title;
		},

		/**
		 * Run tasks in a suite?
		 *
		 * @method isSuite
		 * @return {boolean}
		 */
		isSuite: function () {
			return this.getOptions().suite;
		},

		/**
		 * Is the task in debug-mode?
		 *
		 * @method inDebug
		 * @return {boolean}
		 */
		inDebug: function () {
			return this.getOptions().debug;
		},

		/**
		 * Is the task active?
		 *
		 * @method isActive
		 * @return {boolean}
		 */
		isActive: function () {
			return this.getOptions().active;
		},

		/**
		 * Is the task verbose?
		 *
		 * @method isVerbose
		 * @return {boolean}
		 */
		isVerbose: function () {
			return this.getOptions().verbose;
		},

		/**
		 * Should report?
		 *
		 * @method shouldReport
		 * @return {boolean}
		 */
		shouldReport: function () {
			return this.getOptions().report;
		},

		/**
		 * Echo std-out output of child-process?
		 *
		 * @method shouldEchoStdOut
		 * @return {boolean}
		 */
		shouldEchoStdOut: function () {
			return this.getOptions().echoStdOut;
		},

		/**
		 * Echo std-err output of child-process?
		 *
		 * @method shouldEchoStdErr
		 * @return {boolean}
		 */
		shouldEchoStdErr: function () {
			return this.getOptions().echoStdErr;
		},


		/**
		 * Gets all plugins
		 *
		 * @method getPlugins
		 * @return {object}
		 */
		getPlugins: function () {
			return this._plugins;
		},

		/**
		 * Gets all options-decorator plugins
		 *
		 * @method getTaskDecoratorPlugins
		 * @return {AbstractTaskDecorator[]}
		 */
		getTaskDecoratorPlugins: function () {
			return _.values(this.getPlugins().taskDecorator);
		},

		/**
		 * Gets all client-decorator plugins
		 *
		 * @method getClientDecoratorPlugins
		 * @return {object[]}
		 */
		getClientDecoratorPlugins: function () {
			return this.getPlugins().clientDecorator;
		},

		/**
		 * Gets a specific task plugin
		 *
		 * @method getTaskPlugin
		 * @param {string} name
		 * @return {AbstractTask}
		 */
		getTaskPlugin: function (name) {
			return this.getPlugins().task[name.toLowerCase()];
		},


		/**
		 * Gets the report manager
		 *
		 * @method getReportManager
		 * @return {ReportManager}
		 */
		getReportManager: function () {
			return this._reportManager;
		},


		/**
		 * Gets the label of the task
		 *
		 * @method getLabel
		 * @return {string}
		 */
		getLabel: function () {
			return this.getName() + '-' + this.getTaskId();
		},


		/**
		 * Run the task
		 *
		 * @method run
		 * @param {string} parentId
		 * @return {Promise}
		 */
		run: function (parentId) {

			var suiteId = parentId,
				promise;

			if (this.isActive()) {

				// Should task be wrapped in a suite? Start it
				if (this.isSuite()) {
					suiteId = 'group-' + uuid.v4(); // Generate unique-id
					this.getReportManager().message().suiteStart(suiteId, parentId, this.getTitle());
				}

				// Run task
				promise = this._run(suiteId);

				// Should tasks be wrapped in a suite? Finish it up
				if (this.isSuite()) {
					promise = promise.then(function () {
						this.getReportManager().message().suiteEnd(suiteId);
					}.bind(this), function (err) {
						this.getReportManager().message().suiteEnd(suiteId);
						throw err;
					}.bind(this));
				}

				return promise;

			} else {
				logger.debug('Skip task since it is inactive. ' + this.getLabel());
				return Promise.resolve();
			}
		},

		/**
		 * Run the task
		 *
		 * @method _run
		 * @param {string} parentId
		 * @return {Promise}
		 * @private
		 */
		_run: function (parentId) {
			throw new Error('Unimplemented task function "run".');
		}
	},

	{
		/**
		 * @property TYPE
		 * @type {string}
		 * @static
		 */
		TYPE: 'AbstractTask'
	});

module.exports = AbstractTask;