text: 'use strict';
  
  const fs = require('fs');
  
  const test = require('tape');
  const diff = require('sinon-called-with-diff');
  const sinon = diff(require('sinon'));
  
  const before = require('../before');
  const {connect} = before;
  const dir = '../..';
  
  const validatePath = `${dir}/server/validate`;
  const exitPath = `${dir}/server/exit`;
  const columnsPath = `${dir}/server/columns`;
  
  const validate = require(validatePath);
  const clear = require('clear-module');
  
  const {cache, resolve} = require;
  const stub = (name, exports) => {
      require(name);
      
      const resolved = resolve(name);
      cache[resolved].exports = exports;
  };
  
  test('validate: root: bad', (t) => {
      const config = {
          root: Math.random()
      };
      
      const success = ({done}) => {
          t.fail('should not create server');
          t.end();
          done();
      };
      
      const error = (e) => {
          t.equal(e.message, 'dir should be a string', 'should throw');
          t.end();
      };
      
      connect({config})
          .then(success)
          .catch(error);
  });
  
  test('validate: root: /', (t) => {
      const fn = sinon.stub();
      validate.root('/', fn);
      
      t.notOk(fn.called, 'should not call fn');
      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();
      
      clean();
      require(exitPath);
      stub(exitPath, fn);
      
      const {editor} = require(validatePath);
      const msg = 'cloudcmd --editor: could be "dword", "edward" or "deepword" only';
      
      editor('hello');
      
      t.ok(fn.calledWith(msg), 'should call fn');
      
      t.end();
  });
  
  test('validate: columns', (t) => {
      const fn = sinon.stub();
      
      clean();
      require(exitPath);
      stub(exitPath, fn);
      
      const {columns} = require(validatePath);
      
      columns('name-size-date');
      
      t.notOk(fn.called, 'should not call exit');
      t.end();
  });
  
  test('validate: columns: wrong', (t) => {
      const fn = sinon.stub();
      
      clean();
      clear(columnsPath);
      require(exitPath);
      stub(exitPath, fn);
      stub(columnsPath, {
          'name-size-date': '',
          'name-size': '',
      });
      
      const {columns} = require(validatePath);
      const msg = 'cloudcmd --columns: can be only one of: "name-size-date", "name-size"';
      
      columns('hello');
      
      t.ok(fn.calledWith(msg), 'should call exit');
      t.end();
  });
  
  function clean() {
      clear(validatePath);
      clear(exitPath);
  }
  
  