all files / lib/resolver/ constructor.js

100% Statements 41/41
100% Branches 12/12
100% Functions 4/4
100% Lines 30/30
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      71× 71× 51×   70×                                       103×   102× 102×         101×   71× 71× 70×       71×     30× 30×      
"use strict";
var assert = require('../util').assert;
var ResolutionError = require('../ResolutionError');
 
// This madness is necessary because Function.apply/call doesn't work on ES6 classes.
function callCtor(Type, deps) {
  var i;
  switch (deps.length) {
    case 0:  i = new Type(); break;
    case 1:  i = new Type(deps[0]); break;
    case 2:  i = new Type(deps[0], deps[1]); break;
    case 3:  i = new Type(deps[0], deps[1], deps[2]); break;
    case 4:  i = new Type(deps[0], deps[1], deps[2], deps[3]); break;
    case 5:  i = new Type(deps[0], deps[1], deps[2], deps[3], deps[4]); break;
    case 6:  i = new Type(deps[0], deps[1], deps[2], deps[3], deps[4], deps[5]); break;
    case 7:  i = new Type(deps[0], deps[1], deps[2], deps[3], deps[4], deps[5], deps[6]); break;
    case 8:  i = new Type(deps[0], deps[1], deps[2], deps[3], deps[4], deps[5], deps[6], deps[7]); break;
    case 9:  i = new Type(deps[0], deps[1], deps[2], deps[3], deps[4], deps[5], deps[6], deps[7], deps[8]); break;
    case 10: i = new Type(deps[0], deps[1], deps[2], deps[3], deps[4], deps[5], deps[6], deps[7], deps[8], deps[9]); break;
    default: throw new Error("Seriously? You have more than 10 constructor parameters?");
  }
  return i;
}
 
/**
 * Treats the registered component as a constructor and calls it to produce an instance which then becomes
 * the resolved instance.
 *
 * @name constructor
 * @param {...string} [dependencyKey] A dependency key to resolve and pass as an argument to the constructor.
 * @function
 * @memberOf Resolver:constructor#
 */
 
/**
 * Creates a new component instance using a constructor.
 *
 * @function
 * @exports Resolver:constructor
 * @throws ResolutionError if the component is not a function.
 */
module.exports = function constructor(ctx, res, next) {
  res.instance(false);
 
  var Type = ctx.component();
  assert.type(Type,
    'function',
    "Constructor resolver: Component must be a function: " + (typeof Type),
    ResolutionError);
 
  ctx.resolve(this.args())
    .then(function(deps) {
      try {
        var instance = callCtor(Type, deps.list);
        res.resolve(instance);
      } catch (e) {
        res.fail(e);
      }
 
      next();
    })
    .catch(function(err) {
      res.fail(err);
      next();
    });
};