@putout/plugin-tape 
Putout
plugin helps to apply best parctises for tests written with supertape.
Install
npm i @putout/plugin-tape -D
Rules
{
"rules": {
"tape/apply-stub-operator": "on",
"tape/apply-with-name": "on",
"tape/add-t-end": "on",
"tape/add-stop-all": "on",
"tape/add-await-to-re-import": "on",
"tape/remove-useless-t-end": "on",
"tape/sync-with-name": "on",
"tape/switch-expected-with-result": "on",
"tape/convert-tape-to-supertape": "on",
"tape/convert-throws-to-try-catch": "on",
"tape/convert-does-not-throw-to-try-catch": "on",
"tape/convert-called-with-args": "on",
"tape/convert-called-with-to-called-with-no-args": "on",
"tape/convert-called-with-no-args-to-called-with": "on",
"tape/convert-equal-to-called-once": "on",
"tape/convert-deep-equal-to-equal": "on",
"tape/expand-try-catch-arguments": "on",
"tape/convert-emitter-to-promise": "on",
"tape/convert-ok-to-match": "on",
"tape/convert-ok-to-called-with": "on",
"tape/convert-match-regexp-to-string": "on",
"tape/add-args": "on",
"tape/declare": "on",
"tape/remove-default-messages": "on",
"tape/remove-useless-not-called-args": "on",
"tape/remove-only": "on",
"tape/remove-skip": "on",
"tape/remove-stop-all": "on"
}
}
switch-expected-with-result
β Incorrect code example
test('plugin-apply-destructuring: transform: array: destructuring', (t) => {
t.eqaul(expected, result);
t.end();
});
β
Correct code example
test('plugin-apply-destructuring: transform: array: destructuring', (t) => {
t.eqaul(result, expected);
t.end();
});
convert-tape-to-supertape
β Incorrect code example
const test = require('tape');
β
Correct code example
const test = require('supertape');
convert-throws-to-try-catch
β Incorrect code example
const test = require('supertape');
test('some message', (t) => {
t.throws(copymitter, /from should be a string!/, 'should throw when no args');
t.end();
});
β
Correct code example
const tryCatch = require('try-catch');
const test = require('supertape');
test('some message', (t) => {
const [error] = tryCatch(copymitter);
t.equal(error.message, 'from shoulde be a string!', 'should throw when no args');
t.end();
});
convert-does-not-throw-to-try-catch
β Incorrect code example
const test = require('supertape');
test('some message', (t) => {
t.doesNotThrow(copymitter, 'should throw when no args');
t.end();
});
β
Correct code example
const test = require('supertape');
const tryCatch = require('try-catch');
test('some test', (t) => {
const [error] = tryCatch(copymitter);
t.notOk(error, 'should not throw when no args');
t.end();
});
convert-called-with-args
β Incorrect code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
const fn = stub();
fn();
t.calledWith(fn, 'hello');
t.end();
});
β
Correct code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
const fn = stub();
fn();
t.calledWith(fn, ['hello']);
t.end();
});
convert-equal-to-called-once
No need to use equal
, supertape
supports calledOnce
.
β Incorrect code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
const fn = stub();
fn();
t.equal(fn.callCount, 1);
t.end();
});
β
Correct code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
const fn = stub();
fn();
t.calledOnce(fn);
t.end();
});
convert-deep-equal-to-equal
Use equal
when comparing with primitives, deepEqual
for Objects
and Arrays
;
β Incorrect code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
t.deepEqual(x, 5);
t.end();
});
β
Correct code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
t.equal(x, 5);
t.end();
});
convert-called-with-to-called-with-no-args
β Incorrect code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
const fn = stub();
fn();
t.calledWith(fn);
t.end();
});
β
Correct code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
const fn = stub();
fn();
t.calledWithNoArgs(fn);
t.end();
});
convert-called-with-no-args-to-called-with
β Incorrect code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
const fn = stub();
fn();
t.calledWithNoArgs(fn, [1, 2]);
t.end();
});
β
Correct code example
const test = require('supertape');
const {stub} = test;
test('some message', (t) => {
const fn = stub();
fn();
t.calledWith(fn, [1, 2]);
t.end();
});
convert-emitter-to-promise
β Incorrect code example
test('copymitter', (t) => {
const cp = copymitter(from, to, ['1']);
cp.on('end', (t) => {
t.end();
});
});
β
Correct code example
const {once} = require('events');
test('copymitter', async (t) => {
const cp = copymitter(from, to, ['1']);
await once(cp, 'end');
t.end();
});
expand-try-catch-arguments
β Incorrect code example
import tryCatch from 'try-catch';
test('some message', (t) => {
const fn = () => copymitter('/hello');
const [error] = tryCatch(fn);
t.equal(error.message, 'to should be a string!');
t.end();
});
β
Correct code example
import tryCatch from 'try-catch';
test('some message', (t) => {
const [error] = tryCatch(copymitter, '/hello');
t.equal(error.message, 'to should be a string!');
t.end();
});
apply-stub-operator
β Incorrect code example
test('some message', (t) => {
t.ok(fn.calledWith(a));
t.end();
});
β
Correct code example
test('some message', (t) => {
t.calledWith(fn, [a]);
t.end();
});
apply-with-name
β Incorrect code example
test('should call init before show', (t) => {
const init = stub();
const show = stub();
t.calledInOrder([init, show]);
t.end();
});
β
Correct code example
test('should call init before show', (t) => {
const init = stub().withName('init');
const show = stub().withName('show');
t.calledInOrder([init, show]);
t.end();
});
sync-with-name
β Incorrect code example
test('should call init before show', (t) => {
const init = stub().withName('show');
const show = stub().withName('show');
t.calledInOrder([init, show]);
t.end();
});
β
Correct code example
test('should call init before show', (t) => {
const init = stub().withName('init');
const show = stub().withName('show');
t.calledInOrder([init, show]);
t.end();
});
declare
mockImport
β Incorrect code example
import {stub} from 'supertape';
mockImport('fs/promises', {
readFile: stub().resolves(''),
});
β
Correct code Example
import {stub} from 'supertape';
import {createMockImport} from 'mock-import';
const {
mockImport,
stopAll,
reImport,
} = createMockImport(import.meta.url);
mockImport('fs/promises', {
readFile: stub().resolves(''),
});
tape
β Incorrect code example
test('xxx', (t) => {
const a = stub();
t.end();
});
β
Correct code example
import {
test,
stub,
} from 'supertape';
test('xxx', (t) => {
const a = stub();
t.end();
});
add-args
β Incorrect code example
test('xxx', () => {
t.end();
});
β
Correct code example
test('xxx', (t) => {
t.end();
});
add-t-end
β Incorrect code example
test('xxx', () => {
});
β
Correct code example
test('xxx', (t) => {
t.end();
});
add-await-to-re-import
β Incorrect code example
test('stop-all: should be called', (t) => {
const read = reImport('./read');
t.end();
});
β
Correct code example
test('stop-all: should be called', async (t) => {
const read = await reImport('./read');
t.end();
});
add-stop-all
When you write test mocking ESM
with mockImport()
never forget to call stopAll()
when you no longer need it. This leads to bugs in tests which are hard to find, each test should be checked with the one which pass when called alone but fail when called with others.
β Incorrect code example
test('stop-all: should be called', (t) => {
mockImport('fs/promises', {
readFile: stub(),
});
t.end();
});
β
Correct code example
test('stop-all: should be called', (t) => {
mockImport('fs/promises', {
readFile: stub(),
});
stopAll();
t.end();
});
remove-useless-t-end
β Incorrect code example
test('test: remove me', () => {
t.end();
t.end();
});
β
Correct code example
test('test: remove me', () => {
t.end();
});
convert-ok-to-match
β Incorrect code example
t.ok(result.includes('hello'));
β
Correct code example
t.match(result, /hello/);
convert-ok-to-match
β Incorrect code example
t.ok(set.calledWith(1, 2));
β
Correct code example
t.calledWith(set, [1, 2]);
convert-equal-to-not-ok
β Incorrect code example
t.equal(error, null);
β
Correct code example
t.notOk(error);
convert-equal-to-ok
β Incorrect code example
t.equal(result, true);
β
Correct code example
t.ok(result);
convert-match-regexp-to-string
β Incorrect code example
t.match(result, RegExp('hello'));
β
Correct code example
t.match(result, 'hello');
remove-default-messages
supertape
will put this information for you, and it is always the same.
No need to repeat the same information twice on one line, better to avoid it.
β Incorrect code example
t.equal(result, expected, 'should equal');
β
Correct code example
t.equal(result, expected);
remove-useless-not-called-args
β Incorrect code example
t.notCalled(fn, []);
β
Correct code example
t.notCalled(fn);
remove-only
β Incorrect code example
test.only('some test', (t) => {
t.end();
});
β
Correct code Example
test('some test', (t) => {
t.end();
});
remove-skip
β Incorrect code example
test.skip('some test', (t) => {
t.end();
});
remove-stop-all
When reImport()
or reRequire
not called, stopAll()
is redundant and should be removed.
β Incorrect code example
test('some test', (t) => {
stopAll();
t.end();
});
β
Correct code Example
test('some test', (t) => {
t.end();
});
License
MIT