Code coverage report for asset-builder/lib/buildGlobs.js

Statements: 100% (41 / 41)      Branches: 100% (14 / 14)      Functions: 100% (11 / 11)      Lines: 100% (41 / 41)      Ignored: none     

All files » asset-builder/lib/ » buildGlobs.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140            1 1 1 1 1 1                                 1 6   6                                                   1 14   14   49     14   16 16 16   16 5             11 6               16 16     14                   1 14 14 1   14 205 274         1 7                   1 21     1   17 379 379 25   379      
/**
 * buildGlobs
 * @module
 */
'use strict';
 
var _          = require('lodash');
var obj        = require('object-path');
var minimatch  = require('minimatch');
var Dependency = require('./Dependency');
var types      = require('./types.json');
var traverse   = require('traverse');
 
/**
 * buildGlobs
 *
 * @class
 * @param {Object} dependencies a map of dependencies
 * @param {Array} bowerFiles an array bower component file paths
 * @param {Object} options
 *
 * @property {Object} globs the glob strings organized by type
 * @property {Object} globs.js an array of javascript Dependency objects
 * @property {Object} globs.css an array of css Dependency objects
 * @property {Object} globs.fonts an array of fonts path glob strings
 * @property {Object} globs.images an array of image path glob strings
 * @property {Object} globs.bower an array of image path glob strings
 */
var buildGlobs = module.exports = function(dependencies, bowerFiles, options) {
  options = options || {};
 
  this.globs = {
    // js is an array of objects because there can be multople js files
    js: this.getOutputFiles('js', dependencies, bowerFiles),
    // css is an array of objects because there can be multiple css files
    css: this.getOutputFiles('css', dependencies, bowerFiles),
    // fonts is a flat array since all the fonts go to the same place
    fonts: [].concat(
      this.filterByType(bowerFiles, 'fonts'),
      obj.get(dependencies, 'fonts.files')
    ),
    // fonts is a flat array since all the fonts go to the same place
    images: [].concat(
      obj.get(dependencies, 'images.files')
    ),
    bower: bowerFiles
  };
};
 
/**
 * getOutputFiles
 *
 * @param {String} type
 * @param {Object} dependencies
 * @param {Array} bowerFiles an array bower component file paths
 * @return {undefined}
 */
buildGlobs.prototype.getOutputFiles = function(type, dependencies, bowerFiles) {
  var outputFiles;
 
  outputFiles = _.pick(dependencies, function(dependency, name) {
    // only select dependencies with valid file extensions
    return new RegExp('\.' + type + '$').test(name);
  });
 
  outputFiles = _.transform(outputFiles, function(result, dependency, name) {
    // convert to an array of dependencyObjects
    var dep = new Dependency(name, dependency);
    var bower = [];
    var bowerExclude = this.bowerExclude(dependencies);
 
    if (dependency.bower) {
      bower = bower.concat(
        this.filterByType(
          this.filterByPackage(bowerFiles, dependency.bower),
          type
        )
      );
    } else {
      if (dependency.main) {
        bower = bower.concat(
          this.filterByType(
            this.rejectByPackage(bowerFiles, bowerExclude),
            type
          )
        );
      }
    }
    dep.prependGlobs(bower);
    result.push(dep);
  }, [], this);
 
  return outputFiles;
};
 
/**
 * filterByPackage
 *
 * @param {Array} files
 * @param {String|Array} names
 * @return {Array} files for a particular package name
 */
buildGlobs.prototype.filterByPackage = function(files, names, reject) {
  var method = reject ? 'reject' : 'filter';
  if (!_.isArray(names)) {
    names = [names];
  }
  return _[method](files, function(file) {
    return _.some(names, function(name) {
      return file.indexOf('/bower_components/' + name + '/') > -1;
    });
  });
};
 
buildGlobs.prototype.rejectByPackage = function(files, names) {
  return buildGlobs.prototype.filterByPackage(files, names, true);
};
 
/**
 * filterByType
 *
 * @param {Array} files
 * @param {String} type
 * @return {Array} files for a particular type
 */
buildGlobs.prototype.filterByType = function(files, type) {
  return _.filter(files, minimatch.filter(types[type], {matchBase: true}));
};
 
buildGlobs.prototype.bowerExclude = function(dependencies) {
  // resolve bower dependencies
  return traverse(dependencies).reduce(function(result) {
    var parentKey = obj.get(this, 'parent.key');
    if (this.isLeaf && parentKey === 'bower') {
      result.push(this.parent.node);
    }
    return _.flatten(result);
  }, []);
};