aboutsummaryrefslogtreecommitdiffstats
path: root/src/scenario/ObjectModel.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/scenario/ObjectModel.js')
-rw-r--r--src/scenario/ObjectModel.js153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/scenario/ObjectModel.js b/src/scenario/ObjectModel.js
new file mode 100644
index 00000000..e9125e03
--- /dev/null
+++ b/src/scenario/ObjectModel.js
@@ -0,0 +1,153 @@
+/**
+ * Maintains an object tree from the runner events.
+ *
+ * @param {Object} runner The scenario Runner instance to connect to.
+ *
+ * TODO(esprehn): Every output type creates one of these, but we probably
+ * want one glonal shared instance. Need to handle events better too
+ * so the HTML output doesn't need to do spec model.getSpec(spec.id)
+ * silliness.
+ */
+angular.scenario.ObjectModel = function(runner) {
+ var self = this;
+
+ this.specMap = {};
+ this.value = {
+ name: '',
+ children: {}
+ };
+
+ runner.on('SpecBegin', function(spec) {
+ var block = self.value;
+ angular.foreach(self.getDefinitionPath(spec), function(def) {
+ if (!block.children[def.name]) {
+ block.children[def.name] = {
+ id: def.id,
+ name: def.name,
+ children: {},
+ specs: {}
+ };
+ }
+ block = block.children[def.name];
+ });
+ self.specMap[spec.id] = block.specs[spec.name] =
+ new angular.scenario.ObjectModel.Spec(spec.id, spec.name);
+ });
+
+ runner.on('SpecError', function(spec, error) {
+ var it = self.getSpec(spec.id);
+ it.status = 'error';
+ it.error = error;
+ });
+
+ runner.on('SpecEnd', function(spec) {
+ var it = self.getSpec(spec.id);
+ complete(it);
+ });
+
+ runner.on('StepBegin', function(spec, step) {
+ var it = self.getSpec(spec.id);
+ it.steps.push(new angular.scenario.ObjectModel.Step(step.name));
+ });
+
+ runner.on('StepEnd', function(spec, step) {
+ var it = self.getSpec(spec.id);
+ if (it.getLastStep().name !== step.name)
+ throw 'Events fired in the wrong order. Step names don\' match.';
+ complete(it.getLastStep());
+ });
+
+ runner.on('StepFailure', function(spec, step, error) {
+ var it = self.getSpec(spec.id);
+ var item = it.getLastStep();
+ item.error = error;
+ if (!it.status) {
+ it.status = item.status = 'failure';
+ }
+ });
+
+ runner.on('StepError', function(spec, step, error) {
+ var it = self.getSpec(spec.id);
+ var item = it.getLastStep();
+ it.status = 'error';
+ item.status = 'error';
+ item.error = error;
+ });
+
+ function complete(item) {
+ item.endTime = new Date().getTime();
+ item.duration = item.endTime - item.startTime;
+ item.status = item.status || 'success';
+ }
+};
+
+/**
+ * Computes the path of definition describe blocks that wrap around
+ * this spec.
+ *
+ * @param spec Spec to compute the path for.
+ * @return {Array<Describe>} The describe block path
+ */
+angular.scenario.ObjectModel.prototype.getDefinitionPath = function(spec) {
+ var path = [];
+ var currentDefinition = spec.definition;
+ while (currentDefinition && currentDefinition.name) {
+ path.unshift(currentDefinition);
+ currentDefinition = currentDefinition.parent;
+ }
+ return path;
+};
+
+/**
+ * Gets a spec by id.
+ *
+ * @param {string} The id of the spec to get the object for.
+ * @return {Object} the Spec instance
+ */
+angular.scenario.ObjectModel.prototype.getSpec = function(id) {
+ return this.specMap[id];
+};
+
+/**
+ * A single it block.
+ *
+ * @param {string} id Id of the spec
+ * @param {string} name Name of the spec
+ */
+angular.scenario.ObjectModel.Spec = function(id, name) {
+ this.id = id;
+ this.name = name;
+ this.startTime = new Date().getTime();
+ this.steps = [];
+};
+
+/**
+ * Adds a new step to the Spec.
+ *
+ * @param {string} step Name of the step (really name of the future)
+ * @return {Object} the added step
+ */
+angular.scenario.ObjectModel.Spec.prototype.addStep = function(name) {
+ var step = new angular.scenario.ObjectModel.Step(name);
+ this.steps.push(step);
+ return step;
+};
+
+/**
+ * Gets the most recent step.
+ *
+ * @return {Object} the step
+ */
+angular.scenario.ObjectModel.Spec.prototype.getLastStep = function() {
+ return this.steps[this.steps.length-1];
+};
+
+/**
+ * A single step inside a Spec.
+ *
+ * @param {string} step Name of the step
+ */
+angular.scenario.ObjectModel.Step = function(name) {
+ this.name = name;
+ this.startTime = new Date().getTime();
+};