Code coverage report for istanbul/lib/util/factory.js

Statements: 93.18% (41 / 44)      Branches: 100% (16 / 16)      Functions: 100% (10 / 10)      Lines: 92.86% (39 / 42)     

All files » istanbul/lib/util/ » factory.js
1 /*
2 Copyright (c) 2012, Yahoo! Inc. All rights reserved.
3 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
4 */
5
6 1 var util = require('util'),
7 path = require('path'),
8 fs = require('fs'),
9 abbrev = require('abbrev');
10
11 1 function Factory(kind, dir, allowAbbreviations) {
12 3 this.kind = kind;
13 3 this.dir = dir;
14 3 this.allowAbbreviations = allowAbbreviations;
15 3 this.classMap = {};
16 3 this.abbreviations = null;
17 }
18
19 1 Factory.prototype = {
20
21 knownTypes: function () {
22 11 var keys = Object.keys(this.classMap);
23 11 keys.sort();
24 11 return keys;
25 },
26
27 resolve: function (abbreviatedType) {
28 37 if (!this.abbreviations) {
29 1 this.abbreviations = abbrev(this.knownTypes());
30 }
31 37 return this.abbreviations[abbreviatedType];
32 },
33
34 register: function (constructor) {
35 15 var type = constructor.TYPE;
36 15 if (!type) { throw new Error('Could not register ' + this.kind + ' constructor [no TYPE property]: ' + util.inspect(constructor)); }
37 14 this.classMap[type] = constructor;
38 14 this.abbreviations = null;
39 },
40
41 create: function (type, opts) {
42 39 var allowAbbrev = this.allowAbbreviations,
43 realType = allowAbbrev ? this.resolve(type) : type,
44 Cons;
45
46 39 Cons = realType ? this.classMap[realType] : null;
47 39 if (!Cons) { throw new Error('Invalid ' + this.kind + ' [' + type + '], allowed values are ' + this.knownTypes().join(', ')); }
48 35 return new Cons(opts);
49 },
50
51 loadStandard: function (dir) {
52 3 var that = this;
53 3 fs.readdirSync(dir).forEach(function (file) {
54 17 if (file !== 'index.js' && file.indexOf('.js') === file.length - 3) {
55 12 try {
56 12 that.register(require(path.resolve(dir, file)));
57 } catch (ex) {
58 console.error(ex.message);
59 console.error(ex.stack);
60 throw new Error('Could not register ' + that.kind + ' from file ' + file);
61 }
62 }
63 });
64 },
65
66 bindClassMethods: function (Cons) {
67 3 var tmpKind = this.kind.charAt(0).toUpperCase() + this.kind.substring(1), //ucfirst
68 allowAbbrev = this.allowAbbreviations;
69
70 3 Cons.mix = Factory.mix;
71 3 Cons.register = this.register.bind(this);
72 3 Cons.create = this.create.bind(this);
73 3 Cons.loadAll = this.loadStandard.bind(this, this.dir);
74 3 Cons['get' + tmpKind + 'List'] = this.knownTypes.bind(this);
75 3 if (allowAbbrev) {
76 1 Cons['resolve' + tmpKind + 'Name'] = this.resolve.bind(this);
77 }
78 }
79 };
80
81 1 Factory.mix = function (cons, proto) {
82 12 Object.keys(proto).forEach(function (key) {
83 39 cons.prototype[key] = proto[key];
84 });
85 };
86
87 1 module.exports = Factory;
88
89