diff options
Diffstat (limited to 'src/scenario/Runner.js')
| -rw-r--r-- | src/scenario/Runner.js | 128 | 
1 files changed, 107 insertions, 21 deletions
| diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js index a8b23f83..f628eb04 100644 --- a/src/scenario/Runner.js +++ b/src/scenario/Runner.js @@ -2,13 +2,16 @@   * Runner for scenarios.   */  angular.scenario.Runner = function($window) { +  this.listeners = [];    this.$window = $window;    this.rootDescribe = new angular.scenario.Describe();    this.currentDescribe = this.rootDescribe;    this.api = {      it: this.it, +    iit: this.iit,      xit: angular.noop,      describe: this.describe, +    ddescribe: this.ddescribe,      xdescribe: angular.noop,      beforeEach: this.beforeEach,      afterEach: this.afterEach @@ -19,10 +22,41 @@ angular.scenario.Runner = function($window) {  };  /** + * Emits an event which notifies listeners and passes extra + * arguments. + * + * @param {string} eventName Name of the event to fire. + */ +angular.scenario.Runner.prototype.emit = function(eventName) { +  var self = this; +  var args = Array.prototype.slice.call(arguments, 1); +  eventName = eventName.toLowerCase(); +  if (!this.listeners[eventName]) +    return; +  angular.foreach(this.listeners[eventName], function(listener) { +    listener.apply(self, args); +  }); +}; + +/** + * Adds a listener for an event. + * + * @param {string} eventName The name of the event to add a handler for + * @param {string} listener The fn(...) that takes the extra arguments from emit() + */ +angular.scenario.Runner.prototype.on = function(eventName, listener) { +  eventName = eventName.toLowerCase(); +  this.listeners[eventName] = this.listeners[eventName] || []; +  this.listeners[eventName].push(listener); +}; + +/**   * Defines a describe block of a spec.   * - * @param {String} Name of the block - * @param {Function} Body of the block + * @see Describe.js + * + * @param {string} name Name of the block + * @param {Function} body Body of the block   */  angular.scenario.Runner.prototype.describe = function(name, body) {    var self = this; @@ -38,19 +72,56 @@ angular.scenario.Runner.prototype.describe = function(name, body) {  };  /** + * Same as describe, but makes ddescribe the only blocks to run. + * + * @see Describe.js + * + * @param {string} name Name of the block + * @param {Function} body Body of the block + */ +angular.scenario.Runner.prototype.ddescribe = function(name, body) { +  var self = this; +  this.currentDescribe.ddescribe(name, function() { +    var parentDescribe = self.currentDescribe; +    self.currentDescribe = this; +    try { +      body.call(this); +    } finally { +      self.currentDescribe = parentDescribe; +    } +  }); +}; + +/**   * Defines a test in a describe block of a spec.   * - * @param {String} Name of the block - * @param {Function} Body of the block + * @see Describe.js + * + * @param {string} name Name of the block + * @param {Function} body Body of the block   */  angular.scenario.Runner.prototype.it = function(name, body) {    this.currentDescribe.it(name, body);  };  /** + * Same as it, but makes iit tests the only tests to run. + * + * @see Describe.js + * + * @param {string} name Name of the block + * @param {Function} body Body of the block + */ +angular.scenario.Runner.prototype.iit = function(name, body) { +  this.currentDescribe.iit(name, body); +}; + +/**   * Defines a function to be called before each it block in the describe   * (and before all nested describes).   * + * @see Describe.js + *   * @param {Function} Callback to execute   */  angular.scenario.Runner.prototype.beforeEach = function(body) { @@ -61,6 +132,8 @@ angular.scenario.Runner.prototype.beforeEach = function(body) {   * Defines a function to be called after each it block in the describe   * (and before all nested describes).   * + * @see Describe.js + *   * @param {Function} Callback to execute   */  angular.scenario.Runner.prototype.afterEach = function(body) { @@ -68,24 +141,29 @@ angular.scenario.Runner.prototype.afterEach = function(body) {  };  /** - * Defines a function to be called before each it block in the describe - * (and before all nested describes). + * Creates a new spec runner.   * - * @param {Function} Callback to execute + * @private + * @param {Object} scope parent scope + */ +angular.scenario.Runner.prototype.createSpecRunner_ = function(scope) { +  return scope.$new(angular.scenario.SpecRunner); +}; + +/** + * Runs all the loaded tests with the specified runner class on the + * provided application. + * + * @param {angular.scenario.Application} application App to remote control.   */ -angular.scenario.Runner.prototype.run = function(ui, application, specRunnerClass, specsDone) { -  var $root = angular.scope({}, angular.service); +angular.scenario.Runner.prototype.run = function(application) {    var self = this; -  var specs = this.rootDescribe.getSpecs(); +  var $root = angular.scope(this);    $root.application = application; -  $root.ui = ui; -  $root.setTimeout = function() { -    return self.$window.setTimeout.apply(self.$window, arguments); -  }; -  asyncForEach(specs, function(spec, specDone) { +  this.emit('RunnerBegin'); +  asyncForEach(this.rootDescribe.getSpecs(), function(spec, specDone) {      var dslCache = {}; -    var runner = angular.scope($root); -    runner.$become(specRunnerClass); +    var runner = self.createSpecRunner_($root);      angular.foreach(angular.scenario.dsl, function(fn, key) {        dslCache[key] = fn.call($root);      }); @@ -105,16 +183,24 @@ angular.scenario.Runner.prototype.run = function(ui, application, specRunnerClas          // Make these methods work on the current chain          scope.addFuture = function() {            Array.prototype.push.call(arguments, line); -          return specRunnerClass.prototype.addFuture.apply(scope, arguments); +          return angular.scenario.SpecRunner. +            prototype.addFuture.apply(scope, arguments);          };          scope.addFutureAction = function() {            Array.prototype.push.call(arguments, line); -          return specRunnerClass.prototype.addFutureAction.apply(scope, arguments); +          return angular.scenario.SpecRunner. +            prototype.addFutureAction.apply(scope, arguments);          };          return scope.dsl[key].apply(scope, arguments);        };      }); -    runner.run(ui, spec, specDone); -  }, specsDone || angular.noop); +    runner.run(spec, specDone); +  }, +  function(error) { +    if (error) { +      self.emit('RunnerError', error); +    } +    self.emit('RunnerEnd'); +  });  }; | 
