From 2430f52bb97fa9d682e5f028c977c5bf94c5ec38 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Fri, 23 Mar 2012 14:03:24 -0700 Subject: chore(module): move files around in preparation for more modules --- src/ngScenario/output/Html.js | 171 ++++++++++++++++++++++++++++++++++++++++ src/ngScenario/output/Json.js | 10 +++ src/ngScenario/output/Object.js | 8 ++ src/ngScenario/output/Xml.js | 51 ++++++++++++ 4 files changed, 240 insertions(+) create mode 100644 src/ngScenario/output/Html.js create mode 100644 src/ngScenario/output/Json.js create mode 100644 src/ngScenario/output/Object.js create mode 100644 src/ngScenario/output/Xml.js (limited to 'src/ngScenario/output') diff --git a/src/ngScenario/output/Html.js b/src/ngScenario/output/Html.js new file mode 100644 index 00000000..326928d8 --- /dev/null +++ b/src/ngScenario/output/Html.js @@ -0,0 +1,171 @@ +'use strict'; + +/** + * User Interface for the Scenario Runner. + * + * TODO(esprehn): This should be refactored now that ObjectModel exists + * to use angular bindings for the UI. + */ +angular.scenario.output('html', function(context, runner, model) { + var specUiMap = {}, + lastStepUiMap = {}; + + context.append( + '' + + '
' + + '
' + + '
' + ); + + runner.on('InteractivePause', function(spec, step) { + var ui = lastStepUiMap[spec.id]; + ui.find('.test-title'). + html('paused... resume when ready.'); + }); + + runner.on('SpecBegin', function(spec) { + var ui = findContext(spec); + ui.find('> .tests').append( + '
  • ' + ); + ui = ui.find('> .tests li:last'); + ui.append( + '
    ' + + '

    ' + + ' ' + + ' ' + + '

    ' + + '
    ' + + '
    ' + + '
      ' + + '
      ' + ); + ui.find('> .test-info .test-name').text(spec.name); + ui.find('> .test-info').click(function() { + var scrollpane = ui.find('> .scrollpane'); + var actions = scrollpane.find('> .test-actions'); + var name = context.find('> .test-info .test-name'); + if (actions.find(':visible').length) { + actions.hide(); + name.removeClass('open').addClass('closed'); + } else { + actions.show(); + scrollpane.attr('scrollTop', scrollpane.attr('scrollHeight')); + name.removeClass('closed').addClass('open'); + } + }); + + specUiMap[spec.id] = ui; + }); + + runner.on('SpecError', function(spec, error) { + var ui = specUiMap[spec.id]; + ui.append('
      ');
      +    ui.find('> pre').text(formatException(error));
      +  });
      +
      +  runner.on('SpecEnd', function(spec) {
      +    var ui = specUiMap[spec.id];
      +    spec = model.getSpec(spec.id);
      +    ui.removeClass('status-pending');
      +    ui.addClass('status-' + spec.status);
      +    ui.find("> .test-info .timer-result").text(spec.duration + "ms");
      +    if (spec.status === 'success') {
      +      ui.find('> .test-info .test-name').addClass('closed');
      +      ui.find('> .scrollpane .test-actions').hide();
      +    }
      +    updateTotals(spec.status);
      +  });
      +
      +  runner.on('StepBegin', function(spec, step) {
      +    var ui = specUiMap[spec.id];
      +    spec = model.getSpec(spec.id);
      +    step = spec.getLastStep();
      +    ui.find('> .scrollpane .test-actions').append('
    1. '); + var stepUi = lastStepUiMap[spec.id] = ui.find('> .scrollpane .test-actions li:last'); + stepUi.append( + '
      ' + + '
      ' + ); + stepUi.find('> .test-title').text(step.name); + var scrollpane = stepUi.parents('.scrollpane'); + scrollpane.attr('scrollTop', scrollpane.attr('scrollHeight')); + }); + + runner.on('StepFailure', function(spec, step, error) { + var ui = lastStepUiMap[spec.id]; + addError(ui, step.line, error); + }); + + runner.on('StepError', function(spec, step, error) { + var ui = lastStepUiMap[spec.id]; + addError(ui, step.line, error); + }); + + runner.on('StepEnd', function(spec, step) { + var stepUi = lastStepUiMap[spec.id]; + spec = model.getSpec(spec.id); + step = spec.getLastStep(); + stepUi.find('.timer-result').text(step.duration + 'ms'); + stepUi.removeClass('status-pending'); + stepUi.addClass('status-' + step.status); + var scrollpane = specUiMap[spec.id].find('> .scrollpane'); + scrollpane.attr('scrollTop', scrollpane.attr('scrollHeight')); + }); + + /** + * Finds the context of a spec block defined by the passed definition. + * + * @param {Object} The definition created by the Describe object. + */ + function findContext(spec) { + var currentContext = context.find('#specs'); + angular.forEach(model.getDefinitionPath(spec), function(defn) { + var id = 'describe-' + defn.id; + if (!context.find('#' + id).length) { + currentContext.find('> .test-children').append( + '
      ' + + '

      ' + + '
      ' + + ' ' + + '
      ' + ); + context.find('#' + id).find('> h2').text('describe: ' + defn.name); + } + currentContext = context.find('#' + id); + }); + return context.find('#describe-' + spec.definition.id); + } + + /** + * Updates the test counter for the status. + * + * @param {string} the status. + */ + function updateTotals(status) { + var legend = context.find('#status-legend .status-' + status); + var parts = legend.text().split(' '); + var value = (parts[0] * 1) + 1; + legend.text(value + ' ' + parts[1]); + } + + /** + * Add an error to a step. + * + * @param {Object} The JQuery wrapped context + * @param {function()} fn() that should return the file/line number of the error + * @param {Object} the error. + */ + function addError(context, line, error) { + context.find('.test-title').append('
      ');
      +    var message = _jQuery.trim(line() + '\n\n' + formatException(error));
      +    context.find('.test-title pre:last').text(message);
      +  }
      +});
      diff --git a/src/ngScenario/output/Json.js b/src/ngScenario/output/Json.js
      new file mode 100644
      index 00000000..c024d923
      --- /dev/null
      +++ b/src/ngScenario/output/Json.js
      @@ -0,0 +1,10 @@
      +'use strict';
      +
      +/**
      + * Generates JSON output into a context.
      + */
      +angular.scenario.output('json', function(context, runner, model) {
      +  model.on('RunnerEnd', function() {
      +    context.text(angular.toJson(model.value));
      +  });
      +});
      diff --git a/src/ngScenario/output/Object.js b/src/ngScenario/output/Object.js
      new file mode 100644
      index 00000000..621b816f
      --- /dev/null
      +++ b/src/ngScenario/output/Object.js
      @@ -0,0 +1,8 @@
      +'use strict';
      +
      +/**
      + * Creates a global value $result with the result of the runner.
      + */
      +angular.scenario.output('object', function(context, runner, model) {
      +  runner.$window.$result = model.value;
      +});
      diff --git a/src/ngScenario/output/Xml.js b/src/ngScenario/output/Xml.js
      new file mode 100644
      index 00000000..6cd27fe7
      --- /dev/null
      +++ b/src/ngScenario/output/Xml.js
      @@ -0,0 +1,51 @@
      +'use strict';
      +
      +/**
      + * Generates XML output into a context.
      + */
      +angular.scenario.output('xml', function(context, runner, model) {
      +  var $ = function(args) {return new context.init(args);};
      +  model.on('RunnerEnd', function() {
      +    var scenario = $('');
      +    context.append(scenario);
      +    serializeXml(scenario, model.value);
      +  });
      +
      +  /**
      +   * Convert the tree into XML.
      +   *
      +   * @param {Object} context jQuery context to add the XML to.
      +   * @param {Object} tree node to serialize
      +   */
      +  function serializeXml(context, tree) {
      +     angular.forEach(tree.children, function(child) {
      +       var describeContext = $('');
      +       describeContext.attr('id', child.id);
      +       describeContext.attr('name', child.name);
      +       context.append(describeContext);
      +       serializeXml(describeContext, child);
      +     });
      +     var its = $('');
      +     context.append(its);
      +     angular.forEach(tree.specs, function(spec) {
      +       var it = $('');
      +       it.attr('id', spec.id);
      +       it.attr('name', spec.name);
      +       it.attr('duration', spec.duration);
      +       it.attr('status', spec.status);
      +       its.append(it);
      +       angular.forEach(spec.steps, function(step) {
      +         var stepContext = $('');
      +         stepContext.attr('name', step.name);
      +         stepContext.attr('duration', step.duration);
      +         stepContext.attr('status', step.status);
      +         it.append(stepContext);
      +         if (step.error) {
      +           var error = $('');
      +           stepContext.append(error);
      +           error.text(formatException(stepContext.error));
      +         }
      +       });
      +     });
      +   }
      +});
      -- 
      cgit v1.2.3