Code coverage report for yeoman-generator/lib/env/store.js

Statements: 100% (38 / 38)      Branches: 100% (6 / 6)      Functions: 100% (11 / 11)      Lines: 100% (37 / 37)      Ignored: none     

All files » yeoman-generator/lib/env/ » store.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  1 1 1                 1 161 161                 1 349 125 125   224     1 125       125   20 20             1 224       224                 1 87 87 61               1 17               1 1                   1 61 10   61 61                 1 61 61 61 244      
'use strict';
var util = require('util');
var _ = require('lodash');
var Base = require('../base');
 
/**
 * The Generator store
 * This is used to store generator (NPM modules) reference and instantiate them when
 * requested.
 * @constructor
 */
 
var Store = module.exports = function Store () {
  this._generators = {};
  this._meta = {};
};
 
/**
 * Store a module under the namespace key
 * @param {String}          namespace - The key under which the generator can be retrieved
 * @param {String|Function} generator - A generator module or a module path
 */
 
Store.prototype.add = function add (namespace, generator) {
  if (_.isString(generator)) {
    this._storeAsPath(namespace, generator);
    return;
  }
  this._storeAsModule(namespace, generator);
};
 
Store.prototype._storeAsPath = function _storeAsPath (namespace, path) {
  this._meta[namespace] = {
    resolved: path,
    namespace: namespace
  };
  Object.defineProperty(this._generators, namespace, {
    get: function () {
      var Generator = require(path);
      return Generator;
    },
    enumerable: true,
    configurable: true
  });
};
 
Store.prototype._storeAsModule = function _storeAsModule (namespace, Generator) {
  this._meta[namespace] = {
    resolved: 'unknown',
    namespace: namespace
  };
  this._generators[namespace] = Generator;
};
 
/**
 * Get the module registered under the given namespace
 * @param  {String} namespace
 * @return {Module}
 */
 
Store.prototype.get = function get (namespace) {
  var Generator = this._generators[namespace];
  if (!Generator) return;
  return this.normalizeGenerator(namespace, Generator);
};
 
/**
 * Returns the list of registered namespace.
 * @return {Array} Namespaces array
 */
 
Store.prototype.namespaces = function namespaces () {
  return Object.keys(this._generators);
};
 
/**
 * Get the stored generators meta data
 * @return {Object} Generators metadata
 */
 
Store.prototype.getGeneratorsMeta = function getGeneratorsMeta () {
  return this._meta;
};
 
/**
 * Normalize a Generator, extending it with related metadata and allowing simple
 * function to be registered as generators
 * @param  {Generator} Generator
 * @return {Generator}
 */
 
Store.prototype.normalizeGenerator = function normalizeGenerator (namespace, Generator) {
  if (isRaw(Generator)) {
    Generator = Base.extend({ exec: Generator });
  }
  _.extend(Generator, this._meta[namespace]);
  return Generator;
};
 
/**
 * Check if a Generator implement base Generator prototype.
 * @param  {Generator|Function}  generator
 * @return {Boolean}
 */
 
function isRaw(Generator) {
  Generator = Object.getPrototypeOf(Generator.prototype);
  var methods = ['option', 'argument', 'hookFor', 'run'];
  return methods.filter(function (method) {
    return !!Generator[method];
  }).length !== methods.length;
}