diff --git a/test/server/validate.js b/test/server/validate.js index bd028f71..724b6b87 100644 --- a/test/server/validate.js +++ b/test/server/validate.js @@ -1,7 +1,10 @@ 'use strict'; +const fs = require('fs'); + const test = require('tape'); -const sinon = require('sinon'); +const withDiff = require('../sinon-called-with-diff'); +const sinon = withDiff(require('sinon')); const before = require('../before'); const dir = '../..'; @@ -35,6 +38,56 @@ test('validate: root: /', (t) => { t.end(); }); +test('validate: root: /home', (t) => { + const fn = sinon.stub(); + + validate.root('/home', (...args) => { + fn(...args); + + t.ok(fn.calledWith('root:', '/home'), 'should not call fn'); + t.end(); + }); +}); + +test('validate: root: stat', (t) => { + const fn = sinon.stub(); + const {stat} = fs; + + const error = 'ENOENT'; + fs.stat = (dir, fn) => fn(Error(error)); + + clean(); + require(exitPath); + stub(exitPath, fn); + + const {root} = require(validatePath); + + root('hello', fn); + + const msg = 'cloudcmd --root: %s'; + t.ok(fn.calledWith(msg, error), 'should call fn'); + + fs.stat = stat; + t.end(); +}); + +test('validate: packer: not valid', (t) => { + const fn = sinon.stub(); + + clean(); + require(exitPath); + stub(exitPath, fn); + + const {packer} = require(validatePath); + const msg = 'cloudcmd --packer: could be "tar" or "zip" only'; + + packer('hello'); + + t.ok(fn.calledWith(msg), 'should call fn'); + + t.end(); +}); + test('validate: editor: not valid', (t) => { const fn = sinon.stub(); diff --git a/test/sinon-called-with-diff.js b/test/sinon-called-with-diff.js new file mode 100644 index 00000000..5aca3e63 --- /dev/null +++ b/test/sinon-called-with-diff.js @@ -0,0 +1,57 @@ +'use strict'; + +/* eslint-disable no-console */ + +const chalk = require('chalk'); + +module.exports = (sinon) => { + const {stub} = sinon; + + sinon.stub = () => { + const fn = stub(); + const {calledWith:original} = fn; + + fn.calledWith = (...args) => { + if (original.apply(fn, args)) + return true; + + return calledWith.apply(fn, args); + }; + + return fn; + }; + + Object.assign(sinon.stub, stub); + + return sinon; +}; + +function calledWith(...args) { + if (!this.called) { + write(`expected to call with ${JSON.stringify(this.args)}, but not called at all\n`); + return false; + } + + const actual = this.args.pop(); + + write(`wrong arguments in ${this.func.name}`); + writeObjectActual('actual:', actual); + writeObjectExpected('expected:', args); + + return false; +} + +function write(str) { + process.stdout.write(chalk.red(str) + '\n'); +} + +function writeObjectActual(str, object) { + const json = JSON.stringify(object, null, 2); + console.log(str, chalk.yellow(json) + '\n'); +} + +function writeObjectExpected(str, object) { + const json = JSON.stringify(object, null, 2); + console.log(str, chalk.green(json) + '\n'); +} +