approvals
v7.1.3
Published
Approval Tests Library - Capturing Human Intelligence
Downloads
11,696
Maintainers
Readme
Approvals (Approval Tests for Node.js)
Contents
- Intro
- Badges
- Integrations
- Getting Started
- Documentation
- CLI
- Simple hello world
- Specify diff reporter (great for C.I.)
- Multiple diff reporters
- Reporters
- Supported Diff Tools
- Configuration
- API
- approvals
- approvals.reporters
- approvals~configure(overrideOptions)
- approvals~getConfig(overrideOptions) ⇒ Object
- approvals~mocha(optionalBaseDir)
- approvals~verifyAndScrub(dirName, testName, data, scrubber, optionsOverride)
- approvals~verify(dirName, testName, data, optionsOverride)
- approvals~verifyAsJSON(dirName, testName, data, optionsOverride)
- approvals~verifyAsJSONAndScrub(dirName, testName, data, scrubber, optionsOverride)
- approvals~verifyWithControl(namer, writer, [reporterFactory], [optionsOverride])
- Source Control
- Contributing
- License
Intro
Approval Tests Library - Capturing Human Intelligence
What is an approval test? Check out a brief overview here or learn more about Approvals at approvaltests.com.
Badges
| Service | Status | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Package | | | Github (Linux, Mac, Windows) | |
Integrations
- Mocha tests, see the getting-started
- Approvals API (
require('approvals').verify(...)
) - Command line Utility
Getting Started
Jest Typescript Starter Project
If you want to jump start a new project, clone the Jest Starter Project
Mocha
Below is a simple getting started using Mocha.
Create a project (folder)
mkdir MyProject cd MyProject`
Install approvals
npm install --save-dev approvals
Install Mocha globally to execute our tests
npm install -g mocha
Create a sample Mocha test file called
SimpleLogger.test.js
.require("approvals").mocha(); describe("When running some tests", function () { it("should be able to use Approvals", function () { var data = "Hello World!"; this.verify(data); // or this.verifyAsJSON(data) }); });
Test the file with mocha.
mocha SimpleLogger.test.js
You should be presented with a diff tool. (if not, you may need to install one?)
Documentation
If using Jest, see more documentation here.
CLI
Approvals.NodeJS has a version that can be run as a command line tool.
You can check out the Examples
section of the below CLI help. Or a blog post introducing the tool here: Approval Tests - Command Line Tool (CLI).
Install Approvals CLI
npm install -g approvals
CLI Help
By running approvals --help
# Usage
`approvals testName [options]`
| Arg | Description |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| \*\*[-f | --forceapproveall]\*\* | Skip the approve step and apply the results to the .approved.txt file (good for a first time run) |
| [--reporter difftool] | supports multiple EX: `--reporter opendiff --reporter gitdiff` |
| [--outdir] | dir to place approval file - defaults to current directory |
| [--verbose] | extra debug info |
| TODO: | We need to extend the supported args to include other approval options. (file an [issue](https://github.com/approvals/Approvals.NodeJS/issues) if you need one that's not here) |
# Examples
## Simple hello world
echo 'Hello World!' | approvals helloWorldTest
## Specify diff reporter (great for C.I.)
echo 'Hello World!' | approvals helloWorldTest --reporter gitdiff
## Multiple diff reporters
echo 'Hello World!' | approvals helloWorldTest --reporter gitdiff --reporter p4merge
Reporters
Built-In Reporters
Any of the following reporter may suite your needs. Some support images, some only diffing text, some on mac and linux, some only on windows... Feel free to configure the system to automatically choose your favorite.
Supported Diff Tools
| approval name | Program | Windows | Mac/Linux | Notes |
| --------------- | ---------------------------------------------------------------------------------------------------------------- | :------: | :-------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| beyondcompare
| Beyond Compare | ✓ | ✓ | |
| copycommand
| git diff (console diff) | ✓ | ✓ | Great for C.I. builds runs. |
| diffmerge
| DiffMerge | ✓ | ✓ | |
| donothing
| | ✓ | ✓ | This one does what it says - nothing. |
| gitdiff
| git diff (console diff) | ✓ | ✓ | Using git cli to diff files. Useful in C.I. builds |
| icdiff
| Icdiff | ✓ | ✓ | |
| kdiff3
| KDiff3 | ✓ | ✓ | |
| kompare
| Kompare | ? | ✓ | |
| meld
| Meld | ✓ | ✓ | |
| multi
| | ✓ | ✓ | This allows you to run multiple reporters at the same time. EX: when verifying images, you might like to use p4merge
along with the copycommand
reporter to get the copy CLI command to approve an image as well as view the diff in a tool. |
| nodediff
| nodediff (console diff) | ✓ | ✓ | colorized CLI output without a popup of a diff tool |
| opendiff
| opendiff | | ✓ | |
| p4merge
| p4merge | ✓ | ✓ | |
| tortoisemerge
| Tortise merge | ✓ | ✓ | |
| vimdiff
| | ✓ | ✓ | |
| visualstudio
| Visual Studio Diff tool | ✓ | |
| vscode
| Visual Studio Code Diff tool | ✓ | ✓ |
| vscodium
| VSCodium Diff tool | ✓ | ✓ |
Custom Reporter
Along with the built-in reporters, you can create your own custom reporter just by taking this sample and filling out the interface with your custom reporters desired behavior.
/* OR a custom reporter object. Below is an example custom reporter */
{
/**
* Determine if the file that needs to be reported on can be handled by this reporter object.
* @param {string} receivedFilePath - The path to a received file.
*/
canReportOn(receivedFilePath) {
return true;
}
/**
* Apply the logic necessary to report a difference.
* EX:
* - Open a diff program using the approved & received files
* - Generate and email a report showing the differences.
* @param {string} approvedFilePath - The path to an approved file.
* @param {string} receivedFilePath - The path to a received file.
*/
// Actually execute the diff against the two files
report(approvedFilePath, receivedFilePath) {
// Do some reporting.
// Typically by launching a diff tool
}
}
Configuration
Or more, controlling the behavior of approvals through various tweaks to configuration.
Approvals uses the below configuration to drive its behavior. How you communicate that configuration to approvals can happen in several ways.
The default configuration as defined below can be overridden by using the following strategy.
NOTE: Priority/order of config selection comes from the below list where the first item have the defined defaults and each next step having a potential to override the previous if a configuration value is specified.
- Starting with the defaults (as shown in the JS object below) this is defined in lib/config.js.
- We then take and override the defaults (and only the properties specified) with config in a yaml or json file in your home directory
~/.approvalsConfig
. - You can then call
approvals.configure({...})
. - Then passing any specific configuration at the test level as the last parameter in the verify function
.verify(..., {...overridden config...});
. See API for specific parameters.
Here's an example of using a single reporter p4merge
, and overriding whatever is configured. This will only override this specific test.
it("should use a specific reporter", function () {
this.verify("some data", {
reporters: ["p4merge"],
});
});
If you have the need to execute multiple reporters on a single failure.
Say you made an "awesomeDiffReporter" and wanted it to run that in combination with a "notifyTheBossViaEmailReporter" you can use the MultiReporter like below.
var approvals = require("approvals");
var MultiReporter = approvals.reporters.MultiReporter;
it("should use a multiple reporters", function () {
this.verify("some data", {
reporters: [new MultiReporter(["p4merge", "copycommand"])],
});
});
export const defaultConfig: Config = {
reporters: [
"BeyondCompare",
"diffmerge",
"p4merge",
"tortoisemerge",
"nodediff",
"opendiff",
"gitdiff",
],
normalizeLineEndingsTo: false,
failOnLineEndingDifferences: false,
appendEOL: true,
EOL: os.EOL,
errorOnStaleApprovedFiles: true,
shouldIgnoreStaleApprovedFile: () => false,
stripBOM: false,
forceApproveAll: false,
blockUntilReporterExits: false,
maxLaunches: 10,
};
snippet source | anchor
API
approvals
Approvals module.
- approvals
- static
- inner
- ~configure(overrideOptions)
- ~getConfig(overrideOptions) ⇒ Object
- ~mocha(optionalBaseDir)
- ~verifyAndScrub(dirName, testName, data, scrubber, optionsOverride)
- ~verify(dirName, testName, data, optionsOverride)
- ~verifyAsJSON(dirName, testName, data, optionsOverride)
- ~verifyAsJSONAndScrub(dirName, testName, data, scrubber, optionsOverride)
- ~verifyWithControl(namer, writer, [reporterFactory], [optionsOverride])
approvals.reporters
reporters
gives access to the MultiReporter
Kind: static property of approvals Example
const MultiReporter = approvals.reporters.MultiReporter
reporters.MultiReporter
This allows access to the MultiReporter constructor. You can use this to run multiple reporters at the same time.
Kind: static property of reporters Example
approvals.verify(__dirname, "multi-reporter-example", "some data", {
reporters: [
new MultiReporter('p4merge', 'copycommand')
]
});
approvals~configure(overrideOptions)
Allows you to provide overrides to the default configuration.
Kind: inner method of approvals
| Param | Type | | --- | --- | | overrideOptions | * |
Example
const approvals = require('approvals');
approvals.configure({
reporters: ['p4merge']
});
approvals~getConfig(overrideOptions) ⇒ Object
Allows the creation of an approvals configuration object using any passed in options to override the defaults.
Kind: inner method of approvals Returns: Object - approvals config object with any options overridden.
| Param | Type | | --- | --- | | overrideOptions | Object |
approvals~mocha(optionalBaseDir)
Configure approvals to hook into Mocha tests.
Kind: inner method of approvals
| Param | Type | Description | | --- | --- | --- | | optionalBaseDir | * | An optional folder to save approval files to. |
approvals~verifyAndScrub(dirName, testName, data, scrubber, optionsOverride)
Use this to apply the scrubber function to any data before running verify.
Kind: inner method of approvals
| Param | Type | Description |
| --- | --- | --- |
| dirName | string | Typically __dirname
but could be the base-directory (anywhere) to store both approved and received files. |
| testName | string | A file name safe string to call the file associated with this test. |
| data | string | Buffer | Either the string to save as a text file or a Buffer that represents an image |
| scrubber | * | A function that takes a string and returns a string. Approvals will call this if it exists to scrub the "data" before writing to any files. |
| optionsOverride | * | An object that can contain configurational overrides as defined in the approvals configuration object. |
Example
// basic approval test with a custom scrubber
const approvals = require('approvals');
const scrubber = approvals.scrubbers.multiScrubber([
function (data) {
return (data || '').replace("some text", "some other text");
},
approvals.scrubbers.guidScrubber // to remove guids from the received data
});
approvals.verifyAndScrub(__dirname, 'sample-approval-test', "some text to verify", scrubber);
approvals~verify(dirName, testName, data, optionsOverride)
Kind: inner method of approvals
| Param | Type | Description |
| --- | --- | --- |
| dirName | string | Typically __dirname
but could be the base-directory (anywhere) to store both approved and received files. |
| testName | string | A file name save string to call the file associated with this test. |
| data | string | Buffer | Either the string to save as a text file or a Buffer that represents an image |
| optionsOverride | * | An object that can contain configurational overrides as defined in the approvals configuration object. |
Example
// basic approval test
const approvals = require('approvals');
approvals.verify(__dirname, 'sample-approval-test', "some text to verify");
Example
// basic approval test providing an option to override configuration
const approvals = require('approvals');
approvals.verify(__dirname, 'sample-approval-test', "some text to verify", { normalizeLineEndingsTo: true });
approvals~verifyAsJSON(dirName, testName, data, optionsOverride)
You can pass as "data" any javascript object to be JSON.stringified and run verify against.
Kind: inner method of approvals
| Param | Type | Description |
| --- | --- | --- |
| dirName | string | Typically __dirname
but could be the base-directory (anywhere) to store both approved and received files. |
| testName | string | A file name safe string to call the file associated with this test. |
| data | string | Buffer | This can be any JavaScript object/array that will be JSON.stringified before running verify |
| optionsOverride | * | An object that can contain configurational overrides as defined in the approvals configuration object. |
Example
const approvals = require('approvals');
approvals.verifyAndScrub(__dirname, 'sample-approval-test', { a: "some text in an object" });
approvals~verifyAsJSONAndScrub(dirName, testName, data, scrubber, optionsOverride)
You can pass as "data" any javascript object to be JSON.stringified. Before we run verify the scrubber will be run against the complete string before running verify against it.
Kind: inner method of approvals
| Param | Type | Description |
| --- | --- | --- |
| dirName | string | Typically __dirname
but could be the base-directory (anywhere) to store both approved and received files. |
| testName | string | A file name safe string to call the file associated with this test. |
| data | string | Buffer | This can be any JavaScript object/array that will be JSON.stringified before running verify |
| scrubber | * | A function that takes a string and returns a string. Approvals will call this if it exists to scrub the "data" before writing to any files. |
| optionsOverride | * | An object that can contain configurational overrides as defined in the approvals configuration object. |
Example
// basic approval test with a custom scrubber
const approvals = require('approvals');
const scrubber = approvals.scrubbers.multiScrubber([
function (data) {
return (data || '').replace("some text", "some other text");
},
approvals.scrubbers.guidScrubber // to remove guids from the received data
});
approvals.verifyAndScrub(__dirname, 'sample-approval-test', { a: "some text in an object" }, scrubber);
approvals~verifyWithControl(namer, writer, [reporterFactory], [optionsOverride])
This allows you to take full control of naming and writing files before verifying.
For an example that we use to generate the docs within the readme, check out the test/readmeTests.js in this project.
Kind: inner method of approvals
| Param | Type | | --- | --- | | namer | Object | | writer | Object | | [reporterFactory] | function | | [optionsOverride] | Object |
Source Control
The approvals tool generates 2 files and you likely want to ignore one and check in the other.
*.received.*
files should be IGNORED.*.approved.*
You'll likely want to keep the approved files in source control.
Git
If you're using Git add this to your .gitignore
:
*.received.*
Another issue that can crop up is the line-endings as git can change the files depending on checking out the file on linux/mac vs windows.
A possible fix for this is to add *.approved.* binary
to your .gitattributes
(but that makes viewing diffs as you check in a pain).
Contributing
Check out the guidelines!
License
Copyright (c) 2012-2017 Llewellyn Falco, Jason Jarrett Licensed under the Apache license.