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 0.0.2 to 0.1.0

8

Obj.js

@@ -5,6 +5,11 @@ 'use strict'

* @class
* @param {number} sourceLine
*/
function Obj() {
function Obj(sourceLine) {
// The inner value, either a hash map or a string
this.value = Object.create(null)
this.source = {
begin: sourceLine,
end: sourceLine
}
// Store the last prop name for each level

@@ -54,4 +59,5 @@ this._lastProps = []

this._empty = false
this.source.end++
}
module.exports = Obj

2

package.json
{
"name": "api-test",
"version": "0.0.2",
"version": "0.1.0",
"author": "Sitegui <sitegui@sitegui.com.br>",

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

@@ -47,31 +47,38 @@ /**

var lines = [],
originalLines = text.split(/\r?\n/),
test = new Test,
i
i, line
// Tokenizer
text.split(/\r?\n/).forEach(function (line) {
if (line[0] === '#') {
// Header line
lines.push(new Header(line))
} else if (line[0] === '\t') {
// Object line
if (!(lines[lines.length - 1] instanceof Obj)) {
lines.push(new Obj(line))
try {
// Lexical parsing (put tokens into lines array)
for (i = 0; i < originalLines.length; i++) {
line = originalLines[i]
if (line[0] === '#') {
// Header line
lines.push(new Header(line, i))
} else if (line[0] === '\t') {
// Object line
if (!(lines[lines.length - 1] instanceof Obj)) {
lines.push(new Obj(i))
}
lines[lines.length - 1].push(line)
}
lines[lines.length - 1].push(line)
}
})
} catch (e) {
// Add source code info
e.message += getSourceContext(originalLines, i)
throw e
}
// Syntax parsing (parse tokens from lines array)
i = 0
// Header
if (!checkHeader(lines[0], 1)) {
throw new Error('The first line must be a header')
}
test.name = lines[0].value
i = parseHeader(test, lines, i, originalLines)
// Fixup
i = 1
if (checkHeader(lines[i], 2, 'DB')) {
i = 2
i++
while (i < lines.length && !checkHeader(lines[i], 2)) {
i = parseDBItem(test, lines, i)
i = parseDBItem(test, lines, i, originalLines)
}

@@ -81,3 +88,3 @@ }

while (i < lines.length) {
i = parseCase(test, lines, i)
i = parseCase(test, lines, i, originalLines)
}

@@ -89,9 +96,21 @@

/**
* Try to parse the test header
* @throws if the syntax is invalid
*/
function parseHeader(test, lines, i, originalLines) {
if (!checkHeader(lines[i], 1)) {
throwSyntaxError('Expected a header', lines[i], originalLines)
}
test.name = lines[i].value
return i + 1
}
/**
* Try to parse a DB insertion/clear
* @throws if the syntax is invalid
*/
function parseDBItem(test, lines, i) {
function parseDBItem(test, lines, i, originalLines) {
var match
if (!checkHeader(lines[i], 3)) {
throw new Error('The first line of a DB insertion/clear must be "### ..."')
throwSyntaxError('Expected "### ..."', lines[i], originalLines)
}

@@ -104,3 +123,3 @@

if (!(lines[i + 1] instanceof Obj)) {
throw new Error('The second part of a DB insertion must be an {obj}')
throwSyntaxError('Expected an {obj}', lines[i + 1], originalLines)
}

@@ -110,3 +129,3 @@ test.insertions.push(new Insertion(match[1], match[2], lines[i + 1].value))

} else {
throw new Error('The first line of a DB insertion/clear must be either "### _docName_ in _collection_" or "### Clear _collection_"')
throwSyntaxError('Expected either "### _docName_ in _collection_" or "### Clear _collection_"', lines[i], originalLines)
}

@@ -119,13 +138,13 @@ }

*/
function parseCase(test, lines, i) {
function parseCase(test, lines, i, originalLines) {
if (!checkHeader(lines[i], 2)) {
throw new Error('The first line of a test case must be "## _caseName_"')
throwSyntaxError('Expected "## _caseName_"', lines[i], originalLines)
} else if (!checkHeader(lines[i + 1], 3, 'Post')) {
throw new Error('The second line of a test case must be "### Post"')
throwSyntaxError('Expected "### Post"', lines[i + 1], originalLines)
} else if (!(lines[i + 2] instanceof Obj)) {
throw new Error('The third line of a test case must be an {obj}')
throwSyntaxError('Expected an {obj}', lines[i + 2], originalLines)
} else if (!checkHeader(lines[i + 3], 3, 'Out')) {
throw new Error('The fourth line of a test case must be "### Out"')
throwSyntaxError('Expected "### Out"', lines[i + 3], originalLines)
} else if (!(lines[i + 4] instanceof Obj)) {
throw new Error('The fifth line of a test case must be an {obj}')
throwSyntaxError('Expected an {obj}', lines[i + 4], originalLines)
}

@@ -139,5 +158,5 @@

if (!checkHeader(lines[i], 3) || lines[i].value.indexOf('Find in ') !== 0) {
throw new Error('The first line of a find must be "### Find in _collection_"')
throwSyntaxError('Expected "### Find in _collection_"', lines[i], originalLines)
} else if (!(lines[i + 1] instanceof Obj)) {
throw new Error('The second line of a find must be an {obj}')
throwSyntaxError('Expected an {obj}', lines[i + 1], originalLines)
}

@@ -165,6 +184,37 @@ testCase.finds.push(new Find(lines[i].value.substr(8).trim(), lines[i + 1].value))

* @param {string} line must start with '#'
* @param {number} sourceLine
*/
function Header(line) {
function Header(line, sourceLine) {
this.level = line.match(/^#+/)[0].length
this.value = line.substr(this.level).trim()
this.source = {
begin: sourceLine,
end: sourceLine + 1
}
}
/**
* @param {string[]} originalLines
* @param {number} start
* @param {number} [end=start+1]
* @param {number} [context=3]
*/
function getSourceContext(originalLines, start, end, context) {
end = end || start + 1
context = context || 3
var i, str = '\n\n-----'
for (i = Math.max(0, start - context); i < end + context && i < originalLines.length; i++) {
str += '\n' + (i >= start && i < end ? '>' : ' ') + ' ' + originalLines[i]
}
return str + '\n-----'
}
/**
* @param {string} msg
* @param {(Header|Obj)} token
* @param {string[]} originalLines
*/
function throwSyntaxError(msg, token, originalLines) {
throw new Error(msg + getSourceContext(originalLines, token.source.begin, token.source.end))
}

@@ -8,4 +8,2 @@ # API Test

**WORKING IN PROGRESS**
## Usage

@@ -66,3 +64,3 @@ Create a test file 'test/api-test/sample.md' to test the 'item/get' endpoint, like this:

The syntax for _docDescription_ is described at ## object syntax
The syntax for _docDescription_ is described at bellow

@@ -86,2 +84,47 @@ #### Clearing collections

In all cases, the syntax is described at ## object syntax
In all cases, the syntax is described bellow
## Object syntax
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`).
The object can be a simple JS value, like:
```
new Date
```
Or an object with one property by line and tabs used to declare sub-objects:
```
user:
name:
first: 'Happy'
last: 'Customer'
age: 37 + 2
country: 'cm'.toUpperCase()
```
## Default context
* `randomId()`: return a random mongo-id as a 24-hex-char string
* `randomStr(len)`: return a random string with length `len`
* `empty`: the empty object `{}`
* `post`: the request body of the current test case
* `out`: the response body of the current test case
* `prev`: an object wity keys:
* `post`: the request body of the previous request
* `out`: the response body of the previous request
## Options
* `mongoUri`: the mongo uri to connect to. The hostname SHOULD be 'localhost' and the db name SHOULD contains 'test'. If not, the code will ask for confirmation. This protects one from dropping production data, since the tests automatically clear collections, before inserting docs.
* `baseUrl`: the base API url. Every request url will be composed from this base and the test name.
* `describe`, `it`, `before`: (optional) the mocha interface. Defaults to global mocha functions
* `context`: (optional) define your own variables/functions accessible from object definitions, to help writing tests.
## Examples
See more test examples in the folder 'test/api-test'
## Run test
Run `node index` in 'test/api' to start the a simple API webservice. Then (in another terminal instance), run `npm test` in the project root folder.
## Road map
* Array notation: there is no way to declare an array yet
* Better failure message
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