passy/google-cdn

View on GitHub
test.js

Summary

Maintainability
F
4 days
Test Coverage
/*global describe, it, beforeEach */

'use strict';
var path = require('path');
var assert = require('chai').assert;
var proxyquire = require('proxyquire');
var bowerUtil = require('./util/bower');
var EventEmitter = require('events').EventEmitter;

describe('google-cdn', function () {
  beforeEach(function () {
    this.mainPath = '';

    this.googlecdn = proxyquire('./googlecdn', {
      './util/bower': {
        resolveMainPath: function (supportedTypes, name, version, cb) {
          var mainFiles = {};
          var thatMainPath = (typeof(this.mainPath) === 'object' ? this.mainPath[name] : this.mainPath);
          supportedTypes.types.forEach(function (type) {
            if (supportedTypes.typesRegex[type].test(thatMainPath)) {
              mainFiles[type] = thatMainPath;
            }
          });
          cb(null, mainFiles);
        }.bind(this),
        joinComponent: bowerUtil.joinComponent
      }
    });
  });

  it('should load', function () {
    assert(this.googlecdn !== undefined);
  });

  it('should replace jquery', function (cb) {
    var source = '<script src="bower_components/jquery/jquery.js"></script>';
    var bowerConfig = {
      dependencies: { jquery: '~2.0.0' }
    };

    this.mainPath = 'jquery/jquery.js';

    this.googlecdn(source, bowerConfig, function (err, result) {
      if (err) {
        return cb(err);
      }

      assert.equal(result, '<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>');
      cb();
    });
  });

  it('should replace jquery ui', function (cb) {
    var source = '<script src="bower_components/jquery-ui/ui/jquery-ui.js"></script>';
    var bowerConfig = {
      dependencies: { 'jquery-ui': '~1.10.3' }
    };

    this.mainPath = 'jquery-ui/ui/jquery-ui.js';

    this.googlecdn(source, bowerConfig, function (err, result) {
      if (err) {
        return cb(err);
      }

      assert.equal(result, '<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>');
      cb();
    });
  });

  it('should replace lodash, even though bower and cdnjs use different names', function (cb) {
    var source = '<script src="bower_components/lodash/dist/lodash.compat.js"></script>';
    var bowerConfig = {
      dependencies: { lodash: '~3.9.0' }
    };

    this.mainPath = 'lodash/dist/lodash.compat.js';

    this.googlecdn(source, bowerConfig, { cdn: 'cdnjs' }, function (err, result) {
      if (err) {
        return cb(err);
      }

      assert.equal(result, '<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.9.3/lodash.min.js"></script>');
      cb();
    });
  });

  it('should replace lodash as a devDependency', function (cb) {
    var source = '<script src="bower_components/lodash/dist/lodash.compat.js"></script>';
    var bowerConfig = {
      devDependencies: { lodash: '~3.9.0' }
    };

    this.mainPath = 'lodash/dist/lodash.compat.js';

    this.googlecdn(source, bowerConfig, { cdn: 'cdnjs' }, function (err, result) {
      if (err) {
        return cb(err);
      }

      assert.equal(result, '<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.9.3/lodash.min.js"></script>');
      cb();
    });
  });

  it('should throw without bowerJson', function () {
    var source = '<script src="bower_components/jquery-ui/ui/jquery-ui.js"></script>';
    var bowerConfig = null;

    var fn = this.googlecdn.bind(this, source, bowerConfig, function () {
    });
    assert.throw(fn, /bowerJson.*missing/);
  });

  it('should support cdnjs', function (cb) {
    var source = '<script src="bower_components/jquery/jquery.js"></script>';
    var bowerConfig = {
      dependencies: { 'jquery': '~2.0.1' }
    };

    this.mainPath = 'jquery/jquery.js';

    this.googlecdn(source, bowerConfig, { cdn: 'cdnjs' }, function (err, result) {
      if (err) {
        return cb(err);
      }

      assert.equal(result, '<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>');
      cb();
    });
  });

  it('should support cdn object', function (cb) {
    var source = '<script src="bower_components/jquery/jquery.js"></script>';
    var bowerConfig = {
      dependencies: { 'jquery': '~2.0.1' }
    };

    this.mainPath = 'jquery/jquery.js';

    var cdnObject = {
      jquery: {
        versions: ['2.0.3', '2.0.2', '2.0.1', '2.0.0'],
        url: function (version) {
          return '//my.own.cdn/libs/jquery/' + version + '/jquery.min.js';
        }
      }
    };

    this.googlecdn(source, bowerConfig, { cdn: cdnObject }, function (err, result) {
      if (err) {
        return cb(err);
      }

      assert.equal(result, '<script src="//my.own.cdn/libs/jquery/2.0.3/jquery.min.js"></script>');
      cb();
    });
  });

  it('should support cdn array', function (cb) {
    var source = '<script src="bower_components/jquery/jquery.js">' +
      '</script><script src="bower_components/d3/d3.js"></script>';
    var bowerConfig = {
      dependencies: {
        'jquery': '~2.0.1',
        'd3': '~3.4.0'
      }
    };

    this.mainPath = {
      'jquery': 'jquery/jquery.js',
      'd3': 'd3/d3.js',
    };

    this.googlecdn(source, bowerConfig, { cdn: ['google', 'cdnjs'] }, function (err, result) {
      if (err) {
        return cb(err);
      }

      assert.equal(result, '<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script><script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3.min.js"></script>');
      cb();
    });
  });

  it('should return an error if a requested cdn does not exist', function (cb) {
    var source = '';
    var bowerConfig = {};
    this.googlecdn(source, bowerConfig, { cdn: ['google', 'does-not-exist', 'cdnjs'] }, function (err) {
      assert.match(err, /CDN.*is not supported./);
      cb();
    });
  });

  it('should allow cdn data to include all files in the bower component', function (cb) {
    var source = '<script src="bower_components/angular-i18n/angular-locale_he.js"></script>';
    var bowerConfig = {
      dependencies: { 'angular-i18n': '~1.2.0' }
    };

    var cdnObject = {
      'angular-i18n': {
        all: true,
        versions: ['1.2.6', '1.2.10', '1.2.14'],
        url: function (version) {
          return '//my.own.cdn/libs/angularjs/' + version + '/i18n';
        }
      }
    };

    this.googlecdn(source, bowerConfig, { cdn: cdnObject }, function (err, result) {
      if (err) {
        return cb(err);
      }

      assert.equal(result, '<script src="//my.own.cdn/libs/angularjs/1.2.14/i18n/angular-locale_he.js"></script>');
      cb();
    });
  });

  it('should strip leading slashes', function (cb) {
    var source = '<script src="/bower_components/jquery/jquery.js"></script>';
    var bowerConfig = {
      dependencies: { 'jquery': '2.0.3' }
    };

    this.mainPath = 'jquery/jquery.js';

    this.googlecdn(source, bowerConfig, function (err, result) {
      if (err) {
        return cb(err);
      }

      assert.equal(result, '<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>');
      cb();
    });
  });

  it('should print jquery replacement information', function (cb) {
    var source = '<script src="bower_components/jquery/jquery.js"></script>';
    var bowerConfig = {
      dependencies: { jquery: '~2.0.0' }
    };

    this.mainPath = 'jquery/jquery.js';

    this.googlecdn(source, bowerConfig, function (err, result, replacementInfo) {
      if (err) {
        return cb(err);
      }

      assert.equal(replacementInfo[0].from, 'bower_components/jquery/jquery.js');
      assert.equal(replacementInfo[0].to, '//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js');
      cb();
    });
  });

  it('should print jquery-ui replacement information', function (cb) {
    var source = '<script src="bower_components/jquery-ui/ui/jquery-ui.js"></script>';
    var bowerConfig = {
      dependencies: {
        'jquery-ui': '~1.10.3'
      }
    };

    this.mainPath = 'jquery-ui/ui/jquery-ui.js';

    this.googlecdn(source, bowerConfig, function (err, result, replacementInfo) {
      if (err) {
        return cb(err);
      }

      assert.equal(replacementInfo[0].from, 'bower_components/jquery-ui/ui/jquery-ui.js');
      assert.equal(replacementInfo[0].to, '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js');
      cb();
    });
  });
});

describe('util/bower', function () {
  beforeEach(function () {
    this.pathMock = {
      join: path.join,
      sep: '/'  // Always test the unix way by default.
    };
    var supportedTypes = {
      types: ['js'],
      typesRegex: {}
    };
    supportedTypes.types.forEach(function (type) {
      supportedTypes.typesRegex[type] = new RegExp('\\.' + type + '$', 'i');
    });
    this.supportedTypes = supportedTypes;
    this.queryResult = '';
    this.bowerInfoMock = function bowerInfoMock() {
      var query = new EventEmitter();

      process.nextTick(function () {
        query.emit('end', this.queryResult);
      }.bind(this));

      return query;
    }.bind(this);

    this.util = proxyquire('./util/bower', {
      path: this.pathMock,
      bower: {
        commands: {
          info: this.bowerInfoMock
        }
      }
    });
  });

  it('joinComponent', function () {
    var result = this.util.joinComponent('bower_components', 'jquery/jquery-2.0.js');
    assert.equal(result, 'bower_components/jquery/jquery-2.0.js');
  });

  it('should join on w32', function () {
    this.pathMock.sep = '\\';
    var result = this.util.joinComponent('bower_components', 'jquery\\jquery-2.0.js');
    assert.equal(result, 'bower_components/jquery/jquery-2.0.js');
  });

  it('should resolve jquery to a main path', function (cb) {
    this.queryResult = 'jquery.js';
    this.util.resolveMainPath(this.supportedTypes, 'jquery', '2.0.0', function (err, path) {
      if (err) {
        cb(err);
      }

      assert.deepEqual(path, { js: 'jquery/jquery.js' });
      cb();
    });
  });

  it('should resolve jquery-ui to a main path', function (cb) {
    this.queryResult = ['ui/jquery-ui.js'];
    this.util.resolveMainPath(this.supportedTypes, 'jquery-ui', '1.10.3', function (err, path) {
      if (err) {
        cb(err);
      }

      assert.deepEqual(path, { js: 'jquery-ui/ui/jquery-ui.js' });
      cb();
    });
  });

  it('should resolve lodash to a main path', function (cb) {
    this.queryResult = 'dist/lodash.compat.js';
    this.util.resolveMainPath(this.supportedTypes, 'lodash', '2.4.1', function (err, path) {
      if (err) {
        cb(err);
      }

      assert.deepEqual(path, { js: 'lodash/dist/lodash.compat.js' });
      cb();
    });
  });

  it('should resolve angular to a main path', function (cb) {
    this.queryResult = './angular.js';
    this.util.resolveMainPath(this.supportedTypes, 'angular', '1.2.6', function (err, path) {
      if (err) {
        cb(err);
      }

      assert.deepEqual(path, { js: 'angular/angular.js' });
      cb();
    });
  });

  it('should resolve just js for multiple main files', function (cb) {
    this.queryResult = ['css/multiple.css', 'lib/multiple.js'];
    this.util.resolveMainPath(this.supportedTypes, 'multiple-main', '1.10.3', function (err, path) {
      if (err) {
        cb(err);
      }

      assert.deepEqual(path, { js: 'multiple-main/lib/multiple.js' });
      cb();
    });
  });


  it('should resolve both css and js for multiple main files', function (cb) {
    var supportedTypes = {
      types: ['js', 'css'],
      typesRegex: {}
    };
    supportedTypes.types.forEach(function (type) {
      supportedTypes.typesRegex[type] = new RegExp('\\.' + type + '$', 'i');
    });
    this.queryResult = ['css/multiple.css', 'lib/multiple.js'];
    this.util.resolveMainPath(supportedTypes, 'multiple-main', '1.10.3', function (err, path) {
      if (err) {
        cb(err);
      }

      assert.deepEqual(path, { js: 'multiple-main/lib/multiple.js', css: 'multiple-main/css/multiple.css' });
      cb();
    });
  });


  it('should fall fall back to name w/o main', function (cb) {
    this.queryResult = undefined;
    this.util.resolveMainPath(this.supportedTypes, 'no-main', '1.0', function (err, path) {
      if (err) {
        cb(err);
      }

      assert.deepEqual(path, { js: 'no-main/no-main.js' });
      cb();
    });
  });
});