/**
* User Interface for the Scenario Runner.
*
* @param {Object} The jQuery UI object for the UI.
*/
angular.scenario.ui.Html = function(context) {
this.context = context;
context.append(
'
' +
''
);
};
/**
* Adds a new spec to the UI.
*
* @param {Object} The spec object created by the Describe object.
*/
angular.scenario.ui.Html.prototype.addSpec = function(spec) {
var specContext = this.findContext(spec.definition);
specContext.find('> .tests').append(
''
);
specContext = specContext.find('> .tests li:last');
return new angular.scenario.ui.Html.Spec(specContext, spec.name,
angular.bind(this, function(status) {
var status = this.context.find('#status-legend .status-' + status);
var parts = status.text().split(' ');
var value = (parts[0] * 1) + 1;
status.text(value + ' ' + parts[1]);
})
);
};
/**
* Finds the context of a spec block defined by the passed definition.
*
* @param {Object} The definition created by the Describe object.
*/
angular.scenario.ui.Html.prototype.findContext = function(definition) {
var path = [];
var currentContext = this.context.find('#specs');
var currentDefinition = definition;
while (currentDefinition && currentDefinition.name) {
path.unshift(currentDefinition);
currentDefinition = currentDefinition.parent;
}
angular.foreach(path, angular.bind(this, function(defn) {
var id = 'describe-' + defn.id;
if (!this.context.find('#' + id).length) {
currentContext.find('> .test-children').append(
''
);
this.context.find('#' + id).find('> h2').text('describe: ' + defn.name);
}
currentContext = this.context.find('#' + id);
}));
return this.context.find('#describe-' + definition.id);
};
/**
* A spec block in the UI.
*
* @param {Object} The jQuery object for the context of the spec.
* @param {String} The name of the spec.
* @param {Function} Callback function(status) to call when complete.
*/
angular.scenario.ui.Html.Spec = function(context, name, doneFn) {
this.status = 'pending';
this.context = context;
this.startTime = new Date().getTime();
this.doneFn = doneFn;
context.append(
'' +
'
' +
' ' +
' ' +
'
' +
'
' +
'' +
'
'
);
context.find('> .test-info .test-name').text('it ' + name);
};
/**
* Adds a new Step to this spec and returns it.
*
* @param {String} The name of the step.
*/
angular.scenario.ui.Html.Spec.prototype.addStep = function(name) {
this.context.find('> .test-actions').append('');
var stepContext = this.context.find('> .test-actions li:last');
var self = this;
return new angular.scenario.ui.Html.Step(stepContext, name, function(status) {
self.status = status;
});
};
/**
* Completes the spec and sets the timer value.
*/
angular.scenario.ui.Html.Spec.prototype.complete = function() {
this.context.removeClass('status-pending');
var endTime = new Date().getTime();
this.context.find("> .test-info .timer-result")
.text((endTime - this.startTime) + "ms");
};
/**
* Finishes the spec, possibly with an error.
*
* @param {Object} An optional error
*/
angular.scenario.ui.Html.Spec.prototype.finish = function(error) {
this.complete();
if (error) {
if (this.status !== 'failure') {
this.status = 'error';
}
this.context.append('');
this.context.find('pre:first').text(error.stack || error.toString());
}
this.context.addClass('status-' + this.status);
this.doneFn(this.status);
};
/**
* Finishes the spec, but with a Fatal Error.
*
* @param {Object} Required error
*/
angular.scenario.ui.Html.Spec.prototype.error = function(error) {
this.finish(error);
};
/**
* A single step inside an it block (or a before/after function).
*
* @param {Object} The jQuery object for the context of the step.
* @param {String} The name of the step.
* @param {Function} Callback function(status) to call when complete.
*/
angular.scenario.ui.Html.Step = function(context, name, doneFn) {
this.context = context;
this.name = name;
this.startTime = new Date().getTime();
this.doneFn = doneFn;
context.append(
'' +
''
);
context.find('> .test-title').text(name);
};
/**
* Completes the step and sets the timer value.
*/
angular.scenario.ui.Html.Step.prototype.complete = function() {
this.context.removeClass('status-pending');
var endTime = new Date().getTime();
this.context.find(".timer-result")
.text((endTime - this.startTime) + "ms");
};
/**
* Finishes the step, possibly with an error.
*
* @param {Object} An optional error
*/
angular.scenario.ui.Html.Step.prototype.finish = function(error) {
this.complete();
if (error) {
this.context.addClass('status-failure');
this.doneFn('failure');
} else {
this.context.addClass('status-success');
this.doneFn('success');
}
};
/**
* Finishes the step, but with a Fatal Error.
*
* @param {Object} Required error
*/
angular.scenario.ui.Html.Step.prototype.error = function(error) {
this.complete();
this.context.addClass('status-error');
this.doneFn('error');
};