'use strict' /* global describe, it, before, after */ const spawn = require('cross-spawn') const path = require('path') const which = require('which') const rimraf = require('rimraf') const cpr = require('cpr') const fs = require('fs') require('chai').should() describe('integration tests', () => { it('should run as a shell script with no arguments', (done) => { testArgs('./bin.js', [], done) }) it('should run as a shell script with arguments', (done) => { testArgs('./bin.js', ['a', 'b', 'c'], done) }) it('should run as a node script with no arguments', (done) => { testArgs('node bin.js', [], done) }) it('should run as a node script with arguments', (done) => { testArgs('node bin.js', ['x', 'y', 'z'], done) }) describe('path returned by "which"', () => { it('should match the actual path to the script file', (done) => { which('node', (err, resolvedPath) => { if (err) return done(err) testArgs(`${resolvedPath.replace('Program Files (x86)', 'Progra~2') .replace('Program Files', 'Progra~1')} bin.js`, [], done) }) }) it('should match the actual path to the script file, with arguments', (done) => { which('node', (err, resolvedPath) => { if (err) return done(err) testArgs(`${resolvedPath.replace('Program Files (x86)', 'Progra~2') .replace('Program Files', 'Progra~1')} bin.js`, ['q', 'r'], done) }) }) }) // see #177 it('allows --help to be completed without returning help message', (done) => { testCmd('./bin.js', ['--get-yargs-completions', '--h'], (code, stdout) => { if (code) { done(new Error(`cmd exited with code ${code}`)) return } stdout.should.not.match(/generate bash completion script/) stdout.should.match(/--help/) return done() }) }) // see #497 it('flushes all output when --help is executed', function (done) { if (process.platform === 'win32' && process.version.match(/^v0.10/)) { // Doesn’t work in CI for some reason. return this.skip() } testCmd('./issue-497.js', ['--help'], (code, stdout) => { if (code) { done(new Error(`cmd exited with code ${code}`)) return } stdout.should.match(/--o999/) stdout.should.not.match(/never get here/) return done() }) }) it('correctly fills positional command args with preceding option', (done) => { testCmd('./opt-assignment-and-positional-command-arg.js', ['--foo', 'fOo', 'bar', 'bAz'], (code, stdout) => { if (code) { done(new Error(`cmd exited with code ${code}`)) return } const argv = JSON.parse(stdout) argv._.should.deep.equal(['bar']) argv.foo.should.equal('fOo') argv.baz.should.equal('bAz') return done() }) }) it('correctly fills positional command args with = assignment in preceding option', (done) => { testCmd('./opt-assignment-and-positional-command-arg.js', ['--foo=fOo', 'bar', 'bAz'], (code, stdout) => { if (code) { done(new Error(`cmd exited with code ${code}`)) return } const argv = JSON.parse(stdout) argv._.should.deep.equal(['bar']) argv.foo.should.equal('fOo') argv.baz.should.equal('bAz') return done() }) }) if (process.platform !== 'win32') { describe('load root package.json', () => { before(function (done) { this.timeout(10000) // create a symlinked, and a physical copy of yargs in // our fixtures directory, so that we can test that the // nearest package.json is appropriately loaded. cpr('./', './test/fixtures/yargs', { filter: /node_modules|example|test|package\.json/ }, () => { fs.symlinkSync(process.cwd(), './test/fixtures/yargs-symlink') return done() }) }) describe('version #', () => { it('defaults to appropriate version # when yargs is installed normally', (done) => { testCmd('./normal-bin.js', ['--version'], (code, stdout) => { if (code) { return done(new Error(`cmd exited with code ${code}`)) } stdout.should.match(/9\.9\.9/) return done() }) }) it('defaults to appropriate version # when yargs is symlinked', (done) => { testCmd('./symlink-bin.js', ['--version'], (code, stdout) => { if (code) { return done(new Error(`cmd exited with code ${code}`)) } stdout.should.match(/9\.9\.9/) return done() }) }) }) describe('parser settings', () => { it('reads parser config settings when yargs is installed normally', (done) => { testCmd('./normal-bin.js', ['--foo.bar'], (code, stdout) => { if (code) { return done(new Error(`cmd exited with code ${code}`)) } stdout.should.match(/foo\.bar/) return done() }) }) it('reads parser config settings when yargs is installed as a symlink', (done) => { testCmd('./symlink-bin.js', ['--foo.bar'], (code, stdout) => { if (code) { return done(new Error(`cmd exited with code ${code}`)) } stdout.should.match(/foo\.bar/) return done() }) }) it('reads parser config settings when somebody obscures require.main', (done) => { testCmd('./no-require-main.js', ['--foo.bar'], (code, stdout) => { if (code) { return done(new Error(`cmd exited with code ${code}`)) } stdout.should.match(/foo\.bar/) return done() }) }) it('reads parser config settings when entry file has no extension', (done) => { testCmd('./no-extension', ['--foo.bar'], (code, stdout) => { if (code) { return done(new Error(`cmd exited with code ${code}`)) } stdout.should.match(/foo\.bar/) return done() }) }) }) after(() => { rimraf.sync('./test/fixtures/yargs') fs.unlinkSync('./test/fixtures/yargs-symlink') }) }) } }) function testCmd (cmd, args, cb) { const cmds = cmd.split(' ') const bin = spawn(cmds[0], cmds.slice(1).concat(args.map(String)), { cwd: path.join(__dirname, '/fixtures') }) let stdout = '' bin.stdout.setEncoding('utf8') bin.stdout.on('data', (str) => { stdout += str }) let stderr = '' bin.stderr.setEncoding('utf8') bin.stderr.on('data', (str) => { stderr += str }) bin.on('close', (code) => { cb(code, stdout, stderr) }) } function testArgs (cmd, args, done) { testCmd(cmd, args, (code, stdout, stderr) => { if (code) { done(new Error(`cmd ${cmd} ${args} exited with code ${code}\n${stdout}\n${stderr}`)) return } const _ = JSON.parse(stdout) _.map(String).should.deep.equal(args.map(String)) done() }) }