Socket
Socket
Sign inDemoInstall

api-test

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

api-test - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

out/Case.html

46

classes/Case.js

@@ -11,34 +11,23 @@ 'use strict'

function Case() {
this.finds = []
}
/** @member {string} */
this.name = ''
/**
* @property {string}
*/
Case.prototype.name
/** @member {boolean} */
this.skip = false
/**
* @property {Obj}
*/
Case.prototype.post
/** @member {Obj} */
this.post = null
/**
* @property {string}
*/
Case.prototype.postUrl
/** @member {string} */
this.postUrl = ''
/**
* @property {Obj}
*/
Case.prototype.out
/* @member {Obj} */
this.out = null
/**
* @property {number}
*/
Case.prototype.statusCode
/** @member {number} */
this.statusCode = 0
/**
* @property {Find[]}
*/
Case.prototype.finds
/** @member {Find[]} */
this.finds = []
}

@@ -51,5 +40,6 @@ /**

Case.prototype.execute = function (options, testName) {
var that = this
var that = this,
it = this.skip ? options.it.skip : options.it
options.it(this.name, function (done) {
it(this.name, function (done) {
// Prepare context

@@ -56,0 +46,0 @@ options.context.prev = {

@@ -15,12 +15,6 @@ 'use strict'

* @param {Object} db the mongodb connected db
* @param {string[]} cleared
* @param {Object} context
* @param {Function} done
*/
Clear.prototype.execute = function (db, cleared, context, done) {
if (cleared.indexOf(this.collection) !== -1) {
return done(new Error('The collection ' + this.collection + ' was already cleared'))
}
cleared.push(this.collection)
Clear.prototype.execute = function (db, context, done) {
db.collection(this.collection).remove({}, {

@@ -27,0 +21,0 @@ w: 1

@@ -6,7 +6,9 @@ 'use strict'

* @class
* @property {string} name
* @property {Object} value
* @param {string} name
* @param {Obj} value
*/
function Declaration(name, value) {
/** @member {string} */
this.name = name
/** @member {Obj} */
this.value = value

@@ -18,7 +20,6 @@ }

* @param {Object} db (not used)
* @param {string[]} cleared (not used)
* @param {Object} context
* @param {Function} done
*/
Declaration.prototype.execute = function (db, cleared, context, done) {
Declaration.prototype.execute = function (db, context, done) {
context[this.name] = this.value.execute(context, '<' + this.name + ' is>')

@@ -25,0 +26,0 @@ done()

@@ -6,9 +6,16 @@ 'use strict'

* @property {string} collection
* @property {Object} value
* @property {Obj} value
*/
function Find(collection, value) {
/** @member {string} */
this.collection = collection
/** @member {Obj} */
this.value = value
}
/**
* @param {Object} context
* @param {Object} db
* @param {Function} done
*/
Find.prototype.execute = function (context, db, done) {

@@ -15,0 +22,0 @@ var selector = this.value.execute(context, '<find in ' + this.collection + '>'),

@@ -9,4 +9,11 @@ 'use strict'

function Header(line, sourceLine) {
/** @member {number} */
this.level = line.match(/^#+/)[0].length
/** @member {string} */
this.value = line.substr(this.level).trim()
/**
* @member {Object}
* @property {number} begin
* @property {number} end
*/
this.source = {

@@ -13,0 +20,0 @@ begin: sourceLine,

@@ -10,7 +10,10 @@ 'use strict'

* @property {string} collection
* @property {Object} value
* @property {Obj} value
*/
function Insertion(name, collection, value) {
/** @member {string} */
this.name = name
/** @member {string} */
this.collection = collection
/** @member {Obj} */
this.value = value

@@ -22,19 +25,8 @@ }

* @param {Object} db the mongodb connected db
* @param {string[]} cleared
* @param {Object} context
* @param {Function} done
*/
Insertion.prototype.execute = function (db, cleared, context, done) {
Insertion.prototype.execute = function (db, context, done) {
var that = this
if (cleared.indexOf(this.collection) === -1) {
// Clear the collection first
return new Clear(this.collection).execute(db, cleared, context, function (err) {
if (err) {
return done(err)
}
that.execute(db, cleared, context, done)
})
}
// Prepare the document

@@ -41,0 +33,0 @@ context[that.name] = this.value.execute(context, '<' + this.name + ' in ' + this.collection + '>')

@@ -6,25 +6,26 @@ 'use strict'

/**
* @class
* @typedef {Object} Mixin~Addition
* @property {string[]} path
* @property {string[]} value
*/
function Mixin() {
this.additions = []
this.removals = []
}
/**
* The base path components
* @property {string[]}
* @typedef {string[]} Mixin~Removal
*/
Mixin.prototype.base
/**
* @property {{path:string[],value:string}[]}
* @class
*/
Mixin.prototype.additions
function Mixin() {
/** @member {Mixin~Addition[]} */
this.additions = []
/**
* @property {string[][]}
*/
Mixin.prototype.removals
/** @member {Mixin~Removal[]} */
this.removals = []
/** The base path components
* @member {string[]}
*/
this.base = []
}

@@ -66,2 +67,3 @@ /**

* @returns {*}
* @private
*/

@@ -88,5 +90,5 @@ function copyDeep(x) {

* @param {Object} obj
* @param {(string|number)[]} path
* @param {Array<string|number>} path
* @param {number} [i]
* @throws
* @throws {Error}
* @private

@@ -136,7 +138,6 @@ */

* @param {!Object} obj
* @param {(string|number)[]} path
* @param {Array<string|number>} path
* @param {*} value
* @param {number} [i]
* @throws
* @private
* @throws {Error}
*/

@@ -143,0 +144,0 @@ function add(obj, value, path, i) {

@@ -12,3 +12,9 @@ 'use strict'

function Obj(sourceLine) {
/** @param {string[]} */
this.lines = []
/**
* @member {Object}
* @property {number} begin
* @property {number} end
*/
this.source = {

@@ -18,3 +24,5 @@ begin: sourceLine,

}
/** @member {boolean} */
this.parsed = false
/** @member {Object|Array|string|Mixin} */
this.value = null

@@ -21,0 +29,0 @@ }

@@ -6,8 +6,13 @@ 'use strict'

* @param {string} message
* @param {(Header|Obj)} [el] The element that caused the error (null if not applicable)
* @param {Header|Obj} [...el] The element that caused the error (null if not applicable)
* @extends Error
*/
function ParseError(message, el) {
function ParseError(message) {
Error.call(this)
/** @member {string} */
this.message = message
this.el = el
/** @member {Array<Header|Obj>} */
this.els = [].slice.call(arguments, 1)
}

@@ -22,11 +27,22 @@

ParseError.prototype.addSourceContext = function (originalLines) {
if (!this.el) {
var start = Infinity,
end = -Infinity,
str = '\n\n-----',
i, focus, checkElFocus
if (!this.els.length) {
return
}
var start = this.el.source.begin,
end = this.el.source.end,
str = '\n\n-----',
i
this.els.forEach(function (el) {
start = Math.min(start, el.source.begin)
end = Math.max(end, el.source.end)
})
checkElFocus = function (el) {
return i >= el.source.begin && i < el.source.end
}
for (i = Math.max(0, start - 3); i < end + 3 && i < originalLines.length; i++) {
str += '\n' + (i >= start && i < end ? '>' : ' ') + ' ' + originalLines[i]
focus = this.els.some(checkElFocus)
str += '\n' + (focus ? '>' : ' ') + ' ' + originalLines[i]
}

@@ -33,0 +49,0 @@ str += '\n-----'

@@ -7,10 +7,15 @@ 'use strict'

* @class
* @property {string} name
* @property {Setup[]} setups
* @property {Case[]} cases
*/
function Test() {
/** @member {string} */
this.name = ''
/** @member {Array<Insertion|Clear|Declaration>} */
this.setups = []
/** @member {Case[]} */
this.cases = []
/**
* A map with used collections and the element that has cleared it
* @member {Object<Header>}
*/
this.collections = Object.create(null)
}

@@ -28,5 +33,4 @@

// Insert each document
var cleared = []
async.eachSeries(that.setups, function (setup, done) {
setup.execute(options.db, cleared, options.context, done)
setup.execute(options.db, options.context, done)
}, done)

@@ -33,0 +37,0 @@ })

{
"name": "api-test",
"version": "1.2.0",
"version": "1.3.0",
"author": "Sitegui <sitegui@sitegui.com.br>",

@@ -5,0 +5,0 @@ "description": "API testing made simple",

/**
* @file Parses simple markdown text
*
* The syntax is described using these notations:
* * {x} represents a non-terminal symbol that can span more than one line
* * <x> represents an one-line non-terminal symbol
* * / represents a line-break
* * _x_ represents an arbritary text field
* * 'x' represents the literal x
* * x? means optional
* * x+ means at least once
* * x* means any number of times
* * x|y means either x or y
* * [D] means a digit
* * ... means ignored content
* The syntax is described in doc-syntax.md
*
* {file} = <header> / ... / {setup} / {test}+
*
* <header> = '# ' _testName_
* {setup} = '## Setup' / ({insertion} | {clear} | {declaration})*
* {test} = '## ' _caseName_ / ('### Post' / {obj})? / {out}? / {find}*
*
* {insertion} = '### ' _docName_ ' in ' _collection_ / {obj}
* {clear} = '### Clear ' _collection_
* {declaration} = '### ' _varName_ ' is' / {obj}
* {obj} = '\t' (_value_ | {subobj} | <prop>)
* {out} = '### Out' (' ' <statusCode>)? / {obj}
* {find} = '### Find in ' _collection_ / {obj}
*
* {subobj} = _key_ ':' / '\t' {obj}
* <prop> = _key_ ':' _value_
* <statusCode> = [D] [D] [D]
*
* Paragraph text is ignored (it can be used for documentation)

@@ -166,3 +138,3 @@ */

function parseSetupItem(test, els, i) {
var match, header
var match, header, coll, el, msg

@@ -178,5 +150,18 @@ if (checkHeader(els[i], 2)) {

if ((match = header.match(/^Clear ([a-zA-Z_$][a-zA-Z0-9_$]*)$/))) {
test.setups.push(new Clear(match[1]))
// Clear a collection
coll = match[1]
if (coll in test.collections) {
el = test.collections[coll]
if (el.value.indexOf('Clear ') === 0) {
msg = 'No need to clear the same collection twice'
} else {
msg = 'Clearing the collection after insertion is not a good idea'
}
throw new ParseError(msg, el, els[i])
}
test.collections[coll] = els[i]
test.setups.push(new Clear(coll))
return i + 1
} else if ((match = header.match(/^([a-zA-Z_$][a-zA-Z0-9_$]*) is$/))) {
// Declare a variable
if (!(els[i + 1] instanceof Obj)) {

@@ -188,6 +173,16 @@ throw new ParseError('Expected an {obj}', els[i + 1])

} else if ((match = header.match(/^([a-zA-Z_$][a-zA-Z0-9_$]*) in ([a-zA-Z_$][a-zA-Z0-9_$]*)$/))) {
// Insert a document (clear the collection implicitly)
if (!(els[i + 1] instanceof Obj)) {
throw new ParseError('Expected an {obj}', els[i + 1])
}
test.setups.push(new Insertion(match[1], match[2], els[i + 1].parse()))
coll = match[2]
if (!(coll in test.collections)) {
// Push implicit clear
test.collections[coll] = els[i]
test.setups.push(new Clear(coll))
} else if (test.collections[coll].value.indexOf('Clear ') === 0) {
el = test.collections[coll]
throw new ParseError('No need to clear the collection before insertion, this is done automatically for you', el, els[i])
}
test.setups.push(new Insertion(match[1], coll, els[i + 1].parse()))
return i + 2

@@ -214,7 +209,14 @@ } else {

}
testCase.name = els[i++].value
if (/ \(skip\)$/.test(els[i].value)) {
testCase.name = els[i].value.substr(0, els[i].value.length - 7).trimRight()
testCase.skip = true
} else {
testCase.name = els[i].value
testCase.skip = false
}
i++
i = parseCasePost(testCase, els, i)
i = parseCaseOut(testCase, els, i)
i = parseCaseFinds(testCase, els, i)
i = parseCaseFinds(test.collections, testCase, els, i)

@@ -272,2 +274,3 @@ test.cases.push(testCase)

* Try to parse a test case finds
* @param {Object<Header>} collections Cleared collections
* @param {Case} testCase

@@ -279,3 +282,4 @@ * @param {Object[]} els

*/
function parseCaseFinds(testCase, els, i) {
function parseCaseFinds(collections, testCase, els, i) {
var coll
while (i < els.length && !checkHeader(els[i], 2)) {

@@ -287,3 +291,7 @@ if (!checkHeader(els[i], 3) || els[i].value.indexOf('Find in ') !== 0) {

}
testCase.finds.push(new Find(els[i].value.substr(8).trim(), els[i + 1].parse()))
coll = els[i].value.substr(8).trim()
if (!(coll in collections)) {
throw new ParseError('You can\'t do a find in a collection that wasn\'t cleared in the setup', els[i])
}
testCase.finds.push(new Find(coll, els[i + 1].parse()))
i += 2

@@ -290,0 +298,0 @@ }

@@ -93,2 +93,5 @@ # API Test

## Skipping test cases
By appending ` (skip)` to a test case name (see an [example](https://github.com/clubedaentrega/api-test/blob/master/test/api-test/recursive/user-login.md#wrong-password-skip)) it will be simply ignored. This puts them in a pending state, and is favoured over removing tests which you may forget to add back again.
## Object syntax

@@ -182,2 +185,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).

## TODO
* Make keys less restrictive
* Make keys less restrictive
* Ignore key ordering in find

@@ -8,3 +8,3 @@ # user/login

## Wrong password
## Wrong password (skip)
### Post

@@ -11,0 +11,0 @@ user:

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc