text: var assert = require('assert');
  var sinon = require('sinon');
  var path = require('path');
  var fs = require('fs');
  var Vow = require('vow');
  
  var Checker = require('../../lib/checker');
  var ConfigGenerator = require('../../lib/config/generator');
  
  describe('lib/config/generator', function() {
      var _path = path.resolve(__dirname, '../../lib/config/generator.js');
      var crockfordPresetChoice = { '\u001b[32mPlease choose a preset number:\u001b[39m': '2' };
  
      // jscs:disable maximumLineLength
      var crockfordViolationsAllExceptions = {
          '\u001b[32mrequireMultipleVarDecl\u001b[39m: Create an (e)xception for this rule, or (f)ix the errors yourself?': 'e',
          '\u001b[32mdisallowDanglingUnderscores\u001b[39m: Create an (e)xception for this rule, or (f)ix the errors yourself?': 'e',
          '\u001b[32mrequireSpaceAfterKeywords\u001b[39m: Create an (e)xception for this rule, or (f)ix the errors yourself?': 'e',
          '\u001b[32mrequireBlocksOnNewline\u001b[39m: Create an (e)xception for this rule, or (f)ix the errors yourself?': 'e',
          '\u001b[32mdisallowSpaceBeforeBinaryOperators\u001b[39m: Create an (e)xception for this rule, or (f)ix the errors yourself?': 'e'
      };
      // jscs:enable maximumLineLength
  
      var expectedConfig = {
          preset: 'crockford',
          requireMultipleVarDecl: null,
          disallowDanglingUnderscores: null,
          requireSpaceAfterKeywords: null,
          requireBlocksOnNewline: null,
          disallowSpaceBeforeBinaryOperators: null
      };
      var generator;
  
      beforeEach(function() {
          sinon.stub(console, 'log');
          generator = new ConfigGenerator();
      });
  
      afterEach(function() {
          rAfter();
      });
  
      function rAfter() {
          if (console.log.restore) {
              console.log.restore();
          }
      }
  
      function getChecker() {
          var checker = new Checker();
          checker.registerDefaultRules();
          return checker;
      }
  
      it('checks a given path against all registered presets', function() {
          var checkPathStub = sinon.stub(Checker.prototype, 'checkPath');
          // For preventing subsequent steps from running
          var showErrorCountsStub = sinon.stub(generator, '_showErrorCounts').throws();
  
          var checker = getChecker();
  
          var numPresets = Object.keys(checker.getConfiguration().getRegisteredPresets()).length;
  
          generator.generate(_path);
          assert.ok(checkPathStub.callCount === numPresets);
  
          checkPathStub.restore();
          showErrorCountsStub.restore();
      });
  
      it('displays a count of errors for every preset', function(done) {
          var stub = sinon.stub(generator, '_getUserPresetChoice').throws();
          var presetNames = Object.keys(getChecker().getConfiguration().getRegisteredPresets());
  
          generator.generate(_path)
          .then(null, function() {
              var output = console.log.getCall(1).args[0];
  
              presetNames.forEach(function(name) {
                  assert.ok(output.indexOf(name) !== -1);
              });
  
              stub.restore();
              done();
          });
      });
  
      it('prompts the user to choose a preset', function(done) {
          var stub = sinon.stub(generator, '_showPrompt').throws();
          generator.generate(_path).then(null, function() {
              var prompt = stub.getCall(0).args[0].name;
              assert.ok(prompt.indexOf('Please choose a preset number:') !== -1);
  
              stub.restore();
              done();
          });
      });
  
      it('prompts the user to create an exception or fix a given rule', function(done) {
          var stub = sinon.stub(generator, '_getUserPresetChoice').returns(crockfordPresetChoice);
          var getViolationsStub = sinon.stub(generator, '_showPrompt').throws();
  
          generator.generate(_path).then(null, function() {
              var errorPrompts = getViolationsStub.getCall(0).args[0];
              assert.ok(errorPrompts.length);
              errorPrompts.forEach(function(prompt) {
                  assert.ok(prompt.name.indexOf('(e)xception') !== -1);
                  assert.ok(prompt.name.indexOf('(f)ix') !== -1);
              });
              stub.restore();
              getViolationsStub.restore();
              done();
          });
      });
  
      it('generates a .jscsrc file with the user\'s violation choices', function(done) {
          var presetChoiceStub = sinon.stub(generator, '_getUserPresetChoice').returns(crockfordPresetChoice);
          var getViolationsStub = sinon.stub(generator, '_getUserViolationChoices')
                                  .returns(Vow.cast(crockfordViolationsAllExceptions));
          var fsStub = sinon.stub(fs, 'writeFileSync');
          var assertConfigEquality = function(c1, c2) {
              for (var prop in c1) {
                  assert.ok(c1[prop] === c2[prop]);
              }
          };
  
          generator.generate(_path).then(function() {
              var configPath = fsStub.getCall(0).args[0];
              var config = JSON.parse(fsStub.getCall(0).args[1]);
              assert.ok(configPath === process.cwd() + '/.jscsrc');
              assertConfigEquality(expectedConfig, config);
              presetChoiceStub.restore();
              getViolationsStub.restore();
              fsStub.restore();
              done();
          });
      });
  });
  