Joker has primitive support for plugins. You can register any expectation or/and
any middleware by calling joker.register
.
const fn = () => {};
new Joker().register('foo', fn);
Or you may want to register many functions at once.
const fn = () => {};
const fn1 = () => {};
joker.register({ baz: fn, bar: fn1 });
Register an after
filter.
await new Joker()
.run(cmd)
.after(fn)
.after(fn2)
.end();
The function to be called
instance for chaining
Specify a base command.
Very convenient when testing the same executable again and again.
await new Joker()
.base('node')
.run('--version')
.stdout('11.10.1')
.run(`-e "console.log('hello world')"`)
.stdout('hello world')
.end();
instance for chaining
Register a before
filter.
await new Joker()
.before(fn)
.before(fn2)
.run(cmd)
.end();
The function to be called
instance for chaining
Every Joker
instance can be cloned, which allows you to build "templates" for tests. Here's some examples:
const template = new Joker()
.cwd(path.join(__dirname, 'fixtures'))
.run('echo test');
const test1 = await template
.clone()
.stdout(/test/)
.end()
const test2 = await template
.clone()
.stdout('test')
.end();
clone of the current instance
Assert that a specific exit code is thrown.
await new Joker()
.run('todo add')
.code(1)
.end();
The expected exit code
instance for chaining
Set the current working directory for the command that will be executed.
Change the current working directory of the main command (specified with run
).
Please note that this won't affect any other commands like unlink
etc.
await new Joker()
.cwd(__dirname)
.run('pwd')
.stdout(/test$/)
.end();
instance for chaining
Run the given test
If no argument is passed, a Promise is returned
const result = await new Joker()
.run('echo a b c', (err) => {})
.stdout('a b c')
.end();
expect(result.message).toEqual(
'this err message is only shown after Joker is finished running'
);
You can also pass callback functions if you would like. This will not return a Promise.
await new Joker()
.run('echo a b c')
.stdout('a b c')
.end((err) => {});
The same might be accomplished with supplying a function to run
:
await new Joker()
.run('echo a b c', (err) => {})
.stdout('a b c')
.end((err) => {});
The callback to fire after all Joker jobs are finished
instance for chaining
Set environment variable.
await new Joker()
.env('foo', 'bar')
.env('baz', 'boo')
.run('node --version')
.stdout('11.10.1')
.end();
The name of the environmental variable
instance for chaining
Execute a command that won't be tested. It is useful for running commands
that prepare the command that is tested with the run
method.
await new Joker()
.writeFile('LICENSE', 'MIT License')
.exec('git add -a')
.exec('git commit -m "Add LICENSE"')
.run('git log')
.stdout(/LICENSE/)
.end();
By default the commands will inherit the "environment" for the main command which includes environment variables, cwd, timeout. However, you can override this by supplying a different "environment":
await new Joker()
.exec('git add LICENSE', { timeout: 4, cwd: '/tmp' })
.run('git log')
.stdout(/LICENSE/)
.end();
The command you want to run
The configuration of the environment the test will be run in
instance for chaining
Check if a file or a directory exists.
await new Joker()
.run('mkdir /tmp/test')
.exist('/tmp/test')
.end();
The path to check for existance
instance for chaining
Register an expectation
import expect from 'expect';
await new Joker()
.run('ls')
.expect((result) => {
if (result.stdout !== 'Unicorns') {
return new Error('OMG');
}
expect(res.stderr).toEqual('');
expect(res.stdout).toEqual('Unicorns');
expect(result.code).toEqual(0);
expect(result.killed).toEqual(false);
})
.end();
The custom assertion you want to register, takes Result as an argument
instance for chaining
Match the content of a file.
You can match the contexts against an exact string
await new Joker()
.writeFile(file, 'Hello')
.run('node void.js')
.match(file, 'Hello')
.unlink(file)
.end(done);
You can also match against a regular expression
await new Joker()
.writeFile(file, 'Hello')
.run('node void.js')
.match(file, /ello/)
.unlink(file)
.end(done);
The path of the file who's contents we want to match against
The string or regular expression to match against
instance for chaining
Create a new directory.
await new Joker()
.mkdir('xml-database')
.run('this does stuff with the xml-database directory')
.end();
The name of the folder we want to create
instance for chaining
Register an interactive prompt
Detect a prompt for user input. Accepts a String or RegExp that appears in
the the stdout stream. Must be paired with .respond
.
await new Joker()
.run(cmd)
.on('Your name: ')
.respond('Joe User\n')
.end();
The pattern to listen for
instance for chaining
Register an interactive prompt response
In more detail, this method writes a response to the stdin stream when a prompt is detected
await new Joker()
.run(cmd)
.on('Your name: ')
.respond('Joe User\n')
.end();
The response to send after an event has occured
instance for chaining
Remove a directory
await new Joker()
.mkdir('xml-database')
.run('this does stuff with the xml-database directory')
.rmdir('xml-database')
.end();
The path of the folder you want to remove
instance for chaining
Specify a command to run. Assertions will test the stderr
and stdout
from
the command registered with run
.
await new Joker()
.run('node --version')
.stdout('11.10.1')
.end();
run
commandsawait new Joker()
.run('node --version')
.stdout('11.10.1')
.run(`node -e "console.log('Hello World!')"`)
.stdout('Hello World!')
.end();
await new Joker()
.run('node --version')
.stdout('11.10.1')
.run('echo testing123')
.stdout('testign123')
.end();
instance for chaining
Register a "stderr" expectation.
await new Joker()
.run('todo add')
.stderr('Please specify a todo')
.end();
The regular expression or string to test against
instance for chaining
Set data to pass to stdin
await new Joker()
.run('rev')
.stdin('foobar')
.stdout('raboof')
.end();
The standard input that will be passed as to the run
commands
instance for chaining
Register a "stdout" expectation.
await new Joker()
.run('ls')
.stdout('LICENSE Makefile')
.end();
Works with regular expressions too.
await new Joker()
.run('time')
.stdout(/system/)
.end();
You can also combine regular expressions and string assertions
await new Joker()
.run('echo foo')
// Test for an exact string
.stdout('foo')
// Test using a regular expression
.stdout(/foo/)
.done();
The regular expression or string to test against
instance for chaining
Set a timeout for the main command that you are about to test
await new Joker()
.timeout(1) // ms
.run('cat /dev/null')
.end();
The timeout in milliseconds
instance for chaining
Remove a file
await new Joker()
.writeFile('my-file', data)
.run('this does stuff with my file')
.unlink('my-file')
.end();
The path you want to write to unlink
instance for chaining
Create a new file with the given content
. This is a small wrapper over fs.writeFile
.
Without content:
await new Joker()
.writeFile(pathToFile)
.end();
With content:
await new Joker()
.writeFile(pathToFile, data)
.end();
The path you want to write to
The content to be written to the file
instance for chaining
Generated using TypeDoc
Hello World!
import Joker from '@amilajack/joker'; await new Joker() .run('node --version') .stdout('v11.10.0') .end();
Preparing a test
import Joker from '@amilajack/joker'; await new Joker() // Create the file before the test is run .exec(`echo "console.log('hello world')" > hello.js`) .run('node hello.js') .stdout('hello world') .end();
Setting up the environment
await new Joker() .cwd(path.join(__dirname, 'fixtures')) .env('NODE_ENV', 'production') .before('touch /tmp/test') .run('ls /tmp/') .stdout(/test/) .code(0) .end();
Custom expectations
While Joker comes with built-in expectations, you can use your own too.
await new Joker() .run('unicorns') .expect((result) => { if (result.stdout !== 'unicorns') { return new Error('NO!'); } }) .end();
Usage with a test runner
Joker plays nice with any test runner out there.
Jest
Here is a minimal example how you could use it with Jest using async/await:
describe('todo add', () => { it('adds a new todo item', async () => { const result = await new Joker() .run('todo add') .stdout('A new todo has been added') .end(); expect(result.stdout).toMatchSnapshot(); }); });
Options
Joker can strip newlines and colors. You can tell it to do so by passing an object that looks like this. Joker defaults to showing colors and new lines.
const options = { colors: false, newLines: false }; new Joker(options)