Comparing version 1.5.0 to 1.6.0
@@ -10,9 +10,14 @@ /** | ||
* Generate a random mongo objectId | ||
* @returns {string} | ||
* @returns {ObjectId} | ||
*/ | ||
module.exports.randomId = function () { | ||
return new ObjectID().toHexString() | ||
return new ObjectID() | ||
} | ||
/** | ||
* MongoId constructor | ||
*/ | ||
module.exports.ObjectId = module.exports.ObjectID = ObjectID | ||
/** | ||
* Generate a random string with base64 chars (A-Za-z0-9+/) | ||
@@ -62,4 +67,51 @@ * @param {number} [len=7] | ||
/** | ||
* Generate a random number | ||
* random() is the same as Math.random(): 0 <= x < 1 | ||
* random(N) returns a number 0 <= x < N | ||
* random(M, N) returns M <= x < N | ||
* @param {number} [min=0] | ||
* @param {number} [max=1] | ||
* @returns {number} | ||
*/ | ||
module.exports.random = function (min, max) { | ||
if (min === undefined && max === undefined) { | ||
return Math.random() | ||
} else if (max === undefined) { | ||
return Math.random() * min | ||
} else { | ||
return min + Math.random() * (max - min) | ||
} | ||
} | ||
/** | ||
* Generate a random int min <= x < max | ||
* randomInt() is equal to randomInt(0, 100) | ||
* randomInt(N) is equal to randomInt(0, N) | ||
* @param {number} [min=0] | ||
* @param {number} [max=100] | ||
* @returns {number} | ||
*/ | ||
module.exports.randomInt = function (min, max) { | ||
return Math.floor(module.exports.random(min, max)) | ||
} | ||
/** | ||
* @returns {boolean} | ||
*/ | ||
module.exports.randomBool = function () { | ||
return Math.random() < 0.5 | ||
} | ||
/** | ||
* Return one of its arguments | ||
* @param {...*} value | ||
* @returns {*} | ||
*/ | ||
module.exports.randomOf = function () { | ||
return arguments[Math.floor(Math.random() * arguments.length)] | ||
} | ||
/** | ||
* The empty object | ||
*/ | ||
module.exports.empty = {} |
@@ -59,2 +59,3 @@ 'use strict' | ||
}, function (err, res, out) { | ||
var expected | ||
if (err) { | ||
@@ -64,5 +65,19 @@ return done(err) | ||
options.context.out = out | ||
expected = that.out.execute(options.context, '<out>') | ||
res.statusCode.should.be.equal(that.statusCode) | ||
check(out, that.out.execute(options.context, '<out>'), options.strict) | ||
try { | ||
res.statusCode.should.be.equal(that.statusCode) | ||
check(out, expected, options.strict) | ||
} catch (e) { | ||
console.log('\n-----\n' + | ||
'Request details:\n' + | ||
'\x1b[1;32mInput:\x1b[0m\n' + | ||
JSON.stringify(post, null, ' ') + '\n' + | ||
'\x1b[1;32mOutput:\x1b[0m\n' + | ||
JSON.stringify(out, null, ' ') + '\n' + | ||
'\x1b[1;32mExpected:\x1b[0m\n' + | ||
JSON.stringify(expected, null, ' ') + '\n' + | ||
'-----\n') | ||
throw e | ||
} | ||
async.each(that.finds, function (find, done) { | ||
@@ -69,0 +84,0 @@ find.execute(options.context, options.db, done) |
@@ -22,11 +22,21 @@ 'use strict' | ||
var selector = flat(this.value.execute(context, '<find in ' + this.collection + '>')), | ||
that = this | ||
that = this, | ||
collection = db.collection(this.collection) | ||
db.collection(this.collection).findOne(selector, function (err, doc) { | ||
collection.findOne(selector, function (err, doc) { | ||
if (err) { | ||
return done(err) | ||
} else if (!doc) { | ||
return done(new Error('No document like ' + JSON.stringify(selector) + ' found in ' + that.collection)) | ||
collection.find().toArray(function (err, docs) { | ||
console.log('\n-----\n' + | ||
'\x1b[1;32mDocuments in ' + that.collection + ':\x1b[0m\n' + | ||
JSON.stringify(docs, null, ' ') + '\n' + | ||
'\x1b[1;32mFind query:\x1b[0m\n' + | ||
JSON.stringify(selector, null, ' ') + '\n' + | ||
'-----\n') | ||
return done(new Error('No document like ' + JSON.stringify(selector) + ' found in ' + that.collection)) | ||
}) | ||
} else { | ||
done() | ||
} | ||
done() | ||
}) | ||
@@ -33,0 +43,0 @@ } |
@@ -11,6 +11,12 @@ 'use strict' | ||
this.name = '' | ||
/** @member {boolean} */ | ||
this.skip = false | ||
/** @member {Array<Insertion|Clear|Declaration>} */ | ||
this.setups = [] | ||
/** @member {Case[]} */ | ||
this.cases = [] | ||
/** | ||
@@ -28,4 +34,5 @@ * A map with used collections and the element that has cleared it | ||
Test.prototype.execute = function (options) { | ||
var that = this | ||
options.describe(this.name, function () { | ||
var that = this, | ||
describe = this.skip ? options.describe.skip : options.describe | ||
describe(this.name, function () { | ||
// DB setup | ||
@@ -32,0 +39,0 @@ options.before(function (done) { |
35
index.js
@@ -15,9 +15,12 @@ /*globals describe, before, it*/ | ||
* @param {string} file The folder path | ||
* @param {object} options an object with optional keys: | ||
* - mongoUri | ||
* - describe, before, it (default: mocha globals) | ||
* - baseUrl | ||
* - context (default: {}) | ||
* - recursive (default: false) | ||
* - strict (default: true) | ||
* @param {Object} options an object with optional keys: | ||
* @param {string} options.mongoUri | ||
* @param {string} options.baseUrl | ||
* @param {boolean} [options.recursive=false] | ||
* @param {boolean} [options.strict=true] | ||
* @param {Object} [options.context] | ||
* @param {function(Array<Header|Obj>)} [options.preParse] | ||
* @param {Function} [options.describe] | ||
* @param {Function} [options.before] | ||
* @param {Function} [options.it] | ||
*/ | ||
@@ -35,2 +38,3 @@ module.exports = function (folder, options) { | ||
options.strict = options.strict === undefined ? true : options.strict | ||
options.preParse = options.preParse || function () {} | ||
@@ -52,3 +56,3 @@ options.describe('api', function () { | ||
if (file.substr(-3) === '.md') { | ||
parse(fs.readFileSync(file, 'utf8')).execute(options) | ||
parse(fs.readFileSync(file, 'utf8'), options.preParse).execute(options) | ||
} | ||
@@ -60,2 +64,17 @@ }) | ||
/** | ||
* @class | ||
*/ | ||
module.exports.Header = require('./classes/Header') | ||
/** | ||
* @class | ||
*/ | ||
module.exports.Obj = require('./classes/Obj') | ||
/** | ||
* @class | ||
*/ | ||
module.exports.ParseError = require('./classes/ParseError') | ||
/** | ||
* Make sure the mongo uri has 'localhost' as hostname and 'test' in the DB name | ||
@@ -62,0 +81,0 @@ * @param {string} mongoUri |
{ | ||
"name": "api-test", | ||
"version": "1.5.0", | ||
"version": "1.6.0", | ||
"author": "Sitegui <sitegui@sitegui.com.br>", | ||
@@ -5,0 +5,0 @@ "description": "API testing made simple", |
14
parse.js
@@ -22,6 +22,7 @@ /** | ||
* @param {string} text | ||
* @param {function(Array<Header|Obj>)} preParse | ||
* @returns {Test} | ||
* @throws if the syntax is invalid | ||
*/ | ||
module.exports = function (text) { | ||
module.exports = function (text, preParse) { | ||
var originalLines, i, line, els, lastObj, test | ||
@@ -57,2 +58,3 @@ | ||
try { | ||
preParse(els) | ||
i = parseHeader(test, els, 0) | ||
@@ -83,3 +85,9 @@ i = parseSetups(test, els, i) | ||
} | ||
test.name = els[i].value | ||
if (/ \(skip\)$/.test(els[i].value)) { | ||
test.name = els[i].value.substr(0, els[i].value.length - 7).trimRight() | ||
test.skip = true | ||
} else { | ||
test.name = els[i].value | ||
test.skip = false | ||
} | ||
return i + 1 | ||
@@ -143,3 +151,3 @@ } | ||
if (checkHeader(els[i], 2)) { | ||
if (i >= els.length || checkHeader(els[i], 2)) { | ||
// Out of setup section | ||
@@ -146,0 +154,0 @@ return 0 |
@@ -96,2 +96,4 @@ # API Test | ||
You can also append ` (skip)` to a test file header (see an [example](https://github.com/clubedaentrega/api-test/blob/master/test/api-test/recursive/skip.md)) to skip the whole file. | ||
## Object syntax | ||
@@ -124,2 +126,3 @@ The syntax was designed to be concise and expressive. The values will be eval'ed as normal JS with a context with special variables (see `default context` bellow). | ||
* `ObjectId()`: the mongo object id constructor | ||
* `randomId()`: return a random mongo-id as a 24-hex-char string | ||
@@ -130,2 +133,6 @@ * `randomStr([len=7], [alphabet=a-zA-Z0-9+/])` | ||
* `randomEmail([domain='example.com'])` | ||
* `random([min=0],[max=1])` | ||
* `randomInt([min=0],[max=100])` | ||
* `randomBool()` | ||
* `randomOf(...values)`: return one of its arguments | ||
* `empty`: the empty object `{}` | ||
@@ -145,2 +152,3 @@ * `post`: the request body of the current test case | ||
* `strict`: (optional) whether the output check should be strict and complain about unexpected keys (default: true) | ||
* `preParse`: (optional) a function that will be called with all pre-parsed tokens (Header and Obj). This lets you do crazy stuff with the parsing if you want | ||
@@ -147,0 +155,0 @@ ## Type checking |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
56617
29
1656
210