'use strict';

var _ramda;

function _load_ramda() {
  return _ramda = _interopRequireDefault(require('ramda'));
}

var _chai;

function _load_chai() {
  return _chai = require('chai');
}

var _version;

function _load_version() {
  return _version = _interopRequireDefault(require('../../../src/scope/models/version'));
}

var _versionModelObject;

function _load_versionModelObject() {
  return _versionModelObject = _interopRequireDefault(require('../../../fixtures/version-model-object.json'));
}

var _versionModelExtended;

function _load_versionModelExtended() {
  return _versionModelExtended = _interopRequireDefault(require('../../../fixtures/version-model-extended.json'));
}

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var getVersionWithDepsFixture = function getVersionWithDepsFixture() {
  return (_version || _load_version()).default.parse(JSON.stringify((_ramda || _load_ramda()).default.clone((_versionModelExtended || _load_versionModelExtended()).default)));
};

describe('Version', function () {
  describe('id()', function () {
    describe('simple version', function () {
      var version = void 0;
      var idRaw = void 0;
      var idParsed = void 0;
      before(function () {
        version = new (_version || _load_version()).default((_versionModelObject || _load_versionModelObject()).default);
        idRaw = version.id();
        idParsed = JSON.parse(idRaw);
      });
      it('should have mainFile property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.haveOwnProperty('mainFile');
      });
      it('should have files property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.haveOwnProperty('files');
      });
      it('should have compiler property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.haveOwnProperty('compiler');
      });
      it('should have tester property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.haveOwnProperty('tester');
      });
      it('should have log property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.haveOwnProperty('log');
      });
      it('should have dependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.haveOwnProperty('dependencies');
      });
      it('should have packageDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.haveOwnProperty('packageDependencies');
      });
      it('should have bindingPrefix property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.haveOwnProperty('bindingPrefix');
      });
      it('should not have dists property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('dists');
      });
      it('should not have ci property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('ci');
      });
      it('should not have specsResults property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('specsResults');
      });
      it('should not have docs property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('docs');
      });
      it('should not have devDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('devDependencies');
      });
      it('should not have compilerDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('compilerDependencies');
      });
      it('should not have testerDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('testerDependencies');
      });
      it('should not have flattenedDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('flattenedDependencies');
      });
      it('should not have flattenedDevDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('flattenedDevDependencies');
      });
      it('should not have flattenedCompilerDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('flattenedCompilerDependencies');
      });
      it('should not have flattenedTesterDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('flattenedTesterDependencies');
      });
      it('should not have devPackageDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('devPackageDependencies');
      });
      it('should not have peerPackageDependencies property', function () {
        (0, (_chai || _load_chai()).expect)(idParsed).to.not.haveOwnProperty('peerPackageDependencies');
      });
    });
    describe('version with dependencies', function () {
      var dependencies = void 0;
      before(function () {
        var version = getVersionWithDepsFixture();
        var idRaw = version.id();
        var idParsed = JSON.parse(idRaw);
        dependencies = idParsed.dependencies;
      });
      it('dependencies should be an array', function () {
        (0, (_chai || _load_chai()).expect)(dependencies).to.be.an('array').and.have.lengthOf(1);
      });
      it('dependencies should have properties id and relativePaths only', function () {
        (0, (_chai || _load_chai()).expect)(dependencies[0]).to.haveOwnProperty('id');
        (0, (_chai || _load_chai()).expect)(dependencies[0]).to.haveOwnProperty('relativePaths');
        (0, (_chai || _load_chai()).expect)(dependencies[0]).to.not.haveOwnProperty('nonExistProperty');
        (0, (_chai || _load_chai()).expect)(Object.keys(dependencies[0])).to.have.lengthOf(2);
      });
      it('relativePaths should be an array', function () {
        (0, (_chai || _load_chai()).expect)(dependencies[0].relativePaths).to.be.an('array').and.have.lengthOf(1);
      });
      it('relativePaths should have properties sourceRelativePath and destinationRelativePath only', function () {
        (0, (_chai || _load_chai()).expect)(dependencies[0].relativePaths[0]).to.haveOwnProperty('sourceRelativePath');
        (0, (_chai || _load_chai()).expect)(dependencies[0].relativePaths[0]).to.haveOwnProperty('destinationRelativePath');
        (0, (_chai || _load_chai()).expect)(dependencies[0].relativePaths[0]).to.not.haveOwnProperty('nonExistProperty');
        (0, (_chai || _load_chai()).expect)(Object.keys(dependencies[0].relativePaths[0])).to.have.lengthOf(2);
      });
    });
  });
  describe('hash()', function () {
    var version = void 0;
    var hash = void 0;
    var versionFixtureHash = '693679c1c397ca3c42f6f3486ce1ed042787886a';
    before(function () {
      version = new (_version || _load_version()).default((_versionModelObject || _load_versionModelObject()).default);
      hash = version.hash();
    });
    it('should have a correct hash string', function () {
      (0, (_chai || _load_chai()).expect)(hash.toString()).to.equal(versionFixtureHash);
    });
    it('should have a the same hash string also when loading the version from contents', function () {
      var versionFromContent = (_version || _load_version()).default.parse(JSON.stringify((_versionModelObject || _load_versionModelObject()).default));
      (0, (_chai || _load_chai()).expect)(versionFromContent.hash().toString()).to.equal(versionFixtureHash);
    });
  });
  describe('validate()', function () {
    var version = void 0;
    var validateFunc = void 0;
    beforeEach(function () {
      version = getVersionWithDepsFixture();
      validateFunc = function validateFunc() {
        return version.validate();
      };
    });
    it('should not throw when it has a valid version', function () {
      (0, (_chai || _load_chai()).expect)(validateFunc).to.not.throw();
    });
    it('should throw when mainFile is empty', function () {
      var errMsg = 'mainFile is missing';
      version.mainFile = null;
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw(errMsg);
      version.mainFile = '';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw(errMsg);
      version.mainFile = undefined;
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw(errMsg);
    });
    it('should throw when mainFile path is absolute', function () {
      version.mainFile = '/tmp/main.js';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw(`mainFile ${version.mainFile} is invalid`);
    });
    it('should throw when mainFile path is Windows format', function () {
      version.mainFile = 'a\\tmp.js';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw(`mainFile ${version.mainFile} is invalid`);
    });
    it('should throw when the files are missing', function () {
      version.files = undefined;
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('files are missing');
      version.files = null;
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('files are missing');
      version.files = [];
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('files are missing');
    });
    it('should throw when the file has no hash', function () {
      version.files[0].file = '';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('missing the hash');
    });
    it('should throw when the file has no name', function () {
      version.files[0].name = '';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('missing the name');
    });
    it('should throw when the file.name is not a string', function () {
      version.files[0].name = true;
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be string, got boolean');
    });
    it('should throw when the file hash is not a string', function () {
      version.files[0].file.hash = [];
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be string, got object');
    });
    it('should throw when the main file is not in the file lists', function () {
      version.files[0].relativePath = 'anotherFile.js';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('unable to find the mainFile');
    });
    it('should throw when the two files have the same name but different letter cases', function () {
      version.files[1] = (_ramda || _load_ramda()).default.clone(version.files[0]);
      version.files[1].relativePath = 'bar/Foo.ts';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('files are duplicated bar/foo.ts, bar/Foo.ts');
    });
    it('compiler should have name attribute', function () {
      version.compiler = {};
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('missing the name attribute');
    });
    it('compiler.name should be a string', function () {
      version.compiler.name = true;
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be string, got boolean');
    });
    it('compiler.name should be a valid bit id with version', function () {
      version.compiler.name = 'scope/pref/aaa@latest';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('does not have a version');
    });
    it('compiler.files should have name attribute', function () {
      version.compiler.files[0] = 'string';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('missing the name attribute');
    });
    it('if a compiler is string, it should be a valid bit-id', function () {
      version.compiler = 'this/is\\invalid?!/bit/id';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('the environment-id has an invalid Bit id');
    });
    it('if a compiler is string, it should have scope', function () {
      version.compiler = 'name@0.0.1';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('the environment-id has an invalid Bit id');
    });
    // it('if a compiler is string, it should have version', () => {
    //   version.compiler = 'scope/box/name';
    //   expect(validateFunc).to.throw('does not have a version');
    // });
    it('should throw for an invalid package version', function () {
      version.packageDependencies = { lodash: 34 };
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('expected version of "lodash" to be string, got number');
    });
    it('should not throw for a package version which is a git url', function () {
      version.packageDependencies = { userLib: 'git+ssh://git@git.bit.io' };
      (0, (_chai || _load_chai()).expect)(validateFunc).to.not.throw();
    });
    it('should throw for invalid packageDependencies type', function () {
      version.packageDependencies = 'invalid packages';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be object, got string');
    });
    it('should throw for invalid devPackageDependencies type', function () {
      version.devPackageDependencies = [1, 2, 3];
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be object, got array');
    });
    it('should throw for invalid peerPackageDependencies type', function () {
      version.peerPackageDependencies = true;
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be object, got boolean');
    });
    it('should throw for invalid dist object', function () {
      version.dists = 'invalid dists';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be array, got string');
    });
    it('should throw for invalid dist.relativePath', function () {
      version.dists[0].relativePath = 'invalid*path';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw(`dist-file ${version.dists[0].relativePath} is invalid`);
    });
    it('should throw for an empty dist.relativePath', function () {
      version.dists[0].relativePath = '';
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw(`dist-file ${version.dists[0].relativePath} is invalid`);
    });
    it('should throw for an invalid dist.name', function () {
      version.dists[0].name = 4;
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be string, got number');
    });
    it('should throw when the file hash is not a string', function () {
      version.dists[0].file.hash = {};
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be string, got object');
    });
    it('should throw when dependencies are invalid', function () {
      version.dependencies = {};
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('dependencies must be an instance of Dependencies, got object');
    });
    it('should throw when devDependencies are invalid', function () {
      version.devDependencies = {};
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('devDependencies must be an instance of Dependencies, got object');
    });
    it('should throw when compilerDependencies are invalid', function () {
      version.compilerDependencies = {};
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('compilerDependencies must be an instance of Dependencies, got object');
    });
    it('should throw when testerDependencies are invalid', function () {
      version.testerDependencies = {};
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('testerDependencies must be an instance of Dependencies, got object');
    });
    it('should throw when there are dependencies and the flattenDependencies are empty', function () {
      version.flattenedDependencies = [];
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('it has dependencies but its flattenedDependencies is empty');
    });
    it('should throw when a flattenDependency is invalid', function () {
      version.flattenedDependencies = [1234];
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('expected to be BitId, got number');
    });
    it('should throw when a flattenDependency does not have a version', function () {
      version.flattenedDependencies[0] = version.flattenedDependencies[0].changeVersion(null);
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('does not have a version');
    });
    it('should throw when the log is empty', function () {
      version.log = undefined;
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('log object is missing');
    });
    it('should throw when the log has an invalid type', function () {
      version.log = [];
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be object, got array');
    });
    it('should throw when the bindingPrefix has an invalid type', function () {
      version.bindingPrefix = {};
      (0, (_chai || _load_chai()).expect)(validateFunc).to.throw('to be string, got object');
    });
  });
});