showdown/test/unit/cli.js
Estevao Soares dos Santos c3411a567d fix(cli): cli now works properly
The CLI was completely rewrote. Changed dependency from yargs to
commanderjs,
which is cleaner, faster and has no dependencies.
Also added a complete testsuite for the cli.

Merged branch 'cli_refactor' into develop

Closes #893, #894
2022-03-03 12:48:23 +00:00

294 lines
10 KiB
JavaScript

var fs = require('fs'),
path = require('path'),
chai = require('chai'),
expect = chai.expect,
chaiMatch = require('chai-match'),
execSync = require('child_process').execSync,
spawnSync = require('child_process').spawnSync,
cmd = 'node src/cli/cli.js',
packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
require('sinon');
chai.should();
chai.use(chaiMatch);
/**
* Spawns a CLI process synchrously
* @param {string|null} command
* @param {string[]} args
* @param {{}} [options]
* @returns {{output: *, stdout: string, stderr: string, status: number}}
*/
function spawnCLI (command, args, options) {
'use strict';
var nargs = ['src/cli/cli.js'];
if (command) { nargs.push(command);}
args = nargs.concat(args);
var otp = spawnSync('node', args, options),
stdout = otp.stdout.toString(),
stderr = otp.stderr.toString(),
output = otp.output[0],
status = otp.status;
return {stdout: stdout, stderr: stderr, output: output, status: status};
}
describe('showdown cli', function () {
'use strict';
describe('without commands', function () {
it('should display help if no commands are specified', function () {
var proc = spawnCLI(null, [], {});
proc.status.should.equal(1);
proc.stderr.should.contain('CLI to Showdownjs markdown parser');
proc.stderr.should.contain('Usage:');
proc.stderr.should.contain('Options:');
proc.stderr.should.contain('Commands:');
proc.stdout.should.equal('');
});
describe('-h', function () {
it('should display help', function () {
var proc = spawnCLI(null, ['-h'], {});
proc.status.should.equal(0);
proc.stdout.should.contain('CLI to Showdownjs markdown parser');
proc.stdout.should.contain('Usage:');
proc.stdout.should.contain('Options:');
proc.stdout.should.contain('Commands:');
proc.stderr.should.equal('');
});
});
describe('-v', function () {
it('should display version', function () {
var proc = spawnCLI(null, ['-V'], {});
proc.status.should.equal(0);
proc.stdout.should.match(/^\d{1,2}\.\d{1,3}\.\d{1,3}/);
proc.stdout.should.match(/^(\d{1,2}\.\d{1,3}\.\d{1,3})/).and.capture(0).equals(packageJson.version);
proc.stderr.should.equal('');
});
});
});
describe('makehtml command', function () {
describe('makehtml without flags', function () {
it('should read from stdin and output to stdout', function () {
var proc = spawnCLI('makehtml', [], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.not.equal('');
});
});
describe('makehtml -p', function () {
it('should enable a flavor', function () {
var proc = spawnCLI('makehtml', ['-p', 'github'], {
input: 'this is a :smile:', // test the emoji option as a proxy
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stderr.should.contain('Enabling flavor github...');
proc.stdout.should.equal('<p>this is a 😄</p>');
//'Here in London'.should.match(/(here|there) in (\w+)/i).and.capture(1).equals('London');
});
it('should give an error if a flavor is not recognised', function () {
var proc = spawnCLI('makehtml', ['-p', 'foobar'], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(1);
});
});
describe('makehtml -c', function () {
it('should not parse emoji if config option is not passed', function () {
var proc = spawnCLI('makehtml', [], {
input: 'this is a :smile:',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stderr.should.not.contain('Enabling option emoji');
proc.stdout.should.equal('<p>this is a :smile:</p>');
});
it('should enable a showdown option', function () {
var proc = spawnCLI('makehtml', ['-c', 'emoji'], {
input: 'this is a :smile:',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stderr.should.contain('Enabling option emoji');
proc.stdout.should.equal('<p>this is a 😄</p>');
});
it('should ignore unrecognized options', function () {
var proc = spawnCLI('makehtml', ['-c', 'foobar'], {
input: 'foo',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stderr.should.contain('Enabling option foobar');
proc.stdout.should.equal('<p>foo</p>');
});
});
describe('makehtml -m', function () {
it('should mute information', function () {
var proc = spawnCLI('makehtml', ['-m', '-i'], {input: '**foo**'});
proc.status.should.equal(0);
expect(proc.output).to.be.null; // jshint ignore:line
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.equal('');
});
it('should mute everything, even errors', function () {
var proc = spawnCLI('makehtml', ['-m', '-i']);
proc.status.should.equal(1);
expect(proc.output).to.be.null; // jshint ignore:line
proc.stdout.should.equal('');
proc.stderr.should.equal('');
});
it('should not mute parsed html', function () {
var proc = spawnCLI('makehtml', ['-m', '-i'], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.equal('');
});
});
describe('makehtml -q', function () {
it('should not display information', function () {
var proc = spawnCLI('makehtml', ['-q', '-i'], {input: '**foo**'});
proc.status.should.equal(0);
expect(proc.output).to.be.null; // jshint ignore:line
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.match(/^\s*DONE!\s*$/);
});
it('should display errors', function () {
var proc = spawnCLI('makehtml', ['-q', '-i']);
proc.status.should.equal(1);
expect(proc.output).to.be.null; // jshint ignore:line
proc.stdout.should.equal('');
proc.stderr.should.match(/^ERROR:/);
});
it('should not mute parsed html', function () {
var proc = spawnCLI('makehtml', ['-q', '-i'], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.match(/^\s*DONE!\s*$/);
});
});
describe('makehtml -i -o', function () {
it('should read from stdin and output to stdout', function () {
var proc = spawnCLI('makehtml', ['-i', '-o'], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.not.equal('');
});
});
describe('makehtml -i <file> -o', function () {
it('should read from a file and output to stdout', function () {
var expectedOtp = fs.readFileSync('test/cli/basic.html', 'utf8').toString().trim(),
proc = spawnCLI('makehtml', ['-i', 'test/cli/basic.md'], {encoding: 'utf-8'});
proc.status.should.equal(0);
proc.stdout.should.equal(expectedOtp);
proc.stderr.should.not.equal('');
});
});
describe('makehtml -i -o <file>', function () {
it('should read from stdin and output to a file', function () {
execSync(cmd + ' makehtml -m -i -o .build/io1.html', {
encoding: 'utf8',
input: '**foo**'
});
var otp = fs.readFileSync('.build/io1.html', 'utf8').toString().trim(),
expectedOtp = '<p><strong>foo</strong></p>';
otp.trim().should.equal(expectedOtp);
});
});
describe('makehtml -i <file> -o <file>', function () {
it('should read from a file and output to a file', function () {
var expectedOtp = fs.readFileSync('test/cli/basic.html', 'utf8').toString().trim(),
proc = spawnCLI('makehtml', ['-i', 'test/cli/basic.md', '-o', '.build/io2.html'], {encoding: 'utf-8'}),
otp = fs.readFileSync('.build/io2.html', 'utf8').toString().trim();
otp.trim().should.equal(expectedOtp);
proc.stdout.should.not.equal(expectedOtp);
proc.stderr.should.equal('');
proc.status.should.equal(0);
});
});
describe('makehtml -a', function () {
it('should read from stdin and append to a file', function () {
fs.writeFileSync('.build/io3.html', '<p>foo</p>');
var expectedOtp = '<p>foo</p><p><strong>foo</strong></p>',
proc = spawnCLI('makehtml', ['-i', '-o', '.build/io3.html', '-a'], {
encoding: 'utf8',
input: '**foo**'
}),
otp = fs.readFileSync('.build/io3.html', 'utf8').toString().trim();
proc.status.should.equal(0);
otp.trim().should.equal(expectedOtp);
// since the output is to a file, messages are logged to stdout
proc.stdout.should.not.equal(expectedOtp);
// stderr should be empty
proc.stderr.should.equal('');
});
it('should ignore -a flag if -o <file> is missing', function () {
var expectedOtp = '<p><strong>foo</strong></p>',
proc = spawnCLI('makehtml', ['-a'], {encoding: 'utf8', input: '**foo**'});
proc.status.should.equal(0);
proc.stderr.should.not.equal('');
proc.stdout.should.equal(expectedOtp);
});
});
describe('makehtml -e', function () {
it('should load the extension', function () {
var expectedOtp = '<p><strong>bar</strong></p>',
extPath = path.resolve(__dirname + '/../mocks/mock-extension.js'),
proc = spawnCLI('makehtml', ['-i', '-o', '-e', extPath], {
encoding: 'utf8',
input: '**foo**'
});
proc.status.should.equal(0, 'Process exited with error state');
proc.stdout.trim().should.equal(expectedOtp);
});
});
});
});