gentests
v1.3.1
Published
GenTests is a unit test generator.
Downloads
1
Readme
Description
GenTests is a unit test generator.
Installation
npm install gentests -g
Usage
$ gentests --source sourceFile [--corrector correctorPath] [--delete-cache] [--run exampleFile]
Quick Start
In this example, we'll use a structure like the one below.
📁 package-root
│
└───📁 cjs
│ │
│ │─── 📝 index.cjs
│ │
│ └─── 📝 user-code.cjs
│
└───📁 test
│
└─── 📝 index.specs.js
We define a function with a jsDocs formatted comment.
The system will parse this comment and extract every @example section.
Every @example section will be used to generate a new test case.
From an example section, you can use a formatted pattern like the one below:
// expect: to....
We'll use the "expect" here to overwrite the default expectation in the generated test case. If it is not provided, the system will use what has been evaluated at runtime.
📝 index.cjs content ↴
/**
* This function tries to sort variables
* by key
*
* @example
* // expect: to.be.above(2)
* // should: eat something
* // when: it's hungry
* sortEntryByKey({aa: 1, bb: 2})
*
* @example
* // expect: to.equal(5)
* sortEntryByKey({aa: 5, cc: 2})
*
* @param currentEntity
* @returns {*}
*/
let sortEntryByKey = (currentEntity) =>
{
if (currentEntity instanceof Object)
{
currentEntity = Object.keys({...currentEntity}).sort().reduce(
(obj, key) =>
{
obj[key] = currentEntity[key];
return obj;
},
{}
);
return currentEntity;
}
return currentEntity;
};
module.exports.sortEntryByKey = sortEntryByKey;
From the CLI, go to the "package-root" directory, then run:
💻 ↴
$ gentests --source ./cjs/index.cjs
--delete-cache
This process will generate a test file in a test directory that should look like this:
const chai = require("chai");
const expect = chai.expect;
// ===========================================================================
// Units under test imports
// ---------------------------------------------------------------------------
const {
add,
sortEntryByKey,
varsEqual,
} = require("../demo/code/index.cjs");
// ===========================================================================
// Tests
// ---------------------------------------------------------------------------
describe("In source code", function() {
describe("#sortEntryByKey", function() {
it(`should eat something when it's hungry`, function() {
const currentEntity = {
"aa": 1,
"bb": 2
};
const result = sortEntryByKey(currentEntity);
expect(result).to.be.above(2);
});
});
describe("#sortEntryByKey", function() {
it(`should sort entry by key when currentEntity is { "aa": 5, "cc": 2}`, function() {
const currentEntity = {
"aa": 5,
"cc": 2
};
const result = sortEntryByKey(currentEntity);
expect(result).to.equal(5);
});
});
});
Options
| Options | default | Expect | Description | |----------------|-------------|------------|----------------------------------------------------------------------------------------------------------| | --source | | string | Path to the source file | | --run | | string | A common Js file containing some invocations | | --delete-cache | false | boolean | To reset the GenPack cache | | --esm | false | boolean | To generate tests for ESM | | --corrector | | string | Path to a json file where each key will be replaced by their corresponding value in the generated test |
Examples
With the --corrector option
📝 ./cjs/corrector.json content ↴
{
"In source code": "****** REPLACED *******"
}
💻 ↴
$ gentests --source ./cjs/index.cjs --run cjs/user-code.cjs --corrector cjs/corrector.json --delete-cache
...
// ===========================================================================
// Tests
// ---------------------------------------------------------------------------
describe("****** REPLACED *******", function ()
{
describe("#sortEntryByKey", function ()
{
it(`should sort entry by key when currentEntity is { "aa": 1, "bb": 2}`, function ()
{
...
With the --run option
Define a file with custom calls. The system will try to generate a test case for every call.
📝 user-code.cjs content ↴
// -----------------------------------------
// User Code
// -----------------------------------------
const {varsEqual, sortEntryByKey, add} = require("./demo/code/index.cjs");
sortEntryByKey({aa: 1, bb: 2});
varsEqual("1", "2");
varsEqual("aa", "aa");
varsEqual(54, "asfdgdok");
add(51, 53);
// -----------------------------------------
// User Code End
// -----------------------------------------
/**
* This function tries to sort variables
* by key
* @param currentEntity
* @returns {*}
*/
let sortEntryByKey = (currentEntity) =>
{
if (currentEntity instanceof Object)
{
currentEntity = Object.keys({...currentEntity}).sort().reduce(
(obj, key) =>
{
obj[key] = currentEntity[key];
return obj;
},
{}
);
return currentEntity;
}
return currentEntity;
};
/**
* Compare two variables of any types
*
*
* @summary check equality
* @param {*} entity1
* @param {*} entity2
* @returns {boolean}
* @author Patrice Thimothee
*/
const varsEqual = (entity1, entity2) =>
{
if (typeof entity1 !== typeof entity2)
{
return false;
}
if (Object.prototype.toString.call(entity1) === "[object Symbol]"
|| Object.prototype.toString.call(entity2) === "[object Symbol]")
{
return false;
}
const sorted1 = sortEntryByKey(entity1);
const sorted2 = sortEntryByKey(entity2);
const str1 = JSON.stringify(sorted1);
const str2 = JSON.stringify(sortEntryByKey(sorted2));
return str1 === str2;
};
/** Add two values together **/
const add = function (a, b)
{
return a + b;
};
module.exports.add = add;
module.exports.sortEntryByKey = sortEntryByKey;
module.exports.varsEqual = varsEqual;
📁 package-root
│
└───📁 cjs
│ │
│ │─── 📝 index.cjs
│ │
│ └─── 📝 user-code.cjs
│
└───📁 test
│
└─── 📝 index.specs.js
From the CLI, go to the "package-root" directory, then run:
💻 ↴
$ gentests --source ./cjs/index.cjs --run cjs/user-code.cjs
--delete-cache
This process will generate a test directory against every invocation done in the [user-code.cjs] file