Permalink
Browse files

Cucumber features runner complete; no scenario outlines

  • Loading branch information...
pacovell committed Oct 3, 2011
1 parent 7f57fa2 commit 16c293eb1892620d05744bcc135af4337136c4db
Showing with 240 additions and 127 deletions.
  1. +72 −127 bin/kyuri
  2. +8 −0 examples/step_definitions/calculator.js
  3. +18 −0 examples/support/env.js
  4. +1 −0 lib/kyuri.js
  5. +141 −0 lib/kyuri/runners/cucumber.js
View
199 bin/kyuri
@@ -5,22 +5,9 @@ var path = require('path'),
fs = require('fs'),
events = require('events');
-//
-// Attempt to load Coffee-Script. If it's not available, continue on our
-// merry way, if it is available, set it up so we can include `*.coffee`
-// scripts and start searching for them.
-//
-var fileExt, specFileExt;
-
-try {
- var coffee = require('coffee-script');
- require.registerExtension('.coffee', function (content) { return coffee.compile(content) });
- stepExt = /\.(js|coffee)$/;
-} catch (_) {
- fileExt = /\.js$/;
-}
-
featureFileExt = /\.(feature)$/;
+stepsDirs = ['steps', 'step_definitions'];
+envDirs = ['support'];
var inspect = require('eyes').inspector({
stream: null,
@@ -32,125 +19,83 @@ require.paths.unshift(path.join(__dirname, '..', 'lib'));
var kyuri = require('kyuri');
var help = [
- "usage: kyuri [FILE, ...] [options]",
- "",
- "options:",
- // Options compliant from 'cucumber --help'
- " --i18n LANG List keywords for in a particular language",
- " Run with \"--i18n help\" to see all languages",
- " -h, --help You're staring at it",
-
- // Options specific to Kyuri
- " --server Run the Kyuri web service. Default to port 9000",
- " --port Port to run server on",
-
+ "usage: kyuri [FILE, ...]"
].join('\n');
-/* Lets be compliant with Cucumber since this is essentially a pure javascript runner + some javascript options foo?
- (i.e. lets generate .coffee vs. .js step definitions :])
-
+var root = process.cwd();
- -r, --require LIBRARY|DIR Require files before executing the features. If this
- option is not specified, all *.rb files that are
- siblings or below the features will be loaded auto-
- matically. Automatic loading is disabled when this
- option is specified, and all loading becomes explicit.
- Files under directories named "support" are always
- loaded first.
- This option can be specified multiple times.
- --i18n LANG List keywords for in a particular language
- Run with "--i18n help" to see all languages
- -f, --format FORMAT How to format features (Default: pretty). Available formats:
- debug : For developing formatters - prints the calls made to the listeners.
- html : Generates a nice looking HTML report.
- json : Prints the feature as JSON
- json_pretty : Prints the feature as pretty JSON
- junit : Generates a report similar to Ant+JUnit.
- pdf : Generates a PDF report. You need to have the
- prawn gem installed. Will pick up logo from
- features/support/logo.png or
- features/support/logo.jpg if present.
- pretty : Prints the feature as is - in colours.
- progress : Prints one character per scenario.
- rerun : Prints failing files with line numbers.
- stepdefs : Prints All step definitions with their locations. Same as
- the usage formatter, except that steps are not printed.
- tag_cloud : Prints a tag cloud of tag usage.
- usage : Prints where step definitions are used.
- The slowest step definitions (with duration) are
- listed first. If --dry-run is used the duration
- is not shown, and step definitions are sorted by
- filename instead.
- Use --format rerun --out features.txt to write out failing
- features. You can rerun them with cucumber @rerun.txt.
- FORMAT can also be the fully qualified class name of
- your own custom formatter. If the class isn't loaded,
- Cucumber will attempt to require a file with a relative
- file name that is the underscore name of the class name.
- Example: --format Foo::BarZap -> Cucumber will look for
- foo/bar_zap.rb. You can place the file with this relative
- path underneath your features/support directory or anywhere
- on Ruby's LOAD_PATH, for example in a Ruby gem.
- -o, --out [FILE|DIR] Write output to a file/directory instead of STDOUT. This option
- applies to the previously specified --format, or the
- default format if no format is specified. Check the specific
- formatter's docs to see whether to pass a file or a dir.
- -t, --tags TAG_EXPRESSION Only execute the features or scenarios with tags matching TAG_EXPRESSION.
- Scenarios inherit tags declared on the Feature level. The simplest
- TAG_EXPRESSION is simply a tag. Example: --tags @dev. When a tag in a tag
- expression starts with a ~, this represents boolean NOT. Example: --tags ~@dev.
- A tag expression can have several tags separated by a comma, which represents
- logical OR. Example: --tags @dev,@wip. The --tags option can be specified
- several times, and this represents logical AND. Example: --tags @foo,~@bar --tags @zap.
- This represents the boolean expression (@foo || !@bar) && @zap.
-
- Beware that if you want to use several negative tags to exclude several tags
- you have to use logical AND: --tags ~@fixme --tags @buggy.
-
- Positive tags can be given a threshold to limit the number of occurrences.
- Example: --tags @qa:3 will fail if there are more than 3 occurrences of the @qa tag.
- This can be practical if you are practicing Kanban or CONWIP.
- -n, --name NAME Only execute the feature elements which match part of the given name.
- If this option is given more than once, it will match against all the
- given names.
- -e, --exclude PATTERN Don't run feature files or require ruby files matching PATTERN
- -p, --profile PROFILE Pull commandline arguments from cucumber.yml which can be defined as
- strings or arrays. When a 'default' profile is defined and no profile
- is specified it is always used. (Unless disabled, see -P below.)
- When feature files are defined in a profile and on the command line
- then only the ones from the command line are used.
- -P, --no-profile Disables all profile loading to avoid using the 'default' profile.
- -c, --[no-]color Whether or not to use ANSI color in the output. Cucumber decides
- based on your platform and the output destination if not specified.
- -d, --dry-run Invokes formatters without executing the steps.
- This also omits the loading of your support/env.rb file if it exists.
- Implies --no-snippets.
- -a, --autoformat DIR Reformats (pretty prints) feature files and write them to DIRECTORY.
- Be careful if you choose to overwrite the originals.
- Implies --dry-run --formatter pretty.
- -m, --no-multiline Don't print multiline strings and tables under steps.
- -s, --no-source Don't print the file and line of the step definition with the steps.
- -i, --no-snippets Don't print snippets for pending steps.
- -q, --quiet Alias for --no-snippets --no-source.
- -b, --backtrace Show full backtrace for all errors.
- -S, --strict Fail if there are any undefined steps.
- -w, --wip Fail if there are any passing scenarios.
- -v, --verbose Show the files and features loaded.
- -g, --guess Guess best match for Ambiguous steps.
- -x, --expand Expand Scenario Outline Tables in output.
- --drb Run features against a DRb server. (i.e. with the spork gem)
- --port PORT Specify DRb port. Ignored without --drb
- --version Show version.
- -h, --help You're looking at it.
-
+/**
+ Load .js files found in the directory or subdirectories of the feature files,
+ adding exports to the steps array (if any).
*/
+var _loadJavascripts = function (directory, steps) {
+ if (!directory.match(/^\//)) {
+ directory = path.join(root, directory);
+ }
+
+ if(path.existsSync(directory)) {
+ var files = fs.readdirSync(directory);
+ files.forEach(function (file) {
+ var fullPath = path.join(directory, file),
+ stats = fs.statSync(fullPath),
+ exported;
+
+ if (stats.isDirectory()) {
+ _loadJavascripts(fullPath, steps);
+ } else {
+ if (file.match(/\.js$/)) {
+ // Add root to all relative paths
+ if (!fullPath.match(/^\//)) {
+ fullPath = path.join(root, fullPath);
+ }
+ console.log('Loaded ' + fullPath);
+ exported = require(fullPath);
+ if (exported && exported.forEach && steps) {
+ exported.forEach(function (obj) {
+ steps.push(obj); // Pass-by-reference array must be modified in place
+ })
+ }
+ }
+ }
+ });
+ }
+};
// Get rid of process runner
// ('node' in most cases)
var arg, args = [], argv = process.argv.slice(2);
-// Current directory index,
-// and path of test folder.
-var root, testFolder;
+kyuri.runner = kyuri.runners.cucumber;
+
+var features = [];
+var steps = [];
+argv.forEach(function (file) {
+ if (file.match(featureFileExt)) {
+ // Load envDirs first and without steps
+ envDirs.forEach(function (dir) {
+ _loadJavascripts(path.join(path.dirname(file), dir));
+ });
+ // Load steps
+ stepsDirs.forEach(function (dir) {
+ _loadJavascripts(path.join(path.dirname(file), dir), steps);
+ });
+ features.push(kyuri.parse(fs.readFileSync(file).toString()));
+ }
+});
+
+var complete = false;
+
+kyuri.runners.cucumber.run(features, steps, function (err) {
+ if (err) {
+ console.log('Errors');
+ console.log(err);
+ }
+ complete = true;
+});
-sys.puts('Kyuri test runner not currently complete in 0.2.0. In the roadmap for 0.2.1');
+var _waitComplete = function () {
+ if (!complete) {
+ process.nextTick(_waitComplete);
+ }
+};
+_waitComplete();
@@ -0,0 +1,8 @@
+var Steps = require('kyuri').Steps;
+
+Steps.Given(/^I have entered (\d+) into the calculator$/, function (step, num) {
+ console.log('Calculator: ' + num);
+ step.done();
+});
+
+Steps.export(module);
View
@@ -0,0 +1,18 @@
+/*
+ * Set up environmental configuration here, for example database events and functions
+ *
+ * (C) 2011 Paul Covell (paul@done.com)
+ * MIT LICENSE
+ *
+ */
+var Runner = require('kyuri').runner;
+
+Runner.on('beforeTest', function (done) {
+ console.log('beforeTest event');
+ done();
+});
+
+Runner.on('afterTest', function (done) {
+ console.log('afterTest event');
+ done();
+});
View
@@ -27,6 +27,7 @@ kyuri.Steps = require('kyuri/steps');
//
kyuri.runners = {};
kyuri.runners.vows = require('kyuri/runners/vows');
+kyuri.runners.cucumber = require('kyuri/runners/cucumber');
//
// Remark we should probably export the runner methods
Oops, something went wrong.

0 comments on commit 16c293e

Please sign in to comment.