Doctestes play an important role in creating examples for documentation, as well as for testing the functions of your API.
How to run
Writing the tests from the "api.js" file is very easy to run:
% smappi test
To debug code running with tests, you can use inspect, as well as to debug API:
% node --inspect `which smappi` test
How to write
For make it easier to write the docs, we have improved the jsdoctap library for working with masks.
Masks
With the help of the mask operator "..." you can match any data, this will reduce the detailed description of the test and make the examples understandable and short.
In addition, if you parse sites or other sources, then usually some of the data changes and you will need to adjust to it, the masks will allow you to ignore the data being changed.
Lists
For lists, use the "...[]" mask correctly, but you can also "...":
/**
* Array
*
* @example
* func(1, 2, 3)
* // => [1, 2, 3, ...[], 8, 9]
* func(1, 2, 3)
* // => [1, 2, 3, ..., 9]
*/
function func (a, b, c) {
return [a, b, c, 4, 5, 6, 7, 8, 9]
}
Objects
For objects, use the "...{}" mask correctly:
/**
* Object
*
* @example
* func()
* // => {a: 1, ...{}, z: 42}
*/
function func () {
return {a: 1, b: 2, c: 3, z: 42}
}
Strings
Strings can be matched by the mask "..." or using a regular expression:
/**
* String
*
* @example
* func()
* // => "Hello ..."
*
* @example
* func()
* // => /Hello.+/
*/
function func () {
return "Hello World"
}
Numbers
Numbers can be matched using a regular expression:
/**
* Number
*
* @example
* func()
* // => /\d+/
*/
function func () {
return 42
}
Mixed example
Example with all types of data at once:
/**
* Mixed
*
* @example
* func()
* // => [1, 2, 3, ...[], {a: 1, b: 2, c: /\d+/, ...{}, z: 'Hello ...'}, 7, 8, ...]
*/
function func () {
return [
1, 2, 3, 4, 5, 6, {
a: 1,
b: 2,
c: 3,
d: 4, e: 5,
z: 'Hello World'
},
7, 8, 9, 10
]
}
Customization
If you do not have this syntax, you can always wrap the function call and change the response:
/**
* Delete one property from object
*
* @example
* (function () { let res = func(); delete res.age; return res; })()
* // => {name: 'John'}
*/
function func () {
return {name: 'John', age: 42}
}
Deferred return
If you use a deferred return, then the tests will wait for it to run, so you do not have to worry about it. However, the tests in this case will work asynchronously, i.e. not in the order in which the file "api.js" is defined:
/**
* Deferred return example
*
* @example
* func()
* // => {age: 42}
*/
function func () {
setTimeout(() => {
self.return({age: 42})
}, 2000);
}
More examples can be found here