Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: cucumber/cucumber-js
...
head fork: cucumber/cucumber-js
  • 5 commits
  • 19 files changed
  • 0 commit comments
  • 1 contributor
View
17 History.md
@@ -2,10 +2,25 @@
## [v0.2](https://github.com/cucumber/cucumber-js/compare/v0.1.5...master)
-### [master (unreleased)](https://github.com/cucumber/cucumber-js/compare/v0.2.16...master)
+### [master (unreleased)](https://github.com/cucumber/cucumber-js/compare/v0.2.17...master)
**TBD**
+### [v0.2.17](https://github.com/cucumber/cucumber-js/compare/v0.2.16...v0.2.17)
+
+
+#### New features
+
+* Add pretty formatter (simplified, monochrome) (#59) (@renier, Julien Biezemans)
+
+#### Documentation, internals and tests
+
+* Display only master branch build status in README (Julien Biezemans)
+* Rename "summary logger" to "summarizer" (#59) (Julien Biezemans)
+* Extract common formatter methods (#59, #63) (Julien Biezemans)
+
+
+
### [v0.2.16](https://github.com/cucumber/cucumber-js/compare/v0.2.15...v0.2.16)
View
4 README.md
@@ -1,4 +1,4 @@
-# Cucumber.js [![Build Status](https://secure.travis-ci.org/cucumber/cucumber-js.png)](http://travis-ci.org/cucumber/cucumber-js)
+# Cucumber.js [![Build Status](https://secure.travis-ci.org/cucumber/cucumber-js.png?branch=master)](http://travis-ci.org/cucumber/cucumber-js)
*Cucumber*, the [popular Behaviour-Driven Development tool](http://cukes.info), brought to your JavaScript stack.
@@ -26,7 +26,7 @@ Cucumber.js is still a work in progress. Here is its current status.
| [Hooks](https://github.com/cucumber/cucumber-tck/blob/master/hooks.feature) | Done |
| [I18n](https://github.com/cucumber/cucumber-tck/blob/master/i18n.feature) | To do |
| [JSON formatter](https://github.com/cucumber/cucumber-tck/blob/master/json_formatter.feature) | To do |
-| [Pretty formatter](https://github.com/cucumber/cucumber-tck/blob/master/pretty_formatter.feature) | To do<sup>2</sup> |
+| [Pretty formatter](https://github.com/cucumber/cucumber-tck/blob/master/pretty_formatter.feature) | WIP<sup>2</sup> |
| [Scenario outlines and examples](https://github.com/cucumber/cucumber-tck/blob/master/scenario_outlines_and_examples.feature) | To do |
| [Stats collector](https://github.com/cucumber/cucumber-tck/blob/master/stats_collector.feature) | To do |
| [Step argument transforms](https://github.com/cucumber/cucumber-tck/blob/master/step_argument_transforms.feature) | To do |
View
2  lib/cucumber.js
@@ -16,6 +16,6 @@ Cucumber.Type = require('./cucumber/type');
Cucumber.Util = require('./cucumber/util');
Cucumber.VolatileConfiguration = require('./cucumber/volatile_configuration');
-Cucumber.VERSION = "0.2.16";
+Cucumber.VERSION = "0.2.17";
module.exports = Cucumber;
View
11 lib/cucumber/cli.js
@@ -13,9 +13,9 @@ var Cli = function(argv) {
},
runSuiteWithConfiguration: function runSuiteWithConfiguration(configuration, callback) {
- var runtime = Cucumber.Runtime(configuration);
- var progressFormatter = Cucumber.Listener.ProgressFormatter();
- runtime.attachListener(progressFormatter);
+ var runtime = Cucumber.Runtime(configuration);
+ var formatter = configuration.getFormatter();
+ runtime.attachListener(formatter);
runtime.start(callback);
},
@@ -57,6 +57,11 @@ var Cli = function(argv) {
tags to exclude several tags you have to use\n\
logical AND: --tags ~@fixme --tags ~@buggy.\n\
\n\
+-f, --format FORMAT How to format features (default: progress).\n\
+ Available formats:\n\
+ pretty : prints the feature as is\n\
+ progress : prints one character per scenario\n\
+\n\
-v, --version Display Cucumber.js's version.\n\
\n\
-h, --help You're looking at it.\n");
View
10 lib/cucumber/cli/argument_parser.js
@@ -57,10 +57,16 @@ var ArgumentParser = function(argv) {
return tagGroups;
},
+ getFormat: function getFormat() {
+ var format = self.getOptionOrDefault(ArgumentParser.FORMAT_OPTION_NAME, ArgumentParser.DEFAULT_FORMAT_VALUE);
+ return format;
+ },
+
getKnownOptionDefinitions: function getKnownOptionDefinitions() {
var definitions = {};
definitions[ArgumentParser.REQUIRE_OPTION_NAME] = [path, Array];
definitions[ArgumentParser.TAGS_OPTION_NAME] = [String, Array];
+ definitions[ArgumentParser.FORMAT_OPTION_NAME] = String;
definitions[ArgumentParser.HELP_FLAG_NAME] = Boolean;
definitions[ArgumentParser.VERSION_FLAG_NAME] = Boolean;
return definitions;
@@ -69,6 +75,7 @@ var ArgumentParser = function(argv) {
getShortenedOptionDefinitions: function getShortenedOptionDefinitions() {
var definitions = {};
definitions[ArgumentParser.REQUIRE_OPTION_SHORT_NAME] = [ArgumentParser.LONG_OPTION_PREFIX + ArgumentParser.REQUIRE_OPTION_NAME];
+ definitions[ArgumentParser.FORMAT_OPTION_SHORT_NAME] = [ArgumentParser.LONG_OPTION_PREFIX + ArgumentParser.FORMAT_OPTION_NAME];
definitions[ArgumentParser.HELP_FLAG_SHORT_NAME] = [ArgumentParser.LONG_OPTION_PREFIX + ArgumentParser.HELP_FLAG_NAME];
return definitions;
},
@@ -107,6 +114,9 @@ ArgumentParser.REQUIRE_OPTION_NAME = "require";
ArgumentParser.REQUIRE_OPTION_SHORT_NAME = "r";
ArgumentParser.TAGS_OPTION_NAME = "tags";
ArgumentParser.TAGS_OPTION_SHORT_NAME = "t";
+ArgumentParser.FORMAT_OPTION_NAME = "format";
+ArgumentParser.FORMAT_OPTION_SHORT_NAME = "f";
+ArgumentParser.DEFAULT_FORMAT_VALUE = "progress";
ArgumentParser.HELP_FLAG_NAME = "help";
ArgumentParser.HELP_FLAG_SHORT_NAME = "h";
ArgumentParser.DEFAULT_HELP_FLAG_VALUE = false;
View
18 lib/cucumber/cli/configuration.js
@@ -5,6 +5,22 @@ var Configuration = function(argv) {
argumentParser.parse(argv);
var self = {
+ getFormatter: function getFormatter() {
+ var formatter;
+ var format = argumentParser.getFormat();
+ switch(format) {
+ case Configuration.PROGRESS_FORMAT_NAME:
+ formatter = Cucumber.Listener.ProgressFormatter();
+ break;
+ case Configuration.PRETTY_FORMAT_NAME:
+ formatter = Cucumber.Listener.PrettyFormatter();
+ break;
+ default:
+ throw new Error("Unknown formatter name \"" + format + "\".");
+ }
+ return formatter;
+ },
+
getFeatureSources: function getFeatureSources() {
var featureFilePaths = argumentParser.getFeatureFilePaths();
var featureSourceLoader = Cucumber.Cli.FeatureSourceLoader(featureFilePaths);
@@ -47,4 +63,6 @@ var Configuration = function(argv) {
};
return self;
};
+Configuration.PRETTY_FORMAT_NAME = "pretty";
+Configuration.PROGRESS_FORMAT_NAME = "progress";
module.exports = Configuration;
View
4 lib/cucumber/listener.js
@@ -33,7 +33,9 @@ var Listener = function () {
Listener.EVENT_HANDLER_NAME_PREFIX = 'handle';
Listener.EVENT_HANDLER_NAME_SUFFIX = 'Event';
+Listener.Formatter = require('./listener/formatter');
+Listener.PrettyFormatter = require('./listener/pretty_formatter');
Listener.ProgressFormatter = require('./listener/progress_formatter');
Listener.StatsJournal = require('./listener/stats_journal');
-Listener.SummaryLogger = require('./listener/summary_logger');
+Listener.Summarizer = require('./listener/summarizer');
module.exports = Listener;
View
27 lib/cucumber/listener/formatter.js
@@ -0,0 +1,27 @@
+var Formatter = function (options) {
+ var Cucumber = require('../../cucumber');
+
+ if (!options)
+ options = {};
+ if (options['logToConsole'] == undefined)
+ options['logToConsole'] = true;
+
+ var logs = "";
+
+ var self = Cucumber.Listener();
+
+ self.log = function log(string) {
+ logs += string;
+ if (options['logToConsole'])
+ process.stdout.write(string);
+ if (typeof(options['logToFunction']) == 'function')
+ options['logToFunction'](string);
+ };
+
+ self.getLogs = function getLogs() {
+ return logs;
+ };
+
+ return self;
+};
+module.exports = Formatter;
View
71 lib/cucumber/listener/pretty_formatter.js
@@ -0,0 +1,71 @@
+var PrettyFormatter = function(options) {
+ var Cucumber = require('../../cucumber');
+
+ var self = Cucumber.Listener.Formatter(options);
+ var summarizer = Cucumber.Listener.Summarizer();
+
+ var parentHear = self.hear;
+ self.hear = function hear(event, callback) {
+ summarizer.hear(event, function () {
+ parentHear(event, callback);
+ });
+ };
+
+ self.handleBeforeFeatureEvent = function handleBeforeFeatureEvent(event, callback) {
+ var feature = event.getPayloadItem('feature');
+ var source = feature.getKeyword() + ": " + feature.getName() + "\n\n";
+ self.log(source);
+ callback();
+ };
+
+ self.handleBeforeScenarioEvent = function handleBeforeScenarioEvent(event, callback) {
+ var scenario = event.getPayloadItem('scenario');
+ var source = scenario.getKeyword() + ": " + scenario.getName() + "\n";
+ self.logIndented(source, 1);
+ callback();
+ };
+
+ self.handleAfterScenarioEvent = function handleAfterScenarioEvent(event, callback) {
+ self.log("\n");
+ callback();
+ };
+
+ self.handleStepResultEvent = function handleStepResult(event, callback) {
+ var stepResult = event.getPayloadItem('stepResult');
+ var step = stepResult.getStep();
+ var source = step.getKeyword() + step.getName() + "\n";
+ self.logIndented(source, 2);
+
+ stepResult.isFailed();
+ if (stepResult.isFailed()) {
+ var failure = stepResult.getFailureException();
+ var failureDescription = failure.stack || failure;
+ self.logIndented(failureDescription + "\n", 3);
+ }
+ callback();
+ };
+
+ self.handleAfterFeaturesEvent = function handleAfterFeaturesEvent(event, callback) {
+ var summaryLogs = summarizer.getLogs();
+ self.log(summaryLogs);
+ callback();
+ };
+
+ self.logIndented = function logIndented(text, level) {
+ var indented = self.indent(text, level);
+ self.log(indented);
+ };
+
+ self.indent = function indent(text, level) {
+ var indented;
+ text.split("\n").forEach(function(line) {
+ var prefix = new Array(level + 1).join(" ");
+ line = (prefix + line).replace(/\s+$/, '');
+ indented = (typeof(indented) == 'undefined' ? line : indented + "\n" + line);
+ });
+ return indented;
+ };
+
+ return self;
+};
+module.exports = PrettyFormatter;
View
20 lib/cucumber/listener/progress_formatter.js
@@ -1,15 +1,11 @@
var ProgressFormatter = function(options) {
var Cucumber = require('../../cucumber');
- var logs = "";
-
if (!options)
options = {};
- if (options['logToConsole'] == undefined)
- options['logToConsole'] = true;
- var self = Cucumber.Listener();
- var summaryLogger = Cucumber.Listener.SummaryLogger();
+ var self = Cucumber.Listener.Formatter(options);
+ var summaryLogger = Cucumber.Listener.Summarizer();
var parentHear = self.hear;
self.hear = function hear(event, callback) {
@@ -18,18 +14,6 @@ var ProgressFormatter = function(options) {
});
};
- self.log = function log(string) {
- logs += string;
- if (options['logToConsole'])
- process.stdout.write(string);
- if (typeof(options['logToFunction']) == 'function')
- options['logToFunction'](string);
- };
-
- self.getLogs = function getLogs() {
- return logs;
- };
-
self.handleStepResultEvent = function handleStepResult(event, callback) {
var stepResult = event.getPayloadItem('stepResult');
if (stepResult.isSuccessful())
View
4 lib/cucumber/listener/summary_logger.js → lib/cucumber/listener/summarizer.js
@@ -1,4 +1,4 @@
-var SummaryLogger = function () {
+var Summarizer = function () {
var Cucumber = require('../../cucumber');
var logs = "";
@@ -174,4 +174,4 @@ var SummaryLogger = function () {
return self;
};
-module.exports = SummaryLogger;
+module.exports = Summarizer;
View
3  package.json
@@ -1,7 +1,7 @@
{ "name" : "cucumber"
, "description" : "The official JavaScript implementation of Cucumber."
, "keywords" : [ "testing", "bdd", "cucumber", "gherkin", "tests" ]
-, "version" : "0.2.16"
+, "version" : "0.2.17"
, "homepage" : "http://github.com/cucumber/cucumber-js"
, "author" : "Julien Biezemans <jb@jbpros.com> (http://jbpros.net)"
, "contributors" : [
@@ -12,6 +12,7 @@
, "Olivier Melcher <olivier.melcher@gmail.com>"
, "Tristan Dunn <tristanzdunn@gmail.com>"
, "Ted de Koning"
+ , "@renier"
]
, "repository" :
{ "type" : "git"
View
175 spec/cucumber/cli/argument_parser_spec.js
@@ -1,23 +1,23 @@
require('../../support/spec_helper');
-describe("Cucumber.Cli.ArgumentParser", function() {
+describe("Cucumber.Cli.ArgumentParser", function () {
var Cucumber = requireLib('cucumber');
var path = require('path');
var nopt;
var argumentParser, argv;
- beforeEach(function() {
+ beforeEach(function () {
nopt = spyOnModule('nopt'); // stubbed BEFORE ArgumentParser() is called.
argv = createSpy("arguments (argv)");
argumentParser = Cucumber.Cli.ArgumentParser(argv);
});
- describe("parse()", function() {
+ describe("parse()", function () {
var knownOptionDefinitions, shortenedOptionDefinitions;
var options;
- beforeEach(function() {
+ beforeEach(function () {
knownOptionDefinitions = createSpy("known option definitions");
shortenedOptionDefinitions = createSpy("shortened option definitions");
options = createSpy("parsed options");
@@ -27,61 +27,66 @@ describe("Cucumber.Cli.ArgumentParser", function() {
spyOn(argumentParser, 'storeOptions');
});
- it("gets the known option definitions", function() {
+ it("gets the known option definitions", function () {
argumentParser.parse();
expect(argumentParser.getKnownOptionDefinitions).toHaveBeenCalled();
});
- it("gets the shortened option definitions", function() {
+ it("gets the shortened option definitions", function () {
argumentParser.parse();
expect(argumentParser.getShortenedOptionDefinitions).toHaveBeenCalled();
});
- it("gets the options from nopt based on the definitions and argv", function() {
+ it("gets the options from nopt based on the definitions and argv", function () {
argumentParser.parse();
expect(nopt).toHaveBeenCalledWith(knownOptionDefinitions, shortenedOptionDefinitions, argv, Cucumber.Cli.ArgumentParser.NUMBER_OF_LEADING_ARGS_TO_SLICE);
});
- it("stores the options", function() {
+ it("stores the options", function () {
argumentParser.parse();
expect(argumentParser.storeOptions).toHaveBeenCalledWith(options);
});
});
- describe("getKnownOptionDefinitions()", function() {
- it("returns a hash", function() {
+ describe("getKnownOptionDefinitions()", function () {
+ it("returns a hash", function () {
var knownOptionDefinitions = argumentParser.getKnownOptionDefinitions();
expect(typeof(knownOptionDefinitions)).toBe('object');
});
- it("defines a --require option to accept paths", function() {
+ it("defines a --require option to accept paths", function () {
var knownOptionDefinitions = argumentParser.getKnownOptionDefinitions();
expect(knownOptionDefinitions[Cucumber.Cli.ArgumentParser.REQUIRE_OPTION_NAME]).toEqual([path, Array]);
});
- it("defines a --tags option to include and exclude tags", function() {
+ it("defines a --tags option to include and exclude tags", function () {
var knownOptionDefinitions = argumentParser.getKnownOptionDefinitions();
expect(knownOptionDefinitions[Cucumber.Cli.ArgumentParser.TAGS_OPTION_NAME]).toEqual([String, Array]);
});
- it("defines a --help flag", function() {
+ it("defines a --format option to specify the format", function () {
+ var knownOptionDefinitions = argumentParser.getKnownOptionDefinitions();
+ expect(knownOptionDefinitions[Cucumber.Cli.ArgumentParser.FORMAT_OPTION_NAME]).toEqual(String);
+ });
+
+ it("defines a --help flag", function () {
var knownOptionDefinitions = argumentParser.getKnownOptionDefinitions();
expect(knownOptionDefinitions[Cucumber.Cli.ArgumentParser.HELP_FLAG_NAME]).toEqual(Boolean);
});
- it("defines a --version flag", function() {
+ it("defines a --version flag", function () {
var knownOptionDefinitions = argumentParser.getKnownOptionDefinitions();
expect(knownOptionDefinitions[Cucumber.Cli.ArgumentParser.VERSION_FLAG_NAME]).toEqual(Boolean);
});
});
- describe("getShortenedOptionDefinitions()", function() {
- it("returns a hash", function() {
+ describe("getShortenedOptionDefinitions()", function () {
+ it("returns a hash", function () {
var shortenedOptionDefinitions = argumentParser.getShortenedOptionDefinitions();
expect(typeof(shortenedOptionDefinitions)).toBe('object');
});
- it("defines an alias to --require as -r", function() {
+ it("defines an alias to --require as -r", function () {
var optionName = Cucumber.Cli.ArgumentParser.LONG_OPTION_PREFIX + Cucumber.Cli.ArgumentParser.REQUIRE_OPTION_NAME;
var aliasName = Cucumber.Cli.ArgumentParser.REQUIRE_OPTION_SHORT_NAME;
var aliasValue = [optionName];
@@ -89,7 +94,15 @@ describe("Cucumber.Cli.ArgumentParser", function() {
expect(shortenedOptionDefinitions[aliasName]).toEqual(aliasValue);
});
- it("defines an alias to --help as -h", function() {
+ it("defines an alias to --format as -f", function () {
+ var optionName = Cucumber.Cli.ArgumentParser.LONG_OPTION_PREFIX + Cucumber.Cli.ArgumentParser.FORMAT_OPTION_NAME;
+ var aliasName = Cucumber.Cli.ArgumentParser.FORMAT_OPTION_SHORT_NAME;
+ var aliasValue = [optionName];
+ var shortenedOptionDefinitions = argumentParser.getShortenedOptionDefinitions();
+ expect(shortenedOptionDefinitions[aliasName]).toEqual(aliasValue);
+ });
+
+ it("defines an alias to --help as -h", function () {
var optionName = Cucumber.Cli.ArgumentParser.LONG_OPTION_PREFIX + Cucumber.Cli.ArgumentParser.HELP_FLAG_NAME;
var aliasName = Cucumber.Cli.ArgumentParser.HELP_FLAG_SHORT_NAME;
var aliasValue = [optionName];
@@ -98,38 +111,38 @@ describe("Cucumber.Cli.ArgumentParser", function() {
});
});
- describe("getFeatureFilePaths()", function() {
+ describe("getFeatureFilePaths()", function () {
var Cucumber = requireLib('cucumber');
var unexpandedFeaturePaths;
var expandedFeaturePaths;
- beforeEach(function() {
+ beforeEach(function () {
unexpandedFeaturePaths = createSpy("unexpanded feature paths");
expandedFeaturePaths = createSpy("expanded feature paths");
spyOn(argumentParser, 'getUnexpandedFeaturePaths').andReturn(unexpandedFeaturePaths);
spyOn(Cucumber.Cli.ArgumentParser.FeaturePathExpander, 'expandPaths').andReturn(expandedFeaturePaths);
});
- it("gets the unexpanded feature file paths", function() {
+ it("gets the unexpanded feature file paths", function () {
argumentParser.getFeatureFilePaths();
expect(argumentParser.getUnexpandedFeaturePaths).toHaveBeenCalled();
});
- it("asks the feature path expander to expand the paths", function() {
+ it("asks the feature path expander to expand the paths", function () {
argumentParser.getFeatureFilePaths();
expect(Cucumber.Cli.ArgumentParser.FeaturePathExpander.expandPaths).toHaveBeenCalledWith(unexpandedFeaturePaths);
});
- it("returns the expanded feature file paths", function() {
+ it("returns the expanded feature file paths", function () {
expect(argumentParser.getFeatureFilePaths()).toBe(expandedFeaturePaths);
});
});
- describe("getFeatureDirectoryPaths()", function() {
+ describe("getFeatureDirectoryPaths()", function () {
var featureFilePaths, featureDirectoryPaths;
- beforeEach(function() {
+ beforeEach(function () {
featureDirectoryPaths = [createSpy("first feature directory path"),
createSpy("second feature directory path")];
featureFilePaths = [createSpyWithStubs("first feature path",
@@ -139,218 +152,236 @@ describe("Cucumber.Cli.ArgumentParser", function() {
spyOn(argumentParser, 'getFeatureFilePaths').andReturn(featureFilePaths);
});
- it("gets the feature file paths", function() {
+ it("gets the feature file paths", function () {
argumentParser.getFeatureDirectoryPaths();
expect(argumentParser.getFeatureFilePaths).toHaveBeenCalled();
});
- it("strips off the feature file name from each path", function() {
+ it("strips off the feature file name from each path", function () {
argumentParser.getFeatureDirectoryPaths();
- featureFilePaths.forEach(function(featureFilePath) {
+ featureFilePaths.forEach(function (featureFilePath) {
expect(featureFilePath.replace).toHaveBeenCalledWith(Cucumber.Cli.ArgumentParser.FEATURE_FILENAME_REGEXP, '');
});
});
- it("returns the paths", function() {
+ it("returns the paths", function () {
expect(argumentParser.getFeatureDirectoryPaths()).toEqual(featureDirectoryPaths);
});
});
- describe("getUnexpandedFeaturePaths()", function() {
+ describe("getUnexpandedFeaturePaths()", function () {
var options, remaining;
- beforeEach(function() {
+ beforeEach(function () {
options = { argv: { remain: [] } };
spyOn(argumentParser, 'getOptions').andReturn(options);
});
- it("gets the options", function() {
+ it("gets the options", function () {
argumentParser.getUnexpandedFeaturePaths();
expect(argumentParser.getOptions).toHaveBeenCalled();
});
- describe("when there are remaining command-line arguments", function() {
- beforeEach(function() {
+ describe("when there are remaining command-line arguments", function () {
+ beforeEach(function () {
remaining = [createSpy("remaining command-line argument")];
remaining.length = 1;
options = { argv: { remain: remaining } };
argumentParser.getOptions.andReturn(options);
});
- it("returns the remaining command-line arguments", function() {
+ it("returns the remaining command-line arguments", function () {
expect(argumentParser.getUnexpandedFeaturePaths()).toBe(remaining);
});
});
- describe("when there are no remaining command-line arguments", function() {
- beforeEach(function() {
+ describe("when there are no remaining command-line arguments", function () {
+ beforeEach(function () {
options = { argv: { remain: [] } };
argumentParser.getOptions.andReturn(options);
});
- it("returns the default 'features' sub-directory path", function() {
+ it("returns the default 'features' sub-directory path", function () {
expect(argumentParser.getUnexpandedFeaturePaths()).toEqual(["features"]);
});
});
});
- describe("getSupportCodeFilePaths", function() {
+ describe("getSupportCodeFilePaths", function () {
var unexpandedSupportCodeFilePaths, expandedSupportCodePaths;
- beforeEach(function() {
+ beforeEach(function () {
unexpandedSupportCodeFilePaths = createSpy("unexpanded support code file paths");
expandedSupportCodePaths = createSpy("expanded support code file paths");
spyOn(argumentParser, 'getUnexpandedSupportCodeFilePaths').andReturn(unexpandedSupportCodeFilePaths);
spyOn(Cucumber.Cli.ArgumentParser.SupportCodePathExpander, 'expandPaths').andReturn(expandedSupportCodePaths);
});
- it("gets the unexpanded support code file paths", function() {
+ it("gets the unexpanded support code file paths", function () {
argumentParser.getSupportCodeFilePaths();
expect(argumentParser.getUnexpandedSupportCodeFilePaths).toHaveBeenCalled();
});
- it("asks the support code file expander to expand the paths", function() {
+ it("asks the support code file expander to expand the paths", function () {
argumentParser.getSupportCodeFilePaths();
expect(Cucumber.Cli.ArgumentParser.SupportCodePathExpander.expandPaths).toHaveBeenCalledWith(unexpandedSupportCodeFilePaths);
});
- it("returns the expanded support code paths", function() {
+ it("returns the expanded support code paths", function () {
expect(argumentParser.getSupportCodeFilePaths()).toBe(expandedSupportCodePaths);
});
});
- describe("getUnexpandedSupportCodeFilePaths()", function() {
+ describe("getUnexpandedSupportCodeFilePaths()", function () {
var featureDirectoryPaths, unexpandedSupportCodeFilePaths;
- beforeEach(function() {
+ beforeEach(function () {
featureDirectoryPaths = createSpy("paths to directories in which features lie");
unexpandedSupportCodeFilePaths = createSpy("unexpanded support code file paths");
spyOn(argumentParser, 'getFeatureDirectoryPaths').andReturn(featureDirectoryPaths);
spyOn(argumentParser, 'getOptionOrDefault').andReturn(unexpandedSupportCodeFilePaths);
});
- it("gets the directories in which the features lie", function() {
+ it("gets the directories in which the features lie", function () {
argumentParser.getUnexpandedSupportCodeFilePaths();
expect(argumentParser.getFeatureDirectoryPaths).toHaveBeenCalled();
});
- it("gets the unexpanded support code file paths from the --require option or its default value: the feature directories", function() {
+ it("gets the unexpanded support code file paths from the --require option or its default value: the feature directories", function () {
argumentParser.getUnexpandedSupportCodeFilePaths();
expect(argumentParser.getOptionOrDefault).toHaveBeenCalledWith(Cucumber.Cli.ArgumentParser.REQUIRE_OPTION_NAME, featureDirectoryPaths);
});
- it("returns the unexpanded support code file paths", function() {
+ it("returns the unexpanded support code file paths", function () {
expect(argumentParser.getUnexpandedSupportCodeFilePaths()).toBe(unexpandedSupportCodeFilePaths);
});
});
- describe("getTagGroups()", function() {
+ describe("getTagGroups()", function () {
var _ = require('underscore');
var tagOptionValues, tagGroups;
- beforeEach(function() {
+ beforeEach(function () {
tagOptionValues = createSpy("tag option values");
tagGroups = createSpy("tag groups");
spyOn(argumentParser, 'getOptionOrDefault').andReturn(tagOptionValues);
spyOn(Cucumber.TagGroupParser, 'getTagGroupsFromStrings').andReturn(tagGroups);
});
- it("gets the tag option values", function() {
+ it("gets the tag option values", function () {
argumentParser.getTagGroups();
expect(argumentParser.getOptionOrDefault).toHaveBeenCalledWith(Cucumber.Cli.ArgumentParser.TAGS_OPTION_NAME, []);
});
- it("gets the tag groups based on the tag option values", function() {
+ it("gets the tag groups based on the tag option values", function () {
argumentParser.getTagGroups();
expect(Cucumber.TagGroupParser.getTagGroupsFromStrings).toHaveBeenCalledWith(tagOptionValues);
});
- it("returns the tag option values", function() {
+ it("returns the tag option values", function () {
expect(argumentParser.getTagGroups()).toBe(tagGroups);
});
});
- describe("isHelpRequested()", function() {
+ describe("getFormat()", function () {
+ var format;
+
+ beforeEach(function () {
+ format = createSpy("format");
+ spyOn(argumentParser, 'getOptionOrDefault').andReturn(format);
+ });
+
+ it("gets the format option value", function () {
+ argumentParser.getFormat();
+ expect(argumentParser.getOptionOrDefault).toHaveBeenCalledWith(Cucumber.Cli.ArgumentParser.FORMAT_OPTION_NAME, 'progress');
+ });
+
+ it("returns the format", function () {
+ expect(argumentParser.getFormat()).toBe(format);
+ });
+ });
+
+ describe("isHelpRequested()", function () {
var isHelpRequested;
- beforeEach(function() {
+ beforeEach(function () {
isHelpRequested = createSpy("is help requested?");
spyOn(argumentParser, 'getOptionOrDefault').andReturn(isHelpRequested);
});
- it("gets the 'help' flag with a default value", function() {
+ it("gets the 'help' flag with a default value", function () {
argumentParser.isHelpRequested();
expect(argumentParser.getOptionOrDefault).toHaveBeenCalledWith(Cucumber.Cli.ArgumentParser.HELP_FLAG_NAME, Cucumber.Cli.ArgumentParser.DEFAULT_HELP_FLAG_VALUE);
});
- it("returns the flag value", function() {
+ it("returns the flag value", function () {
expect(argumentParser.isHelpRequested()).toBe(isHelpRequested);
});
});
- describe("isVersionRequested()", function() {
+ describe("isVersionRequested()", function () {
var isVersionRequested;
- beforeEach(function() {
+ beforeEach(function () {
isVersionRequested = createSpy("is version requested?");
spyOn(argumentParser, 'getOptionOrDefault').andReturn(isVersionRequested);
});
- it("gets the 'version' flag with a default value", function() {
+ it("gets the 'version' flag with a default value", function () {
argumentParser.isVersionRequested();
expect(argumentParser.getOptionOrDefault).toHaveBeenCalledWith(Cucumber.Cli.ArgumentParser.VERSION_FLAG_NAME, Cucumber.Cli.ArgumentParser.DEFAULT_VERSION_FLAG_VALUE);
});
- it("returns the flag value", function() {
+ it("returns the flag value", function () {
expect(argumentParser.isVersionRequested()).toBe(isVersionRequested);
});
});
- describe("getOptions() [storeOptions()]", function() {
+ describe("getOptions() [storeOptions()]", function () {
var options;
- beforeEach(function() {
+ beforeEach(function () {
options = createSpy("options");
});
- it("returns the stored options", function() {
+ it("returns the stored options", function () {
argumentParser.storeOptions(options);
expect(argumentParser.getOptions()).toBe(options);
});
});
- describe("getOptionOrDefault()", function() {
+ describe("getOptionOrDefault()", function () {
var optionName, defaultVaue;
- beforeEach(function() {
+ beforeEach(function () {
optionName = "option-name";
defaultValue = createSpy("default option value");
spyOn(argumentParser, 'getOptions').andReturn({});
});
- it("gets the options", function() {
+ it("gets the options", function () {
argumentParser.getOptionOrDefault(optionName, defaultValue);
expect(argumentParser.getOptions).toHaveBeenCalled();
});
- describe("when the requested option has a value", function() {
+ describe("when the requested option has a value", function () {
var options, optionValue;
- beforeEach(function() {
+ beforeEach(function () {
options = {};
optionValue = createSpy("option value");
options[optionName] = optionValue;
argumentParser.getOptions.andReturn(options);
});
- it("returns the option value", function() {
+ it("returns the option value", function () {
expect(argumentParser.getOptionOrDefault(optionName, defaultValue)).toBe(optionValue);
});
});
- describe("when the requested option is not set", function() {
- it("returns the default value", function() {
+ describe("when the requested option is not set", function () {
+ it("returns the default value", function () {
expect(argumentParser.getOptionOrDefault(optionName, defaultValue)).toBe(defaultValue);
});
});
View
134 spec/cucumber/cli/configuration_spec.js
@@ -1,14 +1,14 @@
require('../../support/spec_helper');
require('../../support/configurations_shared_examples.js');
-describe("Cucumber.Cli.Configuration", function() {
+describe("Cucumber.Cli.Configuration", function () {
var Cucumber = requireLib('cucumber');
var argv, configuration;
var argumentParser;
var context = {};
- beforeEach(function() {
+ beforeEach(function () {
argv = createSpy("arguments (argv)");
argumentParser = createSpyWithStubs("argument parser", {parse: null});
spyOn(Cucumber.Cli, 'ArgumentParser').andReturn(argumentParser);
@@ -18,20 +18,82 @@ describe("Cucumber.Cli.Configuration", function() {
itBehavesLikeAllCucumberConfigurations(context);
- describe("constructor", function() {
- it("creates an argument parser", function() {
+ describe("constructor", function () {
+ it("creates an argument parser", function () {
expect(Cucumber.Cli.ArgumentParser).toHaveBeenCalledWith();
});
- it("tells the argument parser to parse the arguments", function() {
+ it("tells the argument parser to parse the arguments", function () {
expect(argumentParser.parse).toHaveBeenCalledWith(argv);
});
});
- describe("getFeatureSources()", function() {
+ describe("getFormatter()", function () {
+ beforeEach(function () {
+ spyOnStub(argumentParser, 'getFormat').andReturn("progress");
+ });
+
+ it("gets the formatter name from the argument parser", function () {
+ configuration.getFormatter();
+ expect(argumentParser.getFormat).toHaveBeenCalled();
+ });
+
+ describe("when the formatter name is \"progress\"", function () {
+ var formatter;
+
+ beforeEach(function () {
+ argumentParser.getFormat.andReturn("progress");
+ formatter = createSpy("formatter");
+ spyOn(Cucumber.Listener, 'ProgressFormatter').andReturn(formatter);
+ });
+
+ it("creates a new progress formatter", function () {
+ configuration.getFormatter();
+ expect(Cucumber.Listener.ProgressFormatter).toHaveBeenCalled();
+ });
+
+ it("returns the progress formatter", function () {
+ expect(configuration.getFormatter()).toBe(formatter);
+ });
+ });
+
+ describe("when the formatter name is \"pretty\"", function () {
+ var formatter;
+
+ beforeEach(function () {
+ argumentParser.getFormat.andReturn("pretty");
+ formatter = createSpy("formatter");
+ spyOn(Cucumber.Listener, 'PrettyFormatter').andReturn(formatter);
+ });
+
+ it("creates a new pretty formatter", function () {
+ configuration.getFormatter();
+ expect(Cucumber.Listener.PrettyFormatter).toHaveBeenCalled();
+ });
+
+ it("returns the pretty formatter", function () {
+ expect(configuration.getFormatter()).toBe(formatter);
+ });
+ });
+
+ describe("when the formatter name is unknown", function () {
+ var formatter;
+
+ beforeEach(function () {
+ argumentParser.getFormat.andReturn("blah");
+ });
+
+ it("throws an exceptions", function () {
+ expect(configuration.getFormatter).toThrow();
+ });
+ });
+ });
+
+
+ describe("getFeatureSources()", function () {
var featureFilePaths, featureSourceLoader, featureSources;
- beforeEach(function() {
+ beforeEach(function () {
featureFilePaths = createSpy("feature file paths");
featureSourceLoader = createSpy("feature source loader");
featureSources = createSpy("feature sources");
@@ -40,55 +102,55 @@ describe("Cucumber.Cli.Configuration", function() {
spyOn(Cucumber.Cli, 'FeatureSourceLoader').andReturn(featureSourceLoader);
});
- it("gets the feature file paths", function() {
+ it("gets the feature file paths", function () {
configuration.getFeatureSources();
expect(argumentParser.getFeatureFilePaths).toHaveBeenCalled();
});
- it("creates a feature source loader for those paths", function() {
+ it("creates a feature source loader for those paths", function () {
configuration.getFeatureSources();
expect(Cucumber.Cli.FeatureSourceLoader).toHaveBeenCalledWith(featureFilePaths);
});
- it("gets the feature sources from the loader", function() {
+ it("gets the feature sources from the loader", function () {
configuration.getFeatureSources();
expect(featureSourceLoader.getSources).toHaveBeenCalled();
});
- it("returns the feature sources", function() {
+ it("returns the feature sources", function () {
expect(configuration.getFeatureSources()).toBe(featureSources);
});
});
- describe("getAstFilter()", function() {
+ describe("getAstFilter()", function () {
var astFilter, tagFilterRules;
- beforeEach(function() {
+ beforeEach(function () {
astFilter = createSpyWithStubs("AST filter");
tagFilterRules = createSpy("tag specs");
spyOn(Cucumber.Ast, 'Filter').andReturn(astFilter);
spyOn(configuration, 'getTagAstFilterRules').andReturn(tagFilterRules);
});
- it("gets the tag filter rules", function() {
+ it("gets the tag filter rules", function () {
configuration.getAstFilter();
expect(configuration.getTagAstFilterRules).toHaveBeenCalled();
});
- it("instantiates an AST filter", function() {
+ it("instantiates an AST filter", function () {
configuration.getAstFilter();
expect(Cucumber.Ast.Filter).toHaveBeenCalledWith(tagFilterRules);
});
- it("returns the AST filter", function() {
+ it("returns the AST filter", function () {
expect(configuration.getAstFilter()).toBe(astFilter);
});
});
- describe("getSupportCodeLibrary()", function() {
+ describe("getSupportCodeLibrary()", function () {
var supportCodeFilePaths, supportCodeLoader, supportCodeLibrary;
- beforeEach(function() {
+ beforeEach(function () {
supportCodeFilePaths = createSpy("support code file paths");
supportCodeLoader = createSpy("support code loader");
supportCodeLibrary = createSpy("support code library");
@@ -97,81 +159,81 @@ describe("Cucumber.Cli.Configuration", function() {
spyOnStub(supportCodeLoader, 'getSupportCodeLibrary').andReturn(supportCodeLibrary);
});
- it("gets the support code file paths", function() {
+ it("gets the support code file paths", function () {
configuration.getSupportCodeLibrary();
expect(argumentParser.getSupportCodeFilePaths).toHaveBeenCalled();
});
- it("creates a support code loader for those paths", function() {
+ it("creates a support code loader for those paths", function () {
configuration.getSupportCodeLibrary();
expect(Cucumber.Cli.SupportCodeLoader).toHaveBeenCalledWith(supportCodeFilePaths);
});
- it("gets the support code library from the support code loader", function() {
+ it("gets the support code library from the support code loader", function () {
configuration.getSupportCodeLibrary();
expect(supportCodeLoader.getSupportCodeLibrary).toHaveBeenCalled();
});
- it("returns the support code library", function() {
+ it("returns the support code library", function () {
expect(configuration.getSupportCodeLibrary()).toBe(supportCodeLibrary);
});
});
- describe("getTagAstFilterRules()", function() {
+ describe("getTagAstFilterRules()", function () {
var tagGroups, rules;
- beforeEach(function() {
+ beforeEach(function () {
tagGroups = [createSpy("tag group 1"), createSpy("tag group 2"), createSpy("tag group 3")];
rules = [createSpy("any of tags rule 1"), createSpy("any of tags rule 2"), createSpy("any of tags rule 3")];
spyOnStub(argumentParser, 'getTagGroups').andReturn(tagGroups);
spyOn(Cucumber.Ast.Filter, 'AnyOfTagsRule').andReturnSeveral(rules);
});
- it("gets the tag groups from the argument parser", function() {
+ it("gets the tag groups from the argument parser", function () {
configuration.getTagAstFilterRules();
expect(argumentParser.getTagGroups).toHaveBeenCalled();
});
- it("creates an 'any of tags' filter rule per each group", function() {
+ it("creates an 'any of tags' filter rule per each group", function () {
configuration.getTagAstFilterRules();
- tagGroups.forEach(function(tagGroup) {
+ tagGroups.forEach(function (tagGroup) {
expect(Cucumber.Ast.Filter.AnyOfTagsRule).toHaveBeenCalledWith(tagGroup);
});
});
- it("returns all the rules", function() {
+ it("returns all the rules", function () {
expect(configuration.getTagAstFilterRules()).toEqual(rules);
});
});
- describe("isHelpRequired()", function() {
- beforeEach(function() {
+ describe("isHelpRequired()", function () {
+ beforeEach(function () {
spyOnStub(argumentParser, 'isHelpRequested');
});
- it("asks the argument parser whether the help was requested or not", function() {
+ it("asks the argument parser whether the help was requested or not", function () {
configuration.isHelpRequested();
expect(argumentParser.isHelpRequested).toHaveBeenCalled();
});
- it("returns the answer from the argument parser", function() {
+ it("returns the answer from the argument parser", function () {
var isHelpRequested = createSpy("is help requested?");
argumentParser.isHelpRequested.andReturn(isHelpRequested);
expect(configuration.isHelpRequested()).toBe(isHelpRequested);
});
});
- describe("isVersionRequired()", function() {
- beforeEach(function() {
+ describe("isVersionRequired()", function () {
+ beforeEach(function () {
spyOnStub(argumentParser, 'isVersionRequested');
});
- it("asks the argument parser whether the version was requested or not", function() {
+ it("asks the argument parser whether the version was requested or not", function () {
configuration.isVersionRequested();
expect(argumentParser.isVersionRequested).toHaveBeenCalled();
});
- it("returns the answer from the argument parser", function() {
+ it("returns the answer from the argument parser", function () {
var isVersionRequested = createSpy("is version requested?");
argumentParser.isVersionRequested.andReturn(isVersionRequested);
expect(configuration.isVersionRequested()).toBe(isVersionRequested);
View
14 spec/cucumber/cli_spec.js
@@ -109,14 +109,14 @@ describe("Cucumber.Cli", function() {
describe("runSuiteWithConfiguration()", function() {
var configuration, runtime, callback;
- var progressFormatter;
+ var formatter;
beforeEach(function() {
- configuration = createSpy("CLI configuration");
+ formatter = createSpy("formatter");
+ configuration = createSpyWithStubs("CLI configuration", {getFormatter: formatter});
runtime = createSpyWithStubs("runtime", {start: null, attachListener: null});
callback = createSpy("callback");
spyOn(Cucumber, 'Runtime').andReturn(runtime);
- spyOn(Cucumber.Listener, 'ProgressFormatter').andReturn(progressFormatter);
});
it("creates a Cucumber runtime with the CLI configuration", function() {
@@ -124,14 +124,14 @@ describe("Cucumber.Cli", function() {
expect(Cucumber.Runtime).toHaveBeenCalledWith(configuration);
});
- it("creates a new progress formatter", function() {
+ it("gets the formatter from the configuration", function() {
cli.runSuiteWithConfiguration(configuration, callback);
- expect(Cucumber.Listener.ProgressFormatter).toHaveBeenCalled();
+ expect(configuration.getFormatter).toHaveBeenCalled();
});
- it("attaches the progress formatter to the runtime", function() {
+ it("attaches the formatter to the runtime", function() {
cli.runSuiteWithConfiguration(configuration, callback);
- expect(runtime.attachListener).toHaveBeenCalledWith(progressFormatter);
+ expect(runtime.attachListener).toHaveBeenCalledWith(formatter);
});
it("runs the runtime with the callback", function() {
View
98 spec/cucumber/listener/formatter_spec.js
@@ -0,0 +1,98 @@
+require('../../support/spec_helper');
+
+describe("Cucumber.Listener.Formatter", function () {
+ var Cucumber = requireLib('cucumber');
+ var formatter, listener;
+
+ beforeEach(function () {
+ var Formatter = Cucumber.Listener.Formatter;
+ listener = createSpy("listener");
+ spyOn(Cucumber, 'Listener').andReturn(listener);
+ Cucumber.Listener.Formatter = Formatter;
+ formatter = Cucumber.Listener.Formatter();
+ });
+
+ describe("constructor", function () {
+ it("creates a listener", function () {
+ expect(Cucumber.Listener).toHaveBeenCalled();
+ });
+
+ it("extends the formatter", function () {
+ expect(formatter).toBe(listener);
+ });
+ });
+
+ describe("log()", function () {
+ var logged, alsoLogged, loggedBuffer;
+
+ beforeEach(function () {
+ logged = "this was logged";
+ alsoLogged = "this was also logged";
+ loggedBuffer = logged + alsoLogged;
+ spyOn(process.stdout, 'write');
+ });
+
+ it("records logged strings", function () {
+ formatter.log(logged);
+ formatter.log(alsoLogged);
+ expect(formatter.getLogs()).toBe(loggedBuffer);
+ });
+
+ it("outputs the logged string to STDOUT by default", function () {
+ formatter.log(logged);
+ expect(process.stdout.write).toHaveBeenCalledWith(logged);
+ });
+
+ describe("when asked to output to STDOUT", function () {
+ beforeEach(function () {
+ formatter = Cucumber.Listener.Formatter({logToConsole: true});
+ });
+
+ it("outputs the logged string to STDOUT", function () {
+ formatter.log(logged);
+ expect(process.stdout.write).toHaveBeenCalledWith(logged);
+ });
+ });
+
+ describe("when asked to not output to STDOUT", function () {
+ beforeEach(function () {
+ formatter = Cucumber.Listener.Formatter({logToConsole: false});
+ });
+
+ it("does not output anything to STDOUT", function () {
+ formatter.log(logged);
+ expect(process.stdout.write).not.toHaveBeenCalledWith(logged);
+ });
+ });
+
+ describe("when asked to output to a function", function () {
+ var userFunction;
+
+ beforeEach(function () {
+ userFunction = createSpy("output user function");
+ formatter = Cucumber.Listener.Formatter({logToFunction: userFunction});
+ });
+
+ it("calls the function with the logged string", function () {
+ formatter.log(logged);
+ expect(userFunction).toHaveBeenCalledWith(logged);
+ });
+ });
+ });
+
+ describe("getLogs()", function () {
+ it("returns the logged buffer", function () {
+ var logged = "this was logged";
+ var alsoLogged = "this was also logged";
+ var loggedBuffer = logged + alsoLogged;
+ spyOn(process.stdout, 'write'); // prevent actual output during spec execution
+ formatter.log(logged);
+ formatter.log(alsoLogged);
+ expect(formatter.getLogs()).toBe(loggedBuffer);
+ });
+
+ it("returns an empty string when the progress formatter did not log anything yet", function () {
+ expect(formatter.getLogs()).toBe("");
+ });
+ });
+});
View
315 spec/cucumber/listener/pretty_formatter_spec.js
@@ -0,0 +1,315 @@
+require('../../support/spec_helper');
+
+describe("Cucumber.Listener.PrettyFormatter", function () {
+ var Cucumber = requireLib('cucumber');
+ var formatter, formatterHearMethod, summarizer, prettyFormatter, options;
+
+ beforeEach(function () {
+ options = createSpy(options);
+ formatter = createSpyWithStubs("formatter", {log: null});
+ formatterHearMethod = spyOnStub(formatter, 'hear');
+ summarizer = createSpy("summarizer");
+ spyOn(Cucumber.Listener, 'Formatter').andReturn(formatter);
+ spyOn(Cucumber.Listener, 'Summarizer').andReturn(summarizer);
+ prettyFormatter = Cucumber.Listener.PrettyFormatter(options);
+ });
+
+ describe("constructor", function () {
+ it("creates a formatter", function() {
+ expect(Cucumber.Listener.Formatter).toHaveBeenCalledWith(options);
+ });
+
+ it("extends the formatter", function () {
+ expect(prettyFormatter).toBe(formatter);
+ });
+
+ it("creates a summarizer", function () {
+ expect(Cucumber.Listener.Summarizer).toHaveBeenCalled();
+ });
+ });
+
+ describe("hear()", function () {
+ var event, callback;
+
+ beforeEach(function () {
+ event = createSpy("event");
+ callback = createSpy("callback");
+ spyOnStub(summarizer, 'hear');
+ });
+
+ it("tells the summarizer to listen to the event", function () {
+ prettyFormatter.hear(event, callback);
+ expect(summarizer.hear).toHaveBeenCalled();
+ expect(summarizer.hear).toHaveBeenCalledWithValueAsNthParameter(event, 1);
+ expect(summarizer.hear).toHaveBeenCalledWithAFunctionAsNthParameter(2);
+ });
+
+ describe("summarizer callback", function () {
+ var summarizerCallback;
+
+ beforeEach(function () {
+ prettyFormatter.hear(event, callback);
+ summarizerCallback = summarizer.hear.mostRecentCall.args[1];
+ });
+
+ it("tells the formatter to listen to the event", function () {
+ summarizerCallback();
+ expect(formatterHearMethod).toHaveBeenCalledWith(event, callback);
+ });
+ });
+ });
+
+ describe("handleBeforeFeatureEvent()", function () {
+ var event, feature, keyword, name, callback;
+
+ beforeEach(function () {
+ keyword = "feature-keyword";
+ name = "feature-name";
+ feature = createSpyWithStubs("feature", { getKeyword: keyword, getName: name });
+ event = createSpyWithStubs("event", { getPayloadItem: feature });
+ callback = createSpy("callback");
+ });
+
+ it("gets the feature from the event payload", function () {
+ prettyFormatter.handleBeforeFeatureEvent(event, callback);
+ expect(event.getPayloadItem).toHaveBeenCalledWith('feature');
+ });
+
+ it("gets the feature keyword", function () {
+ prettyFormatter.handleBeforeFeatureEvent(event, callback);
+ expect(feature.getKeyword).toHaveBeenCalled();
+ });
+
+ it("gets the feature name", function () {
+ prettyFormatter.handleBeforeFeatureEvent(event, callback);
+ expect(feature.getName).toHaveBeenCalled();
+ });
+
+ it("logs the feature header", function () {
+ prettyFormatter.handleBeforeFeatureEvent(event, callback);
+ var text = keyword + ": " + name + "\n\n";
+ expect(prettyFormatter.log).toHaveBeenCalledWith(text);
+ });
+
+ it("calls back", function () {
+ prettyFormatter.handleBeforeFeatureEvent(event, callback);
+ expect(callback).toHaveBeenCalled();
+ });
+ });
+
+ describe("handleBeforeScenarioEvent()", function () {
+ var event, scenario, keyword, name, callback;
+
+ beforeEach(function () {
+ keyword = "scenario-keyword";
+ name = "scenario-name";
+ scenario = createSpyWithStubs("scenario", { getKeyword: keyword, getName: name });
+ event = createSpyWithStubs("event", { getPayloadItem: scenario });
+ spyOn(prettyFormatter, 'logIndented');
+ callback = createSpy("callback");
+ });
+
+ it("gets the scenario from the event payload", function () {
+ prettyFormatter.handleBeforeScenarioEvent(event, callback);
+ expect(event.getPayloadItem).toHaveBeenCalledWith('scenario');
+ });
+
+ it("gets the scenario keyword", function () {
+ prettyFormatter.handleBeforeScenarioEvent(event, callback);
+ expect(scenario.getKeyword).toHaveBeenCalled();
+ });
+
+ it("gets the scenario name", function () {
+ prettyFormatter.handleBeforeScenarioEvent(event, callback);
+ expect(scenario.getName).toHaveBeenCalled();
+ });
+
+ it("logs the scenario header, indented by one level", function () {
+ prettyFormatter.handleBeforeScenarioEvent(event, callback);
+ var text = keyword + ": " + name + "\n";
+ expect(prettyFormatter.logIndented).toHaveBeenCalledWith(text, 1);
+ });
+
+ it("calls back", function () {
+ prettyFormatter.handleBeforeScenarioEvent(event, callback);
+ expect(callback).toHaveBeenCalled();
+ });
+ });
+
+ describe("handleAfterScenarioEvent()", function () {
+ var event, callback;
+
+ beforeEach(function () {
+ event = createSpy("event");
+ callback = createSpy("callback");
+ });
+
+ it("logs a new line", function () {
+ prettyFormatter.handleAfterScenarioEvent(event, callback);
+ expect(prettyFormatter.log).toHaveBeenCalledWith("\n");
+ });
+
+ it("calls back", function () {
+ prettyFormatter.handleAfterScenarioEvent(event, callback);
+ expect(callback).toHaveBeenCalled();
+ });
+ });
+
+ describe("handleStepResultEvent()", function () {
+ var event, stepResult, keyword, name, step, callback;
+
+ beforeEach(function () {
+ keyword = "step-keyword ";
+ name = "step-name";
+ step = createSpyWithStubs("step", { getKeyword: keyword, getName: name });
+ stepResult = createSpyWithStubs("step result", { getStep: step, isFailed: null });
+ event = createSpyWithStubs("event", { getPayloadItem: stepResult });
+ spyOn(prettyFormatter, 'logIndented');
+ callback = createSpy("callback");
+ });
+
+ it("gets the step result from the event payload", function () {
+ prettyFormatter.handleStepResultEvent(event, callback);
+ expect(event.getPayloadItem).toHaveBeenCalledWith('stepResult');
+ });
+
+ it("gets the step from the step result", function () {
+ prettyFormatter.handleStepResultEvent(event, callback);
+ expect(stepResult.getStep).toHaveBeenCalled();
+ });
+
+ it("gets the step keyword", function () {
+ prettyFormatter.handleStepResultEvent(event, callback);
+ expect(step.getKeyword).toHaveBeenCalled();
+ });
+
+ it("gets the step name", function () {
+ prettyFormatter.handleStepResultEvent(event, callback);
+ expect(step.getName).toHaveBeenCalled();
+ });
+
+ it("logs the step header, indented by two levels", function () {
+ prettyFormatter.handleStepResultEvent(event, callback);
+ var text = keyword + name + "\n";
+ expect(prettyFormatter.logIndented).toHaveBeenCalledWith(text, 2);
+ });
+
+ it("checks whether the step result is failed or not", function () {
+ prettyFormatter.handleStepResultEvent(event, callback);
+ expect(stepResult.isFailed).toHaveBeenCalled();
+ });
+
+ describe("when the step failed", function () {
+ var exception;
+
+ beforeEach(function () {
+ exception = createSpy("exception");
+ stepResult.isFailed.andReturn(true);
+ spyOnStub(stepResult, 'getFailureException').andReturn(exception);
+ });
+
+ it("gets the failure exception", function () {
+ prettyFormatter.handleStepResultEvent(event, callback);
+ expect(stepResult.getFailureException).toHaveBeenCalled();
+ });
+
+ it("logs the failure stack when there is one, indented by three levels", function () {
+ var stack = "failure stack";
+ var text = stack + "\n";
+ exception.stack = stack;
+ prettyFormatter.handleStepResultEvent(event, callback);
+ expect(prettyFormatter.logIndented).toHaveBeenCalledWith(text, 3);
+ });
+
+ it("logs the failure itself when there no stack, indented by three levels", function () {
+ exception = "exception text";
+ var text = exception + "\n";
+ stepResult.getFailureException.andReturn(exception);
+ prettyFormatter.handleStepResultEvent(event, callback);
+ expect(prettyFormatter.logIndented).toHaveBeenCalledWith(text, 3);
+ });
+ });
+
+ it("calls back", function () {
+ prettyFormatter.handleStepResultEvent(event, callback);
+ expect(callback).toHaveBeenCalled();
+ });
+ });
+
+ describe("handleAfterFeaturesEvent()", function () {
+ var event, callback, summary;
+
+ beforeEach(function () {
+ event = createSpy("event");
+ callback = createSpy("callback");
+ summary = createSpy("summary logs");
+ spyOnStub(summarizer, 'getLogs').andReturn(summary);
+ });
+
+ it("gets the summary from the summarizer", function () {
+ prettyFormatter.handleAfterFeaturesEvent(event, callback);
+ expect(summarizer.getLogs).toHaveBeenCalled();
+ });
+
+ it("logs the summary", function () {
+ prettyFormatter.handleAfterFeaturesEvent(event, callback);
+ expect(prettyFormatter.log).toHaveBeenCalledWith(summary);
+ });
+
+ it("calls back", function () {
+ prettyFormatter.handleAfterFeaturesEvent(event, callback);
+ expect(callback).toHaveBeenCalled();
+ });
+ });
+
+ describe("logIndented()", function () {
+ var text, level, indented;
+
+ beforeEach(function () {
+ text = createSpy("text");
+ level = createSpy("level");
+ indented = createSpy("indented text");
+ spyOn(prettyFormatter, 'indent').andReturn(indented);
+ });
+
+ it("indents the text", function () {
+ prettyFormatter.logIndented(text, level);
+ expect(prettyFormatter.indent).toHaveBeenCalledWith(text, level);
+ });
+
+ it("logs the indented text", function () {
+ prettyFormatter.logIndented(text, level);
+ expect(prettyFormatter.log).toHaveBeenCalledWith(indented);
+ });
+ });
+
+ describe("indent()", function () {
+ it("returns the original text on a 0-indentation level", function () {
+ var original = "cuke\njavascript";
+ var expected = original;
+ var actual = prettyFormatter.indent(original, 0);
+ expect(actual).toEqual(expected);
+ });
+
+ it("returns the 1-level indented text", function () {
+ var original = "cuke\njavascript";
+ var expected = " cuke\n javascript";
+ var actual = prettyFormatter.indent(original, 1);
+ expect(actual).toEqual(expected);
+ });
+
+ it("returns the 2-level indented text", function () {
+ var original = "cuke\njavascript";
+ var expected = " cuke\n javascript";
+ var actual = prettyFormatter.indent(original, 2);
+ expect(actual).toEqual(expected);
+ });
+
+ it("returns the 3-level indented text", function () {
+ var original = "cuke\njavascript";
+ var expected = " cuke\n javascript";
+ var actual = prettyFormatter.indent(original, 3);
+ expect(actual).toEqual(expected);
+ });
+ });
+});
View
144 spec/cucumber/listener/progress_formatter_spec.js
@@ -2,30 +2,29 @@ require('../../support/spec_helper');
describe("Cucumber.Listener.ProgressFormatter", function () {
var Cucumber = requireLib('cucumber');
- var listener, listenerHearMethod, summaryLogger, progressFormatter;
+ var formatter, formatterHearMethod, summarizer, progressFormatter, options;
beforeEach(function () {
- var ProgressFormatter = Cucumber.Listener.ProgressFormatter;
- listener = createSpy("listener");
- listenerHearMethod = spyOnStub(listener, 'hear');
- summaryLogger = createSpy("summary logger");
- spyOn(Cucumber, 'Listener').andReturn(listener);
- spyOnStub(Cucumber.Listener, 'SummaryLogger').andReturn(summaryLogger);
- Cucumber.Listener.ProgressFormatter = ProgressFormatter;
- progressFormatter = Cucumber.Listener.ProgressFormatter();
+ options = createSpy(options);
+ formatter = createSpyWithStubs("formatter", {log: null});
+ formatterHearMethod = spyOnStub(formatter, 'hear');
+ summarizer = createSpy("summarizer");
+ spyOn(Cucumber.Listener, 'Formatter').andReturn(formatter);
+ spyOn(Cucumber.Listener, 'Summarizer').andReturn(summarizer);
+ progressFormatter = Cucumber.Listener.ProgressFormatter(options);
});
describe("constructor", function () {
- it("creates a listener", function() {
- expect(Cucumber.Listener).toHaveBeenCalled();
+ it("creates a formatter", function() {
+ expect(Cucumber.Listener.Formatter).toHaveBeenCalledWith(options);
});
- it("extends the listener", function () {
- expect(progressFormatter).toBe(listener);
+ it("extends the formatter", function () {
+ expect(progressFormatter).toBe(formatter);
});
- it("creates a summary logger", function () {
- expect(Cucumber.Listener.SummaryLogger).toHaveBeenCalled();
+ it("creates a summarizer", function () {
+ expect(Cucumber.Listener.Summarizer).toHaveBeenCalled();
});
});
@@ -35,105 +34,31 @@ describe("Cucumber.Listener.ProgressFormatter", function () {
beforeEach(function () {
event = createSpy("event");
callback = createSpy("callback");
- spyOnStub(summaryLogger, 'hear');
+ spyOnStub(summarizer, 'hear');
});
- it("tells the summary logger to listen to the event", function () {
+ it("tells the summarizer to listen to the event", function () {
progressFormatter.hear(event, callback);
- expect(summaryLogger.hear).toHaveBeenCalled();
- expect(summaryLogger.hear).toHaveBeenCalledWithValueAsNthParameter(event, 1);
- expect(summaryLogger.hear).toHaveBeenCalledWithAFunctionAsNthParameter(2);
+ expect(summarizer.hear).toHaveBeenCalled();
+ expect(summarizer.hear).toHaveBeenCalledWithValueAsNthParameter(event, 1);
+ expect(summarizer.hear).toHaveBeenCalledWithAFunctionAsNthParameter(2);
});
- describe("summary logger callback", function () {
- var summaryLoggerCallback;
+ describe("summarizer callback", function () {
+ var summarizerCallback;
beforeEach(function () {
progressFormatter.hear(event, callback);
- summaryLoggerCallback = summaryLogger.hear.mostRecentCall.args[1];
+ summarizerCallback = summarizer.hear.mostRecentCall.args[1];
});
- it("tells the listener to listen to the event", function () {
- summaryLoggerCallback();
- expect(listenerHearMethod).toHaveBeenCalledWith(event, callback);
+ it("tells the formatter to listen to the event", function () {
+ summarizerCallback();
+ expect(formatterHearMethod).toHaveBeenCalledWith(event, callback);
});
});
});
- describe("log()", function () {
- var logged, alsoLogged, loggedBuffer;
-
- beforeEach(function () {
- logged = "this was logged";
- alsoLogged = "this was also logged";
- loggedBuffer = logged + alsoLogged;
- spyOn(process.stdout, 'write');
- });
-
- it("records logged strings", function () {
- progressFormatter.log(logged);
- progressFormatter.log(alsoLogged);
- expect(progressFormatter.getLogs()).toBe(loggedBuffer);
- });
-
- it("outputs the logged string to STDOUT by default", function () {
- progressFormatter.log(logged);
- expect(process.stdout.write).toHaveBeenCalledWith(logged);
- });
-
- describe("when asked to output to STDOUT", function () {
- beforeEach(function () {
- progressFormatter = Cucumber.Listener.ProgressFormatter({logToConsole: true});
- });
-
- it("outputs the logged string to STDOUT", function () {
- progressFormatter.log(logged);
- expect(process.stdout.write).toHaveBeenCalledWith(logged);
- });
- });
-
- describe("when asked to not output to STDOUT", function () {
- beforeEach(function () {
- progressFormatter = Cucumber.Listener.ProgressFormatter({logToConsole: false});
- });
-
- it("does not output anything to STDOUT", function () {
- progressFormatter.log(logged);
- expect(process.stdout.write).not.toHaveBeenCalledWith(logged);
- });
- });
-
- describe("when asked to output to a function", function () {
- var userFunction;
-
- beforeEach(function () {
- userFunction = createSpy("output user function");
- progressFormatter = Cucumber.Listener.ProgressFormatter({logToFunction: userFunction});
- });
-
- it("calls the function with the logged string", function () {
- progressFormatter.log(logged);
- expect(userFunction).toHaveBeenCalledWith(logged);
- });
- });
- });
-
- describe("getLogs()", function () {
- it("returns the logged buffer", function () {
- var logged = "this was logged";
- var alsoLogged = "this was also logged";
- var loggedBuffer = logged + alsoLogged;
- spyOn(process.stdout, 'write'); // prevent actual output during spec execution
- progressFormatter.log(logged);
- progressFormatter.log(alsoLogged);
- expect(progressFormatter.getLogs()).toBe(loggedBuffer);
- });
-
- it("returns an empty string when the progress formatter did not log anything yet", function () {
- expect(progressFormatter.getLogs()).toBe("");
- });
- });
-
describe("handleStepResultEvent()", function () {
var event, callback, stepResult;
@@ -283,10 +208,6 @@ describe("Cucumber.Listener.ProgressFormatter", function () {
});
describe("handleSuccessfulStepResult()", function () {
- beforeEach(function () {
- spyOn(progressFormatter, 'log');
- });
-
it("logs the passing step character", function () {
progressFormatter.handleSuccessfulStepResult();
expect(progressFormatter.log).toHaveBeenCalledWith(Cucumber.Listener.ProgressFormatter.PASSED_STEP_CHARACTER);
@@ -294,10 +215,6 @@ describe("Cucumber.Listener.ProgressFormatter", function () {
});
describe("handlePendingStepResult()", function () {
- beforeEach(function () {
- spyOn(progressFormatter, 'log')
- });
-
it("logs the pending step character", function () {
progressFormatter.handlePendingStepResult();
expect(progressFormatter.log).toHaveBeenCalledWith(Cucumber.Listener.ProgressFormatter.PENDING_STEP_CHARACTER);
@@ -305,10 +222,6 @@ describe("Cucumber.Listener.ProgressFormatter", function () {
});
describe("handleSkippedStepResult()", function () {
- beforeEach(function () {
- spyOn(progressFormatter, 'log');
- });
-
it("logs the skipped step character", function () {
progressFormatter.handleSkippedStepResult();
expect(progressFormatter.log).toHaveBeenCalledWith(Cucumber.Listener.ProgressFormatter.SKIPPED_STEP_CHARACTER);
@@ -320,7 +233,6 @@ describe("Cucumber.Listener.ProgressFormatter", function () {
beforeEach(function () {
step = createSpy("step");
- spyOn(progressFormatter, 'log');
});
it("logs the undefined step character", function () {
@@ -334,7 +246,6 @@ describe("Cucumber.Listener.ProgressFormatter", function () {
beforeEach(function () {
stepResult = createSpy("failed step result");
- spyOn(progressFormatter, 'log');
});
it("logs the failed step character", function () {
@@ -350,13 +261,12 @@ describe("Cucumber.Listener.ProgressFormatter", function () {
event = createSpy("event");
callback = createSpy("callback");
summaryLogs = createSpy("summary logs");
- spyOnStub(summaryLogger, 'getLogs').andReturn(summaryLogs);
- spyOn(progressFormatter, 'log');
+ spyOnStub(summarizer, 'getLogs').andReturn(summaryLogs);
});
it("gets the summary", function () {
progressFormatter.handleAfterFeaturesEvent(event, callback);
- expect(summaryLogger.getLogs).toHaveBeenCalled();
+ expect(summarizer.getLogs).toHaveBeenCalled();
});
it("logs the summary", function () {
View
424 spec/cucumber/listener/summary_logger_spec.js
@@ -1,11 +1,11 @@
require('../../support/spec_helper');
-describe("Cucumber.Listener.SummaryLogger", function () {
+describe("Cucumber.Listener.Summarizer", function () {
var Cucumber = requireLib('cucumber');
- var listener, listenerHearMethod, summaryLogger, statsJournal, failedStepResults;
+ var listener, listenerHearMethod, summarizer, statsJournal, failedStepResults;
beforeEach(function () {
- var SummaryLogger = Cucumber.Listener.SummaryLogger;
+ var Summarizer = Cucumber.Listener.Summarizer;
listener = createSpyWithStubs("listener");
listenerHearMethod = spyOnStub(listener, 'hear');
statsJournal = createSpy(