Comparing version 1.9.0 to 2.0.0
18
check.js
'use strict' | ||
var should = require('should'), | ||
types = [String, Number, Boolean, Object, Array] | ||
ObjectID = require('mongodb').ObjectID, | ||
types = [String, Number, Boolean, Object, Array, Date, RegExp, ObjectID] | ||
@@ -10,4 +11,6 @@ /** | ||
* @param {boolean} strict | ||
* @param {string[]} [ignoredKeys=[]] only used if strict is true | ||
* @throws if invalid | ||
*/ | ||
module.exports = function (actual, expected, strict) { | ||
module.exports = function (actual, expected, strict, ignoredKeys) { | ||
var key | ||
@@ -17,3 +20,3 @@ | ||
// Simple type check | ||
should(actual).be.a[expected.name] | ||
should(actual).be.instanceof(expected) | ||
} else if (Array.isArray(expected)) { | ||
@@ -28,3 +31,3 @@ // Check every array element | ||
expected.forEach(function (each, i) { | ||
module.exports(actual[i], each, strict) | ||
module.exports(actual[i], each, strict, ignoredKeys) | ||
}) | ||
@@ -38,7 +41,10 @@ } else if (expected && | ||
should(actual).have.property(key) | ||
module.exports(actual[key], expected[key], strict) | ||
module.exports(actual[key], expected[key], strict, ignoredKeys) | ||
} | ||
if (strict) { | ||
ignoredKeys = ignoredKeys || [] | ||
for (key in actual) { | ||
should(expected).have.property(key) | ||
if (ignoredKeys.indexOf(key) === -1) { | ||
should(expected).have.property(key) | ||
} | ||
} | ||
@@ -45,0 +51,0 @@ } |
@@ -36,4 +36,10 @@ 'use strict' | ||
* Run the test case | ||
* @param {Object} options an object with keys db, it, url, context, strict | ||
* @param {string} testName | ||
* @param {Object} options | ||
* @param {Obejct} options.db | ||
* @param {Function} options.it | ||
* @param {string} options.baseUrl | ||
* @param {Object} options.context | ||
* @param {boolean} options.strict | ||
* @param {string} options.testName | ||
* @param {string[]} options.ignoredFindKeys | ||
*/ | ||
@@ -84,3 +90,3 @@ Case.prototype.execute = function (options, testName) { | ||
async.each(that.finds, function (find, done) { | ||
find.execute(options.context, options.db, done) | ||
find.execute(options, done) | ||
}, done) | ||
@@ -87,0 +93,0 @@ }) |
'use strict' | ||
var stringify = require('../stringify') | ||
var stringify = require('../stringify'), | ||
ObjectID = require('mongodb').ObjectID, | ||
check = require('../check') | ||
@@ -18,105 +20,44 @@ /** | ||
/** | ||
* @param {Object} context | ||
* @param {Object} db | ||
* @param {Object} options | ||
* @param {Object} options.db | ||
* @param {Object} options.context | ||
* @param {boolean} options.strict | ||
* @param {string[]} options.ignoredFindKeys | ||
* @param {Function} done | ||
*/ | ||
Find.prototype.execute = function (context, db, done) { | ||
var selector = flat(this.value.execute(context, '<find in ' + this.collection + '>')), | ||
Find.prototype.execute = function (options, done) { | ||
var target = this.value.execute(options.context, '<find in ' + this.collection + '>'), | ||
that = this, | ||
collection = db.collection(this.collection) | ||
collection = options.db.collection(this.collection) | ||
collection.findOne(selector, function (err, doc) { | ||
collection.find().toArray(function (err, docs) { | ||
var found | ||
if (err) { | ||
return done(err) | ||
} else if (!doc) { | ||
collection.find().toArray(function (err, docs) { | ||
console.log('\n-----\n' + | ||
'\x1b[1;32mDocuments in ' + that.collection + ':\x1b[0m\n' + | ||
stringify(docs, true) + '\n' + | ||
'\x1b[1;32mFind query:\x1b[0m\n' + | ||
stringify(selector, true) + '\n' + | ||
'-----\n') | ||
return done(new Error('No document like ' + JSON.stringify(selector) + ' found in ' + that.collection)) | ||
}) | ||
} else { | ||
done() | ||
} | ||
}) | ||
} | ||
/** | ||
* Make a value flat, so that mongo ignore subdoc key order | ||
* {a: {b: 2}} -> {'a.b': 2} | ||
* @param {Object} value | ||
* @returns {Object} | ||
* @private | ||
*/ | ||
function flat(value) { | ||
var r = Object.create(null), | ||
flatValue = function (value, prefix) { | ||
var t1, t16, t18 | ||
found = docs.some(function (doc) { | ||
try { | ||
check(doc, target, options.strict, options.ignoredFindKeys) | ||
return true | ||
} catch (e) { | ||
return false | ||
} | ||
}) | ||
if (Array.isArray(value)) { | ||
// Subarray | ||
value.forEach(function (each, i) { | ||
flatValue(each, prefix + i + '.') | ||
}) | ||
} else if (value && | ||
typeof value === 'object' && | ||
(value.constructor === Object || Object.getPrototypeOf(value) === null)) { | ||
// Subdoc | ||
Object.keys(value).forEach(function (key) { | ||
flatValue(value[key], prefix + key + '.') | ||
}) | ||
} else if (value === Number) { | ||
// Since there are 3 BSON types for a number, we need a hack here | ||
// use $and with $or for each of those types | ||
if (!('$and' in r)) { | ||
r.$and = [] | ||
} | ||
prefix = prefix.substr(0, prefix.length - 1) | ||
t1 = {} | ||
t16 = {} | ||
t18 = {} | ||
t1[prefix] = { | ||
$type: 1 | ||
} | ||
t16[prefix] = { | ||
$type: 16 | ||
} | ||
t18[prefix] = { | ||
$type: 18 | ||
} | ||
r.$and.push({ | ||
$or: [t1, t16, t18] | ||
}) | ||
} else { | ||
// Simple value | ||
if (value === String) { | ||
value = { | ||
$type: 2 | ||
} | ||
} else if (value === Boolean) { | ||
value = { | ||
$type: 8 | ||
} | ||
} else if (value === Date) { | ||
value = { | ||
$type: 9 | ||
} | ||
} else if (value === RegExp) { | ||
value = { | ||
$type: 11 | ||
} | ||
} | ||
r[prefix.substr(0, prefix.length - 1)] = value | ||
} | ||
if (!found) { | ||
console.log('\n-----\n' + | ||
'\x1b[1;32mDocuments in ' + that.collection + ':\x1b[0m\n' + | ||
stringify(docs, true) + '\n' + | ||
'\x1b[1;32mTarget document:\x1b[0m\n' + | ||
stringify(target, true) + '\n' + | ||
'-----\n') | ||
return done(new Error('No document found in ' + that.collection)) | ||
} | ||
flatValue(value, '') | ||
return r | ||
done() | ||
}) | ||
} | ||
module.exports = Find |
@@ -30,3 +30,11 @@ 'use strict' | ||
* Run the test | ||
* @param {Object} options an object with keys db, describe, before, it, baseUrl, context, strict | ||
* @param {Object} options | ||
* @param {Object} options.db | ||
* @param {Function} options.describe | ||
* @param {Function} options.before | ||
* @param {Function} options.it | ||
* @param {string} options.baseUrl | ||
* @param {Object} options.context | ||
* @param {boolean} options.strict | ||
* @param {string[]} options.ignoredFindKeys | ||
*/ | ||
@@ -33,0 +41,0 @@ Test.prototype.execute = function (options) { |
@@ -21,2 +21,3 @@ /*globals describe, before, it*/ | ||
* @param {Object} [options.context] | ||
* @param {string[]} [options.ignoredFindKeys=['_id', '__v']] | ||
* @param {function(string):boolean} [options.filterFile] | ||
@@ -43,2 +44,3 @@ * @param {function(Array<Header|Obj>, Test)} [options.preParse] | ||
options.preParse = options.preParse || function () {} | ||
options.ignoredFindKeys = options.ignoredFindKeys || ['_id', '__v'] | ||
@@ -45,0 +47,0 @@ options.describe('api', function () { |
{ | ||
"name": "api-test", | ||
"version": "1.9.0", | ||
"version": "2.0.0", | ||
"author": "Sitegui <sitegui@sitegui.com.br>", | ||
@@ -5,0 +5,0 @@ "description": "API testing made simple", |
@@ -151,2 +151,3 @@ # API Test | ||
* `strict`: (optional) whether the output check should be strict and complain about unexpected keys (default: true) | ||
* `ignoredFindKeys`: (optional) document keys to ignore in finds (default: `['_id', '__v']`) | ||
* `filterFile`: (optional) a function that will be called for every file and should return true if this file should be parsed | ||
@@ -169,6 +170,4 @@ * `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 | ||
The valid values for `### Out` are: `String`, `Number`, `Boolean`, `Object`, `Array`. | ||
The valid type values are: `String`, `Number`, `Boolean`, `Object`, `Array`, `Date`, `RegExp`, `ObjectId`. | ||
For `### Find in _coll_` are: `Number`, `String`, `Boolean`, `Date`, `RegExp` | ||
## Custom context | ||
@@ -212,5 +211,2 @@ You can use custom context to help writing tests. All default context variables and methods will still be accessible (unless overwritten). | ||
## Run test | ||
Run `npm test` in the project root folder. | ||
## TODO | ||
* Make keys less restrictive | ||
Run `npm test` in the project root folder. |
@@ -88,2 +88,4 @@ 'use strict' | ||
pushStr(String(value), false, false, colors.regex) | ||
} else if (typeof value === 'function') { | ||
pushStr(value.name || String(value), false, false) | ||
} else if (!Object.keys(value).length) { | ||
@@ -90,0 +92,0 @@ pushStr('{}') |
@@ -25,2 +25,2 @@ # user/login | ||
### Find in users | ||
token: out.token | ||
user with token: out.token |
@@ -34,2 +34,2 @@ # user/login | ||
### Find in users | ||
token: out.token | ||
user with token: out.token |
@@ -38,5 +38,2 @@ # user/signup | ||
user with token: out.token | ||
### Find in users | ||
name: String | ||
password: String | ||
@@ -43,0 +40,0 @@ ## Using the same username again |
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
61547
1800
209