text: /**
   * @fileOverview This test specs runs tests on the package.json file of repository. It has a set of strict tests on the
   * content of the file as well. Any change to package.json must be accompanied by valid test case in this spec-sheet.
   */
  var fs = require('fs'),
      path = require('path'),
      _ = require('lodash'),
      yml = require('js-yaml'),
      parseIgnore = require('parse-gitignore');
  
  /* global describe, it, expect */
  describe('project repository', function () {
      describe('package.json', function () {
          var content,
              json;
  
          try {
              content = fs.readFileSync('./package.json').toString();
              json = JSON.parse(content);
          }
          catch (e) {
              console.error(e);
              content = '';
              json = {};
          }
  
          it('should have readable JSON content', function () {
              expect(content).to.be.ok;
              expect(json).to.not.eql({});
          });
  
          describe('package.json JSON data', function () {
              it('should have valid name, description and author', function () {
                  expect(json).to.have.property('name', 'postman-schemas');
                  expect(json).to.have.property('description',
                      'Tools and data related to Postman\'s JSON-based file formats');
                  expect(json).to.have.property('author', 'Postman Labs <help@getpostman.com> (=)');
                  expect(json).to.have.property('license', 'Apache-2.0');
                  expect(json).to.have.property('homepage', 'https://github.com/postmanlabs/schemas');
                  expect(json).to.have.property('bugs', 'https://github.com/postmanlabs/schemas/issues');
  
                  expect(json).to.have.property('repository');
                  expect(json.repository).to.eql({
                      type: 'git',
                      url: 'git://github.com/postmanlabs/schemas.git'
                  });
  
                  expect(json).to.have.property('keywords');
                  expect(json.keywords).to.eql(['postman', 'collection', 'json-schema']);
  
                  expect(json).to.have.property('engines');
                  expect(json.engines).to.eql({ node: '8' });
              });
  
              it('should have a valid version string in form of <major>.<minor>.<revision>', function () {
                  // eslint-disable-next-line max-len
                  expect(json.version).to.match(/^((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z-]+(?:\.[\dA-Za-z-]+)*))?(?:\+([\dA-Za-z-]+(?:\.[\dA-Za-z-]+)*))?$/);
              });
          });
  
          describe('script definitions', function () {
              it('should exist', function () {
                  expect(json.scripts).to.be.ok;
                  json.scripts && Object.keys(json.scripts).forEach(function (scriptName) {
                      var name = json.scripts[scriptName];
  
                      name = name.replace(/^(node\s|\.\/)/, '');
                      fs.stat(name, function (err) {
                          var fileDetails = path.parse(name);
  
                          expect(err).to.equal(null);
                          expect(fileDetails.ext).to.match(/^\.(sh|js)$/);
                      });
                  });
              });
  
              it('should have the hashbang defined', function () {
                  expect(json.scripts).to.be.ok;
                  json.scripts && Object.keys(json.scripts).forEach(function (scriptName) {
                      var fileDetails,
                          name = json.scripts[scriptName].replace(/^(node\s|\.\/)/, '');
  
                      fileDetails = path.parse(name);
                      expect(fileDetails.ext).to.match(/^\.(sh|js)$/);
  
                      fs.readFile(name, function (error, content) {
                          expect(error).to.equal(null);
                          if (fileDetails.ext === '.sh') {
                              expect((/^#!\/bin\/bash[\r\n][\W\w]*$/g).test(content),
                                  `invalid or missing hashbang in ${name}`).to.be.ok;
                          }
                          else {
                              expect((/^#!\/usr\/bin\/env\snode[\r\n][\W\w]*$/g).test(content),
                                  `invalid or missing hashbang in ${name}`).to.be.ok;
                          }
                      });
                  });
              });
          });
  
          describe('dependencies', function () {
              it('should exist', function () {
                  expect(json.dependencies).to.be.an('object');
              });
  
              it('should point to a valid and precise (no * or ^) semver', function () {
                  json.dependencies && Object.keys(json.dependencies).forEach(function (item) {
                      expect(json.dependencies[item]).to.match(new RegExp('^((\\d+)\\.(\\d+)\\.(\\d+))(?:-' +
                          '([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?(?:\\+([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?$'));
                  });
              });
          });
  
          describe('devDependencies', function () {
              it('should exist', function () {
                  expect(json.devDependencies).to.be.an('object');
              });
  
              it('should point to a valid and precise (no * or ^) semver', function () {
                  json.devDependencies && Object.keys(json.devDependencies).forEach(function (item) {
                      expect(json.devDependencies[item]).to.match(new RegExp('^((\\d+)\\.(\\d+)\\.(\\d+))(?:-' +
                          '([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?(?:\\+([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?$'));
                  });
              });
  
              it('should not overlap devDependencies', function () {
                  var clean = [];
  
                  json.devDependencies && Object.keys(json.devDependencies).forEach(function (item) {
                      !json.dependencies[item] && clean.push(item);
                  });
  
                  expect(Object.keys(json.devDependencies)).to.eql(clean);
              });
          });
  
          describe('main entry script', function () {
              it('should point to a valid file', function (done) {
                  expect(json.main).to.equal('index.js');
                  fs.stat(json.main, done);
              });
          });
      });
  
      describe('README.md', function () {
          it('should exist', function (done) {
              fs.stat('./README.md', done);
          });
  
          it('should have readable content', function () {
              expect(fs.readFileSync('./README.md').toString()).to.be.ok;
          });
      });
  
      describe('LICENSE.md', function () {
          it('should exist', function (done) {
              fs.stat('./LICENSE.md', done);
          });
  
          it('should have readable content', function () {
              expect(fs.readFileSync('./LICENSE.md').toString()).to.be.ok;
          });
      });
  
      describe('.ignore files', function () {
          var gitignorePath = '.gitignore',
              npmignorePath = '.npmignore',
              npmignore = parseIgnore(fs.readFileSync(npmignorePath, 'utf8')),
              gitignore = parseIgnore(fs.readFileSync(gitignorePath, 'utf8'));
  
          describe(gitignorePath, function () {
              it('should exist', function (done) {
                  fs.stat(gitignorePath, done);
              });
  
              it('should have valid content', function () {
                  expect(gitignore).to.not.be.empty;
              });
          });
  
          describe(npmignorePath, function () {
              it('should exist', function (done) {
                  fs.stat(npmignorePath, done);
              });
  
              it('should have valid content', function () {
                  expect(npmignore).to.not.be.empty;
              });
          });
  
          it('should have .gitignore coverage to be a subset of .npmignore coverage', function () {
              expect(_.intersection(gitignore, npmignore)).to.eql(gitignore);
          });
      });
  
      // @todo add eslintrc
      describe.skip('.eslintrc', function () {
          it('should exist', function (done) {
              fs.stat('./.eslintrc', done);
          });
  
          it('should have readable content', function () {
              expect(fs.readFileSync('./.eslintrc').toString()).to.be.ok;
          });
      });
  
      describe('CHANGELOG.yaml', function () {
          it('should exist', function (done) {
              fs.stat('./CHANGELOG.yaml', done);
          });
  
          it('should have readable content', function () {
              expect(yml.safeLoad(fs.readFileSync('./CHANGELOG.yaml')), 'not a valid yaml').to.be.ok;
          });
      });
  });
  