Skip to content

node-modules/coffee

Repository files navigation

Coffee

Test command line on Node.js.


NPM versionBuild Statuscodecov.ioNPM downloads

Install

$ npm i coffee --save-dev

Usage

Coffee is useful for test command line in test frammework (like Mocha).

Fork

You can use fork for spawning Node processes.

constcoffee=require('coffee');describe('cli',()=>{it('should fork node cli',()=>{returncoffee.fork('/path/to/file.js').expect('stdout','12\n').expect('stderr',/34/).expect('code',0).end();});});

In file.js

console.log(12);console.error(34);

You can pass args and opts to child_process fork.

coffee.fork('/path/to/file.js',['args'],{execArgv: ['--inspect']}).expect('stdout','12\n').expect('stderr','34\n').expect('code',0).end();

And more:

coffee.fork('/path/to/file.js')// print origin stdio.debug()// inject a script.beforeScript(mockScript)// interact with prompt.waitForPrompt().write('tz\n')// string strict equals.expect('stdout','abcdefg')// regex.expect('stdout',/^abc/)// multiple.expect('stdout',['abcdefg',/abc/]).expect('code',0).end();

see the API chapter below for more details.

Spawn

You can also use spawn for spawning normal shell scripts.

coffee.spawn('cat').write('1').write('2').expect('stdout','12').expect('code',0).end();

Rule

code

Check the exit code.

coffee.fork('/path/to/file.js',['args']).expect('code',0)// .expect('code', 1).end();

stdout / stderr

Check the stdout and stderr.

coffee.fork('/path/to/file.js',['args']).expect('stdout','12\n').expect('stderr','34\n').expect('code',0).end();

custom

Support custom rules, see test/fixtures/extendable for more details.

const{ Coffee, Rule }=require('coffee');classFileRuleextendsRule{constructor(opts){super(opts);// `args` is which pass to `expect(type, ...args)`, `expected` is the first args.const{ args, expected }=opts;}assert(actual,expected,message){// do sthreturnsuper.assert(fs.existsSync(expected),true,`should exists file ${expected}`);}}classMyCoffeeextendsCoffee{constructor(...args){super(...args);this.setRule('file',FileRule);}staticfork(modulePath,args,opt){returnnewMyCoffee({method: 'fork',cmd: modulePath, args, opt,});}}

Usage:

// test/custom.test.jsconstcoffee=require('MyCoffee');coffee.fork('/path/to/file.js',['args']).expect('file',`${root}/README.md`);.notExpect('file',`${root}/not-exist`);

Support multiple process coverage with nyc

Recommend to use nyc for coverage, you can use any test frammework supported by nyc.

API

coffee.spawn

Run command using child_process.spawn, then return Coffee instance.

Arguments see child_process.spawn

coffee.fork

Run command using child_process.fork, then return Coffee instance.

Arguments see child_process.fork

coffee.Coffee

Assertion object

coffee.expect(type, ...args)

Assert type with expected value, expected value can be string, regular expression, and array.

coffee.spawn('echo',['abcdefg']).expect('stdout','abcdefg').expect('stdout',/^abc/).expect('stdout',['abcdefg',/abc/]).end();

Accept type: stdout / stderr / code / error, see built-in rules description above.

coffee.notExpect(type, ...args)

The opposite assertion of expect.

coffee.includes(type, ...args)

Assert type with expected string value, expected value should be string only.

coffee.spawn('echo',['abcdefg']).includes('stdout','abc').expect('stdout',['abc','efg']).end();

Accept type: stdout / stderr, see built-in rules description above.

coffee.notIncludes(type, ...args)

The opposite assertion of includes.

coffee.write(data)

Write data to stdin.

coffee.fork(path.join(fixtures,'stdin.js')).write('1\n').write('2').expect('stdout','1\n2').end();

coffee.writeKey(...args)

Write special key sequence to stdin, support UP / DOWN / LEFT / RIGHT / ENTER / SPACE.

All args will join as one key.

coffee.fork(path.join(fixtures,'stdin.js')).writeKey('1','ENTER','2').expect('stdout','1\n2').end();

coffee.waitForPrompt(bool)

If you set false, coffee will write stdin immediately, otherwise will wait for prompt message.

coffee.fork('/path/to/cli',['abcdefg']).waitForPrompt().write('tz\n')// choose the second item.writeKey('DOWN','DOWN','ENTER');.end(done);

cli process should emit prompt message:

Or use coffee.on('stdout', callback) instead, see docs below.

constreadline=require('readline');constrl=readline.createInterface({input: process.stdin,output: process.stdout});functionask(q,callback){process.send({type: 'prompt'});rl.question(q,callback);}ask('What\'s your name? ',answer=>{console.log(`hi, ${answer}`);ask('How many coffee do you want? ',answer=>{console.log(`here is your ${answer} coffee`);rl.close();});});

coffee.end([callback])

Callback will be called after completing the assertion, the first argument is Error if throw exception.

coffee.fork('path/to/cli').expect('stdout','abcdefg').end(done);// recommended to left undefind and use promise style.const{ stdout, stderr, code }=awaitcoffee.fork('path/to/cli').end();assert(stdout.includes(abcdefg));

coffee.on(event, callback)

Emit stdout/stderr event.

use for kill long-run process:

coffee.fork('path/to/cli').on('stdout',(buf,{ proc })=>{if(buf.includes('egg-ready')){proc.exitCode=0;proc.kill();}}).expect('stdout','egg-ready').end(done);

use for prompt:

// do not call `waitForPrompt` / `write` / `writeKey`coffee.fork('path/to/cli').on('stdout',(buf,{ proc })=>{if(buf.includes('Your Name: ')){proc.stdin.write('TZ\n');}}).expect('stdout','Your Name: TZ\n').end(done);

coffee.debug(level)

Write data to process.stdout and process.stderr for debug

level can be

  • 0 (default): pipe stdout + stderr
  • 1: pipe stdout
  • 2: pipe stderr
  • false: disable

Alternative you can use COFFEE_DEBUG env.

coffee.coverage()

If you set false, coffee will not generate coverage.json, default: true.

coffee.beforeScript(scriptFile)

Add a hook script before fork child process run.

coffee.Rule

Assertion Rule base class.

LICENSE

Copyright (c) 2017 - 2019 node-modules. Licensed under the MIT license.

About

Test command line on Node.js

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 10