aboutsummaryrefslogtreecommitdiffstats
path: root/src/scenario/ObjectModel.js
diff options
context:
space:
mode:
authorElliott Sprehn2010-10-24 14:14:45 -0700
committerIgor Minar2010-10-26 15:17:57 -0700
commit40d7e66f408eaaa66efd8d7934ab2eb3324236a1 (patch)
treedaf88d70df9037416598307784eb83df93df4fed /src/scenario/ObjectModel.js
parent1d52349440d40de527b5d7f3849070f525c1b79b (diff)
downloadangular.js-40d7e66f408eaaa66efd8d7934ab2eb3324236a1.tar.bz2
Lots of bug fixes in the scenario runner and a bunch of new features.
- By default the runner now creates multiple output formats as it runs. Nodes are created in the DOM with ids: json, xml, and html. ex. $('#json').html() => json output of the runner ex. $('#xml').html() => json output of the runner $result is also an object tree result. The permitted formats are html,json,xml,object. If you don't want certain formats you can select specific ones with the new ng:scenario-output attribute on the script tag. <script src="angular-scenario.js" ng:scenario-output="xml,json"> - Added element(...).count() that returns the number of matching elements for the selector. - repeater(...).count() now returns 0 if no elements matched which can be used to check if a repeater is empty. - Added toBe() matcher that does strict equality with === - Implement iit and ddescribe. If iit() is used instead of it() then only that test will run. If ddescribe() is used instead of describe() them only it() statements inside of it will run. Several iit/ddescribe() blocks can be used to run isolated tests. - Implement new event based model for SpecRunner. You can now listen for events in the runner. This is useful for writing your own UI or connecting a remote process (ex. WebDriver). Event callbacks execute on the Runner instance. Events, if fired, will always be in the below order. All events always happen except for Failure and Error events which only happen in error conditions. Events: RunnerBegin SpecBegin(spec) StepBegin(spec, step) StepError(spec, step, error) StepFailure(spec, step, error) StepEnd(spec, step) SpecError(spec, step, error) SpecEnd(spec) RunnerEnd - Only allow the browser to repaint every 10 steps. Cuts 700ms off Firefox in benchmark, 200ms off Chrome. - Bug Fix: Manually navigate anchors on click since trigger wont work in Firefox.
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();
+};