Skip to content

Commit

Permalink
Merge pull request #22 from telefonicaid/feature/programmatically#21
Browse files Browse the repository at this point in the history
Allow using Tartare programmatically and implement Tartare keywords as a Mocha interface
  • Loading branch information
JoseAntonioRodriguez committed Jan 4, 2015
2 parents d262d7b + 2d09b0d commit be6cb02
Show file tree
Hide file tree
Showing 14 changed files with 1,003 additions and 910 deletions.
39 changes: 39 additions & 0 deletions ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,45 @@

## v0.7.0 / XXX

### Gherkin framework and reporter
* From now on, Tartare can be used programmatically, instantiating a Tartare object, and gaining control over the
tests execution.
You can pass an object to the Tartare constructor with the following options:
- `reporter`: Choose between the console reporter (`gherkin`) or the markdown reporter (`gherkin-md`). Default: `gherkin`.
- `timeout`: Set test timeout in milliseconds. Default: `10000`.
- `filter`: Run only tests matching the filter.
- `bail`: Stop executing tests on the first failure: Default: `true`.
- `useColors`: Set whether colors can be used on console reporters. Default: `true`.
- `enableTimeouts`: Enable timeouts. Default: `true`.
- Any other options will be available through the `getTartareOptions` function.

You can access to the underlying Mocha object through `tartare.mocha`.


```javascript
var Tartare = require('tartare');

// First, instantiate a Tartare instance.
var tartare = new Tartare({
timeout: 5000,
filter: 'some_tag'
});

// Then, add the test files using the "addFiles" method.
tartare.addFiles([file1, file2, ...]);

// Finally, run the tests!
tartare.run(function(failures) {
process.exit(failures);
});
```

* The CLI program now supports new arguments. See `tartare -h` for more info.
* A new `but` step has been added.
* Test execution stops after the first failure as a default behaviour that can be changed passing `bail: false` to the
Tartare constructor, or `--no-bail` to the CLI program.
* `getTartareOptions` and `synchronize` are now global functions, so you can call them without the `tartare.` prefix.

### API Mock

* `lastrequests` resource now include a timestamp for each received request and the list of last request is ordered
Expand Down
140 changes: 96 additions & 44 deletions bin/tartare
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@

'use strict';

require('../lib/utils');
var fs = require('fs')
, spawn = require('child_process').spawn
var Tartare = require('..')
, fs = require('fs')
, path = require('path')
;


Expand All @@ -35,13 +35,20 @@ var supportedReporters = {
};

function _printHelp() {
console.log('\n Usage: tartere [options] [files]');
console.log('\n Usage: tartare [options] [files]');
console.log('\n Options:\n');
console.log(' -h, --help output usage information');
console.log(' -V, --version output the version number');
console.log(' -r, --require require the given module');
console.log(' -R, --reporter <name> specify the reporter to use [gherkin]');
console.log(' -t, --timeout <ms> set test timeout in milliseconds [10000]');
console.log(' -f, --filter <filter_str> run only tests matching <filter_str>');
console.log(' -c, --colors force enabling of colors');
console.log(' -C, --no-colors force disabling of colors');
console.log(' -B, --no-bail prevent from bailing after first step failure');
console.log(' --no-exit require a clean shutdown of the event loop: Tartare will not call process.exit');
console.log(' --no-timeouts disables timeouts');
console.log(' --recursive include sub directories');
console.log(' --reporters display available reporters');
console.log();
console.log(' Filter syntax:');
Expand Down Expand Up @@ -72,7 +79,10 @@ function _printReporters() {
}

var opts = {};
var unrecognizedArgs = [];
var requires = [];
var files = [];
var recursive = false;
var noExit = false;

for (var i = 2; i < process.argv.length; i++) {
switch (process.argv[i]) {
Expand All @@ -87,11 +97,15 @@ for (var i = 2; i < process.argv.length; i++) {
case '--reporters':
_printReporters();
break;
case '-r':
case '--require':
requires.push(process.argv[++i]);
break;
case '-R':
case '--reporter':
opts.reporter = process.argv[++i];
if (!supportedReporters[opts.reporter]) {
console.log('\nUnsupported reporter "' + opts.reporter + '". Valid reporters are: ' +
console.error('\nUnsupported reporter "' + opts.reporter + '". Valid reporters are: ' +
Object.keys(supportedReporters).join(', ') + '\n');
process.exit(-1);
}
Expand All @@ -103,66 +117,104 @@ for (var i = 2; i < process.argv.length; i++) {
case '-f':
case '--filter':
opts.filter = process.argv[++i];
if (!/^[A-Za-z0-9_ ,\-\+&\|\(\)]+$/.test(opts.filter)) {
console.log('\nInvalid filter parameter "' + opts.filter + '". See tartare -h for more info.\n' );
if (!/^[A-Za-z0-9_ ,+&|()-]+$/.test(opts.filter)) {
console.error('\nInvalid filter parameter "' + opts.filter + '". See tartare -h for more info.\n' );
process.exit(-1);
}
break;
case '-g':
case '--grep':
opts.grep = process.argv[++i];
case '-c':
case '--colors':
opts.useColors = true;
break;
case '-C':
case '--no-colors':
opts.useColors = false;
break;
case '-B':
case '--no-bail':
opts.bail = false;
break;
case '--no-exit':
noExit = true;
break;
case '--no-timeouts':
opts.enableTimeouts = false;
break;
case '--recursive':
recursive = true;
break;

case '-i':
case '--invert':
opts.invert = true;
break;
case '--interfaces':
// Discard this argument to avoid being passed in to Mocha
// Discard these arguments to avoid being passed in to Mocha
break;
case '-u':
case '--ui':
// Discard this argument to avoid being passed in to Mocha
// If the argument has a value, discard it too
case '-g':
case '--grep':
// Discard these arguments to avoid being passed in to Mocha
// If the arguments have a value, discard it too
if (!process.argv[i + 1].startsWith('-')) {
i++;
}
break;

default:
unrecognizedArgs.push(process.argv[i]);
if (process.argv[i].startsWith('-')) {
// Other arguments that look like options are added to Tartare options
// to make them available through the function `getTartareOptions`.
// This kind of arguments must always have a value.
var optName = process.argv[i].replace(/^--?/, ''); // Remove leading hyphens
var optValue = process.argv[++i];
if (optValue === undefined) {
console.error('Argument "' + optName + '" must have a value');
process.exit(-1);
}
// Convert optName to its lowerCamelCase form
optName = optName.split('-').map(function(token, index) {
if (index > 0) {
return token.slice(0, 1).toUpperCase() + token.slice(1).toLowerCase();
}
return token.toLowerCase();
}).join('');
opts[optName] = optValue;
} else {
// The argument is a test file
files.push(process.argv[i]);
}
}
}

opts.reporter = opts.reporter || 'gherkin';
opts.timeout = opts.timeout || '10000';

// Require modules passed in through the -r, --require option
module.paths.push(process.cwd(), path.join(process.cwd(), 'node_modules'));
requires.forEach(function(mod) {
require(mod);
});

/*
Call Mocha passing needed arguments
*/
// Expand and resolve the list of test files
var files_ = [];
var lookupFiles = require('mocha/lib/utils').lookupFiles;
files.forEach(function(file){
files_ = files_.concat(lookupFiles(file, ['js'], recursive));
});
files_ = files_.map(function(path_){
return path.resolve(path_);
});

var args = [ __dirname + '/../node_modules/mocha/bin/mocha' ];
args = args.concat('--require', __dirname + '/../lib/mocha-gherkin/mocha-gherkin.js');
args = args.concat('--reporter', __dirname + '/../lib/mocha-gherkin/reporters/' + opts.reporter);
args = args.concat('--ui', 'bdd');
args = args.concat('--timeout', opts.timeout);
if (opts.filter) {
// The filter string is convoyed into a RegExp object, due to how Mocha works
args = args.concat('--grep', 'tartare: ' + RegExp.escape(opts.filter));
} else if (opts.grep) {
args = args.concat('--grep', opts.grep);
if (opts.invert) {
args = args.concat('--invert');
}
}
args = args.concat(unrecognizedArgs);
// Load Tartare
var tartare = new Tartare(opts);
tartare.addFiles(files_);

var child = spawn(process.argv[0], args, { stdio: 'inherit' });
child.on('exit', function (code, signal) {
// Run Tartare
var runner = tartare.run(noExit ? exitLater : process.exit);
function exitLater(code) {
process.on('exit', function() {
if (signal) {
process.kill(process.pid, signal);
} else {
process.exit(code);
}
process.exit(code)
});
}

process.on('SIGINT', function() {
runner.abort();
});
28 changes: 0 additions & 28 deletions gherkin-md.js

This file was deleted.

29 changes: 0 additions & 29 deletions gherkin.js

This file was deleted.

3 changes: 1 addition & 2 deletions lib/apimock/middlewares.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ var jsonschema = require('jsonschema')
, extend = require('node.extend')
, schemas = require('./json-schemas')
, xml2json = require('xml2json')
, utils = require('../utils')
;

/**
Expand All @@ -45,7 +44,7 @@ function _buildLocation(req, _id) {
if ((!req.secure && req.app.settings.port !== 80) || (req.secure && req.app.settings.port !== 443)) {
location += ':' + req.app.settings.port;
}
location += req.path.endsWith('/') ? req.path : req.path + '/';
location += req.path.slice(-1) === '/' ? req.path : req.path + '/';
location += _id;
return location;
}
Expand Down
Loading

0 comments on commit be6cb02

Please sign in to comment.