├── .gitignore
├── .npmignore
├── .travis.yml
├── README.md
├── changelog.md
├── di4js.js
├── di4js.map
├── di4js.min.js
├── examples
├── amd
│ ├── index.html
│ ├── require.js
│ └── script.js
├── autowired
│ ├── index.html
│ └── script.js
├── child container
│ ├── index.html
│ └── script.js
├── fluent
│ ├── index.html
│ └── script.js
├── injection
│ ├── index.html
│ └── script.js
├── list
│ ├── index.html
│ └── script.js
└── testing
│ ├── index.html
│ ├── jasmine-2.2.0
│ ├── boot.js
│ ├── console.js
│ ├── jasmine-html.js
│ ├── jasmine.css
│ ├── jasmine.js
│ └── jasmine_favicon.png
│ └── script.js
├── gruntfile.js
├── lib
└── di4js.js
├── license.md
├── package-lock.json
├── package.json
├── spec-runner.html
├── spec
└── di.spec.js
└── src
├── DefaultDependencyResolver.js
├── DependencyResolver.js
├── DependencyResolverException.js
├── IDependencyResolver.js
├── IInstanceFactory.js
├── INameTransformer.js
├── InstanceFactory.js
├── InstanceFactoryOptions.js
└── NameTransformer.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .grunt
3 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .grunt
3 | spec
4 | src
5 | .travis.yml
6 | bower.json
7 | /di4js.js
8 | /di4js.min.js
9 | gruntfile.js
10 | SpecRunner.html
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
4 | before_install:
5 | - npm install -g grunt-cli
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # di4js
2 |
3 | [](http://gruntjs.com/)
4 | [](https://david-dm.org/gedbac/di4js#info=devDependencies)
5 | [](http://travis-ci.org/gedbac/di4js)
6 |
7 | The __di4js__ module is dependency injection implementation in JavaScript.
8 | Dependency injection is a software design pattern that allows the removal of
9 | hard-coded dependencies and makes it possible to change them. __di4js__ is free
10 | software distributed under the terms of the MIT License (MIT) and can be used
11 | with __web browsers__ or with __node.js__.
12 |
13 | var Car = function (engine, year) {
14 | this.engine = engine;
15 | this.year = year;
16 | };
17 |
18 | Car.prototype.start = function () {
19 | this.engine.start();
20 | };
21 |
22 | var DieselEngine = function () {
23 | this.hp = 0;
24 | };
25 |
26 | DieselEngine.prototype.start = function () {
27 | console.log("Diesel engine with " + this.hp + " hp has been started...");
28 | };
29 |
30 | di
31 | .autowired(false)
32 | .register('dieselEngine')
33 | .as(DieselEngine)
34 | .withProperties()
35 | .prop('hp').val(42);
36 | .register('car')
37 | .as(Car)
38 | .withConstructor()
39 | .param().ref('dieselEngine')
40 | .param().val(1976);
41 |
42 | var car = di.resolve('car');
43 |
44 | car.start(); // Diesel engine with 42 hp has been started...
45 |
46 | ## Overview
47 |
48 | * [Supported platforms](#supported-platforms)
49 | * [Installation](#installation)
50 | * [Node.js](#nodejs)
51 | * [Web Browser](#web-browser)
52 | * [NuGet](#nuget)
53 | * [API](#api)
54 | * [autowired(value)](#diautowiredvalue)
55 | * [isAutowired](#diisautowired)
56 | * [register(name)](#diregistername)
57 | * [as(type)](#diastype)
58 | * [instance(instance)](#diinstanceinstance)
59 | * [asSingleton()](#diassingleton)
60 | * [withConstructor()](#diwithconstructor)
61 | * [param(name)](#diparamname)
62 | * [withProperties()](#diwithproperties)
63 | * [prop(name)](#dipropname)
64 | * [func(name)](#difuncname)
65 | * [val(instance)](#divalinstance)
66 | * [ref(name)](#direfname)
67 | * [setFactory(factory)](#disetfactoryfactory)
68 | * [resolve(name)](#diresolvename)
69 | * [create()](#dicreate)
70 | * [inject(func)](#diinjectfunc)
71 | * [contains(name)](#dicontainsname)
72 | * [setDefaultFactory(factory)](#disetdefaultfactoryfactory)
73 | * [setNameTransformer(transformer)](#disetnametransformertransformer)
74 | * [getDefaultDependencyResolver()](#digetdefaultdependencyresolver)
75 | * [setDefaultDependencyResolver(value)](#disetdefaultdependencyresolvervalue)
76 | * [debug](#didebug)
77 | * [dispose()](#didispose)
78 | * [version](#diversion)
79 | * [License](#license)
80 | * [Authors](#authors)
81 |
82 | ## Supported platforms
83 |
84 | __di4js__ runs on all the following environments:
85 |
86 | __Web browsers__
87 |
88 | * [Chrome](http://www.google.com/chrome/ "Chrome")
89 | * [Firefox](http://www.getfirefox.com/ "Firefox")
90 | * [Internet Explorer (IE9+)](http://www.microsoft.com/windows/internet-explorer/default.aspx "Internet Explorer")
91 |
92 | __Server-side platforms__
93 |
94 | * [Node.js](http://nodejs.org/ "Node.js")
95 |
96 | ## Installation
97 |
98 | ### Node.js
99 |
100 | To install __di4js__ module for Node.js, this command should be used:
101 |
102 | npm install di4js
103 |
104 | Also __di4js__ module's loading statement should be added to main module:
105 |
106 | 'use strict';
107 |
108 | var di = require('di4js');
109 |
110 | // Your code goes here...
111 |
112 | ### Web Browser
113 |
114 | Theare are few options to install __di4js__ to the web browser. Module can be downloaded or can be installed using __NuGet__ package manager.
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | #### AMD
125 |
126 | di4js is compatible with asynchronous module definition (AMD) and it can be loaded as ordinal module.
127 |
128 | define(['di4js'], function (di) {
129 |
130 | });
131 |
132 | ### NuGet
133 |
134 | In Visual Studio __di4js__ module can be installed using NuGet extension. To install __di4js__, run the following command in the package manager console.
135 |
136 | Install-Package di4js
137 |
138 | ## API
139 |
140 | ### di.autowired(value)
141 |
142 | If autowired is enabled for dependency resolver, all type's or instance's dependencies are resolved automatically. By default autowired is disabled for dependency resolver. Parameter *value* is optional and has to be a boolean.
143 |
144 | di
145 | .autowired()
146 | .register('engine')
147 | .as(DieselEngine)
148 | .withProperties()
149 | .prop('hp').val(42);
150 | .register('car')
151 | .as(Car);
152 |
153 | di.resolve('car'); // { engine: { hp: 42 } }
154 |
155 | ### di.isAutowired
156 |
157 | Allows to check if autowired is enabled.
158 |
159 | di
160 | .autowired();
161 |
162 | di.isAutowired; // true
163 |
164 | ### di.register(name)
165 |
166 | Defines registration's name. Parameter *name* is required and has to be a string.
167 |
168 | di.register('dieselEngine');
169 |
170 | Multiple registration's can be defined for a single name. A list of instances will be returned while resolving such registration by name.
171 |
172 | di
173 | .register('engine')
174 | .instance(new DieselEngine())
175 | .register('engine')
176 | .instance(new PetrolEngine());
177 |
178 | var engines = di.resolve('engine'); // []
179 |
180 | ### di.as(type)
181 |
182 | Maps a name with the given type. Parameter *type* is required and has to be a function.
183 |
184 | di.register('dieselEngine').as(DieselEngine);
185 |
186 | ### di.instance(instance)
187 |
188 | Maps registration's name with the given instance. Parameter *instance* is required and can be any type.
189 |
190 | var engine = new DieselEngine();
191 |
192 | di.register('dieselEngine').instance(engine);
193 |
194 | Various types can be used:
195 |
196 | di.register('number').instance(0);
197 | di.register('flag').instance(false);
198 | di.register('str').instance('Hello world!');
199 | di.register('date').instance(new Date());
200 | di.register('func').instance(function () { });
201 | di.register('obj').instance({});
202 |
203 | ### di.asSingleton()
204 |
205 | Marks type as singleton. If type is marked as singleton, the same instance always will be returned.
206 |
207 | di
208 | .register('dieselEngine')
209 | .as(DieselEngine)
210 | .asSingleton();
211 |
212 | ### di.withConstructor()
213 |
214 | Allows to define constructor's parameters.
215 |
216 | ### di.param(name)
217 |
218 | Defines constructor's parameter. Parameter *name* is optional and has to be a string or integer. It can represent parameter's name or index.
219 |
220 | Parameter can be defined without name. Index will be assigned automatically.
221 |
222 | di
223 | .register('car')
224 | .as(Car)
225 | .withConstructor()
226 | .param().val(new DieselEngine())
227 | .param().val(1976);
228 |
229 | di.resolve('car'); // { engine: { hp: 0 }, year: 1976 }
230 |
231 | Parameter can be defined by name or index.
232 |
233 | di
234 | .register('car')
235 | .as(Car)
236 | .withConstructor()
237 | .param('engine').val(new DieselEngine())
238 | .param(1).val(1976);
239 |
240 | di.resolve('car'); // { engine: { hp: 0 }, year: 1976 }
241 |
242 | ### di.withProperties()
243 |
244 | Allows to define type's properties.
245 |
246 | ### di.prop(name)
247 |
248 | Defines property. Parameter *name* is required and has to be a string.
249 |
250 | di
251 | .register('dieselEngine')
252 | .as(DieselEngine)
253 | .withProperties()
254 | .prop('hp').val(140);
255 |
256 | ### di.func(name)
257 |
258 | Defines function which has to be invoked while resoling type. Parameter *name* is required and has to be a string.
259 |
260 | di
261 | .register('car')
262 | .as(Car)
263 | .withProperties()
264 | .func('setEngine')
265 | .param().ref('dieselEngine');
266 |
267 | ### di.val(instance)
268 |
269 | Allows to define property's or constructor paramter's value. Parameter *instance* is required and can be any type.
270 |
271 | Constructor parameter's value is defined.
272 |
273 | di
274 | .register('dieselEngine')
275 | .as(DieselEngine)
276 | .withConstructor()
277 | .param().val(140);
278 |
279 | Property's value is defined.
280 |
281 | di
282 | .register('dieselEngine')
283 | .as(DieselEngine)
284 | .withProperties()
285 | .prop('hp').val(140);
286 |
287 | Function paramter's value is defined.
288 |
289 | di
290 | .register('car')
291 | .as(Car)
292 | .withProperties()
293 | .func('setEngine')
294 | .param().val(new DieselEngine());
295 |
296 | ### di.ref(name)
297 |
298 | Maps property or constructor's parameter with registered type in dependency resolver.
299 |
300 | Constructor's parameter can be resolved while instantiating a type.
301 |
302 | di
303 | .register('car')
304 | .withConstructor()
305 | .param().ref('dieselEngine');
306 |
307 | Property can be resolved while instantiating a type.
308 |
309 | di
310 | .register('car')
311 | .withProperties()
312 | .prop('engine').ref('dieselEngine');
313 |
314 | Function's paramter can be resolved while resolving a type.
315 |
316 | di
317 | .register('car')
318 | .as(Car)
319 | .withProperties()
320 | .func('setEngine')
321 | .param().ref('dieselEngine');
322 |
323 | ### di.setFactory(factory)
324 |
325 | Replaces default factory which is used while instantiating a new instance. Parameter *factory* is required and it accepts function or object.
326 |
327 | A function can be used:
328 |
329 | di
330 | .register('dieselEngine')
331 | .as(DieselEngine)
332 | .setFactory(function (options) {
333 | return new options.type();
334 | });
335 |
336 | An object which has a method *create* can be used:
337 |
338 | var CustomFactory = {
339 | create: function (options) {
340 | return new options.type();
341 | }
342 | };
343 |
344 | di
345 | .register('dieselEngine')
346 | .as(DieselEngine)
347 | .setFactory(CustomFactory);
348 |
349 | ### di.resolve(name)
350 |
351 | Resolves type or instance by name. Parameter *name* is required and has to be a string.
352 |
353 | di.register('dieselEngine').as(DieselEngine);
354 |
355 | var engine = di.resolve('dieselEngine');
356 |
357 | ### di.create()
358 |
359 | Allows to create child container. It usefull when you want to have more when one container or container per specific scope, or to override parent's container do not making inpact on it.
360 |
361 | var child = di.create();
362 | child
363 | .register('dieselEngine')
364 | .as(DieselEngine);
365 |
366 | di.contains('dieselEngine'); // false
367 | child.contains('dieselEngine'); // true
368 |
369 | ### di.inject(func)
370 |
371 | Allows to to inject dependencies to the function or to the instantiated object.
372 |
373 | Dependency are injected automatically by parameter's name to the function.
374 |
375 | di
376 | .register('dieselEngine')
377 | .as(DieselEngine);
378 |
379 | di.inject(function (dieselEngine) {
380 | engine.start(); // Diesel engine with 0 hp has been started...
381 | });
382 |
383 | An array notation can be used for injecting dependencies to the function.
384 |
385 | di
386 | .register('dieselEngine')
387 | .as(DieselEngine);
388 |
389 | di.inject(['dieselEngine', function (dieselEngine) {
390 | engine.start(); // Diesel engine with 0 hp has been started...
391 | }]);
392 |
393 | Properties of the object are set automatically by properties' names.
394 |
395 | di
396 | .register('engine')
397 | .as(DieselEngine);
398 |
399 | var car = new Car();
400 | di.inject(car); // { engine: { hp: 0 }, year: null }
401 |
402 | Registration's name, which has to be applied while injecting dependencies to the function, can be passed to *inject* method.
403 |
404 | di
405 | .register('dieselEngine')
406 | .as(DieselEngine)
407 | .register('car')
408 | .as(Car)
409 | .withConstructor()
410 | .param().ref('dieselEngine')
411 | .param().val(2000);
412 |
413 | di.inject(function (engine, year) {
414 | engine.start(); // Diesel engine with 0 hp has been started...
415 | }, 'car');
416 |
417 | Registration's name, which has to be applied while injecting dependencies to the object, can be passed to *inject* method.
418 |
419 | di
420 | .register('dieselEngine')
421 | .as(DieselEngine)
422 | .register('car')
423 | .as(Car)
424 | .withProperties()
425 | .prop('engine').ref('dieselEngine');
426 |
427 | var car = new Car();
428 | di.inject(car, 'car');
429 |
430 | ### di.contains(name)
431 |
432 | Allows to check if type or instance is registered in dependency resolver with given name. Parameter *name* is required and has to be a string.
433 |
434 | di.resolve('dieselEngine'); // false
435 |
436 | ### di.setDefaultFactory(factory)
437 |
438 | Replaces default factory of dependecy resolver. Factory is used to create instance from type's definition. Parameter *factory* is required and it accepts function or object.
439 |
440 | A function can be used.
441 |
442 | di
443 | .setDefaultFactory(function (options) {
444 | return new options.type();
445 | })
446 | .register('dieselEngine')
447 | .as(DieselEngine);
448 |
449 | An object which has method *created* can be used.
450 |
451 | var customFactory = {
452 | create: function options() {
453 | return new options.type();
454 | }
455 | };
456 |
457 | di
458 | .setDefaultFactory(customFactory)
459 | .register('dieselEngine')
460 | .as(DieselEngine);
461 |
462 | ### di.setNameTransformer(transformer)
463 |
464 | It is used to transform property's or constructor's parameter's name while resolving type's dependencies. Parameter *transformer* is required and it accepts function or object.
465 |
466 | A function can be used.
467 |
468 | di
469 | .autowired(true)
470 | .setNameTransformer(function (name) {
471 | return name.replace(/([A-Z])/g, function (str) {
472 | return '-' + str.toLowerCase();
473 | });
474 | })
475 | .register('diesel-engine')
476 | .as(DieselEngine)
477 | .register('tractor')
478 | .as(Tractor);
479 |
480 | di.resolve('tractor'); // { dieselEngine: { hp: 0 } }
481 |
482 | An object which has method *transform* can be used.
483 |
484 | var customNameTransformer = {
485 | transform: function (name) {
486 | return name.replace(/([A-Z])/g, function (str) {
487 | return '-' + str.toLowerCase();
488 | });
489 | }
490 | };
491 |
492 | di
493 | .autowired(true)
494 | .setNameTransformer(customNameTransformer)
495 | .register('diesel-engine')
496 | .as(DieselEngine)
497 | .register('tractor')
498 | .as(Tractor);
499 |
500 | di.resolve('tractor'); { dieselEngine: { hp: 0 } }
501 |
502 | ### di.getDefaultDependencyResolver()
503 |
504 | Returns default dependency resolver.
505 |
506 | ### di.setDefaultDependencyResolver(value)
507 |
508 | Allows to set default dependency resolver.
509 |
510 | ### di.debug
511 |
512 | This flag allows to print an additional information to the output.
513 |
514 | di.debug = true;
515 |
516 | ### di.dispose()
517 |
518 | Sets dependency resolver to initial state. All registered types and instances are removed from it.
519 |
520 | di
521 | .register('dieselEngine')
522 | .instance(new DieselEngine());
523 |
524 | di.dispose();
525 |
526 | di.resolve('dieselEngine'); // throws an exception
527 |
528 | ### di.version
529 |
530 | Returns module's version.
531 |
532 | di.version; // 1.0.0
533 |
534 | ## License
535 |
536 | This software is distributed under the terms of the MIT License (MIT).
537 |
538 | ## Authors
539 |
540 | Gediminas Backevcius / [@gedbac](https://twitter.com/gedbac)
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 1.1.5 (2020-06-12)
4 |
5 | - Object creation has been fixed
6 |
7 | ## 1.1.4 (2020-06-05)
8 |
9 | - Object creation has been fixed
10 |
11 | ## 1.1.3 (2015-03-04)
12 |
13 | - Registration resolving from parent's cantainer has been fixed
14 | - Now by default option autowired is the same as parent's
15 |
16 | ## 1.1.1 (2015-03-03)
17 |
18 | - Function invocation has been fixed
19 |
20 | ## 1.1.0 (2015-01-28)
21 |
22 | - AMD support has been added
23 | - Option to invoke function while resolving type has been added
24 | - Mode 'debug' is included. This flag allows to print an additional information to the output
25 | - Multiple registrations with same name can be defined
26 |
27 | ## 1.0.7 (2014-12-01)
28 |
29 | - Fixed bug: Dependencies' names has not been transformed while resolving dependencies in method 'inject'
30 | - Fixed bug: Dependecy resolver has been trying to resolve non existant dependency 'toString'
31 |
32 | ## 1.0.6 (2014-10-31)
33 |
34 | - Documentation has been updated
35 | - Version number has been fixed
36 |
37 | ## 1.0.5 (2014-10-28)
38 |
39 | - Development dependencies has been updated
40 | - Validation has been improved
41 | - License has been changed
--------------------------------------------------------------------------------
/di4js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"di4js.min.js","sources":["di4js.js"],"names":["exports","define","amd","window","di","version","DependencyResolverException","message","this","__name","__stack","__message","lines","i","tmp","navigator","userAgent","indexOf","Error","stack","split","length","push","trim","join","replace","error","Object","defineProperty","enumerable","seal","prototype","create","name","get","set","value","toString","msg","InstanceFactoryOptions","options","__type","__parameters","propertyName","type","parameters","IInstanceFactory","freeze","InstanceFactory","Number","Date","Boolean","String","Array","Function","RegExp","Type","apply","INameTransformer","transform","NameTransformer","IDependencyResolver","isAutowired","autowired","register","as","instance","asSingleton","withConstructor","param","withProperties","prop","val","ref","setFactory","factory","inject","func","contains","resolve","getDefaultFactory","setDefaultFactory","getNameTransformer","setNameTransformer","transformer","getRegistration","dispose","DependencyResolver","parent","__parent","__defaultFactory","__nameTransformer","__autowired","__container","__registration","__withProperties","__withConstructor","__parameter","__property","__function","undefined","singleton","dependencies","properties","functions","parameter","index","__findParameter","reference","property","context","resolving","__resolve","registration","arguments","dependencyName","__getConstructorParameters","args","__getFunctionArguments","__resolveDependencyName","__setProperties","__invokeFunctions","has","registrations","str","result","match","debug","console","j","log","__resolveInstance","splice","__createInstance","call","__hasProperty","defaultDependencyResolver","getDefaultDependencyResolver"],"mappings":"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"}
--------------------------------------------------------------------------------
/di4js.min.js:
--------------------------------------------------------------------------------
1 | (function(exports){"use strict";exports=exports||{};if(typeof define==="function"&&define.amd){define(function(){return exports})}else{window.di=exports}if(!("version"in exports)){exports.version="1.1.5"}var DependencyResolverException=function(message){this.__name="DependencyResolverException";this.__stack=null;this.__message=message||"A dependency resolver exception has occurred.";var lines,i,tmp;if(typeof navigator!=="undefined"&&navigator.userAgent.indexOf("Chrome")!==-1||typeof navigator==="undefined"){lines=(new Error).stack.split("\n");if(lines&&lines.length>2){tmp=[];for(i=2;i1){tmp=[];for(i=1;i2){tmp=[];for(i=2;i0){Type=function(){return options.type.apply(this,options.parameters)};Type.prototype=Object.create(options.type.prototype)}return new Type},enumerable:true},toString:{value:function(){return"[object InstanceFactory]"},enumerable:true}});Object.seal(InstanceFactory);Object.seal(InstanceFactory.prototype);exports.InstanceFactory=InstanceFactory;var INameTransformer=Object.create(Object.prototype,{transform:{value:function(name){},enumerable:true},toString:{value:function(){return"[object INameTransformer]"},enumerable:true}});Object.freeze(INameTransformer);exports.INameTransformer=INameTransformer;var NameTransformer=function(){Object.seal(this)};NameTransformer.prototype=Object.create(Object.prototype,{transform:{value:function(name){if(!name){throw new DependencyResolverException("Parameter 'name' is not passed to the method 'transform'")}return name},enumerable:true},toString:{value:function(){return"[object NameTransformer]"},enumerable:true}});Object.seal(NameTransformer);Object.seal(NameTransformer.prototype);exports.NameTransformer=NameTransformer;var IDependencyResolver=Object.create(Object.prototype,{isAutowired:{get:function(){},enumerable:true},autowired:{value:function(value){},enumerable:true},register:{value:function(name){},enumerable:true},as:{value:function(type){},enumerable:true},instance:{value:function(instance){},enumerable:true},asSingleton:{value:function(){},enumerable:true},withConstructor:{value:function(){},enumerable:true},param:{value:function(name){},enumerable:true},withProperties:{value:function(name){},enumerable:true},prop:{value:function(name){},enumerable:true},val:{value:function(instance){},enumerable:true},ref:{value:function(name){},enumerable:true},setFactory:{value:function(factory){},enumerable:true},create:{value:function(){},enumerable:true},inject:{value:function(func,name){},enumerable:true},contains:{value:function(name){},enumerable:true},resolve:{value:function(name){},enumerable:true},getDefaultFactory:{value:function(){},enumerable:true},setDefaultFactory:{value:function(factory){},enumerable:true},getNameTransformer:{value:function(){},enumerable:true},setNameTransformer:{value:function(transformer){},enumerable:true},getRegistration:{value:function(name){},enumerable:true},dispose:{value:function(){},enumerable:true},toString:{value:function(){return"[object IDependencyResolver]"},enumerable:true}});Object.freeze(IDependencyResolver);exports.IDependencyResolver=IDependencyResolver;var DependencyResolver=function(parent){this.__parent=parent;this.__defaultFactory=null;this.__nameTransformer=null;this.__autowired=false;this.__container=null;this.__registration=null;this.__withProperties=false;this.__withConstructor=false;this.__parameter=null;this.__property=null;this.__function=null;if(parent){this.__autowired=parent.isAutowired}Object.defineProperty(this,"__parent",{enumerable:false});Object.defineProperty(this,"__defaultFactory",{enumerable:false});Object.defineProperty(this,"__nameTransformer",{enumerable:false});Object.defineProperty(this,"__autowired",{enumerable:false});Object.defineProperty(this,"__container",{enumerable:false});Object.defineProperty(this,"__registration",{enumerable:false});Object.defineProperty(this,"__withProperties",{enumerable:false});Object.defineProperty(this,"__withConstructor",{enumerable:false});Object.defineProperty(this,"__parameter",{enumerable:false});Object.defineProperty(this,"__property",{enumerable:false});Object.defineProperty(this,"__function",{enumerable:false});Object.seal(this)};DependencyResolver.prototype=Object.create(Object.prototype,{isAutowired:{get:function(){return this.__autowired},enumerable:true},autowired:{value:function(value){if(value===undefined||value===null){value=true}if(typeof value!=="boolean"){throw new DependencyResolverException("Parameter 'value' passed to the method 'autowired' has to "+"be a 'boolean'")}this.__autowired=value;return this},enumerable:true},register:{value:function(name){if(!name){throw new DependencyResolverException("Parameter 'name' is not passed to the method 'register'")}if(typeof name!=="string"){throw new DependencyResolverException("Parameter 'name' passed to the method 'register' has to be "+"a 'string'")}if(!this.__container){this.__container=Object.create(null)}this.__registration={name:name,singleton:false,type:null,instance:null,factory:null,dependencies:null};if(!(name in this.__container)){this.__container[name]=this.__registration}else{if(!(this.__container[name]instanceof Array)){this.__container[name]=[this.__container[name]]}this.__container[name].push(this.__registration)}this.__withConstructor=false;this.__withProperties=false;this.__parameter=null;this.__property=null;return this},enumerable:true},as:{value:function(type){if(!this.__registration){throw new DependencyResolverException("Registration's name is not defined")}if(!type){throw new DependencyResolverException("Parameter 'type' is not passed to the method 'as' for "+"registration '"+this.__registration.name+"'")}if(typeof type!=="function"){throw new DependencyResolverException("Parameter 'type' passed to the method 'as' has to be a 'function' "+"for registration '"+this.__registration.name+"'")}this.__registration.instance=null;this.__registration.type=type;this.__registration.singleton=false;this.__registration.dependencies={parameters:[],properties:[],functions:[]};this.__withConstructor=false;this.__withProperties=false;this.__parameter=null;this.__property=null;this.__function=null;return this},enumerable:true},instance:{value:function(instance){if(!this.__registration){throw new DependencyResolverException("Registration's name is not defined")}if(instance===null||instance===undefined){throw new DependencyResolverException("Parameter 'instance' is not passed to the method 'instance' for "+"registration '"+this.__registration.name+"'")}this.__registration.instance=instance;this.__registration.type=null;this.__registration.factory=null;this.__registration.singleton=true;this.__registration.dependencies=null;this.__withConstructor=false;this.__withProperties=false;this.__parameter=null;this.__property=null;this.__function=null;return this},enumerable:true},asSingleton:{value:function(){if(!this.__registration){throw new DependencyResolverException("Registration's name is not defined")}if(!this.__registration.type){throw new DependencyResolverException("Type is not set for registration '"+this.__registration.name+"'")}this.__registration.singleton=true;this.__withConstructor=false;this.__withProperties=false;this.__parameter=null;this.__property=null;this.__function=null;return this},enumerable:true},withConstructor:{value:function(){if(!this.__registration){throw new DependencyResolverException("Registration's name is not defined")}if(!this.__registration.type){throw new DependencyResolverException("Type is not set for registration '"+this.__registration.name+"'")}this.__withConstructor=true;this.__withProperties=false;this.__parameter=null;this.__property=null;this.__function=null;return this},enumerable:true},param:{value:function(name){if(!this.__registration){throw new DependencyResolverException("Registration's name is not defined")}if(!this.__registration.type){throw new DependencyResolverException("Type is not set for registration '"+this.__registration.name+"'")}var parameters=null,parameter=null,index;if(this.__withConstructor){parameters=this.__registration.dependencies.parameters;if(this.__autowired&&(name===undefined||name===null)){throw new DependencyResolverException("Parameter 'name' has to be passed to the method, when dependency "+"container has option 'autowired' enabled")}parameter=this.__findParameter(name,parameters,this.__registration)}else if(this.__withProperties){if(!this.__function){throw new DependencyResolverException("Function is not defined")}parameters=this.__function.parameters;parameter=this.__findParameter(name,this.__function.parameters,this.__registration)}else{throw new DependencyResolverException("Invocation of method 'withConstructor' or 'withProperties' "+"is missing for registration '"+this.__registration.name+"'")}if(!parameter){parameter={index:index,name:name,value:undefined,reference:undefined};parameters.push(parameter)}this.__parameter=parameter;this.__property=null;return this},enumerable:true},withProperties:{value:function(){if(!this.__registration){throw new DependencyResolverException("Registration's name is not defined")}if(!this.__registration.type){throw new DependencyResolverException("Type is not set for registration '"+this.__registration.name+"'")}this.__withProperties=true;this.__withConstructor=false;this.__parameter=null;this.__property=null;this.__function=null;return this},enumerable:true},prop:{value:function(name){if(!this.__registration){throw new DependencyResolverException("Registration's name is not defined")}if(!name){throw new DependencyResolverException("Parameter 'name' is not passed to the method 'prop' for "+"registration '"+this.__registration.name+"'")}if(typeof name!=="string"){throw new DependencyResolverException("Parameter 'name' passed to the method 'prop' has to be"+" a 'string' for registration '"+this.__registration.name+"'")}if(!this.__registration.type){throw new DependencyResolverException("Type is not set for registration '"+this.__registration.name+"'")}if(!this.__withProperties){throw new DependencyResolverException("Invocation of method 'withProperties' is missing for "+"registration '"+this.__registration.name+"'")}var properties=this.__registration.dependencies.properties,property=null;for(var i=0;i0){for(i=0;i1){str=result[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g,"").replace(/\s+/g,"")}if(str){return str.split(",")}}return[]}},__resolve:{value:function(name,context){if(!name){throw new DependencyResolverException("Parameter 'name' is not passed to the method 'resolve'")}if(typeof name!=="string"){throw new DependencyResolverException("Parameter 'name' passed to the method 'resolve' has to be "+"a 'string'")}if(debug&&console&&"log"in console){var message="-> '"+name+"'";for(var j=0;j-1){context.resolving.splice(index,1)}return instance}},__resolveInstance:{value:function(registration,context){var instance=null;if(registration.instance!==null&®istration.instance!==undefined){instance=registration.instance}else{instance=this.__createInstance(registration,context);this.__setProperties(instance,registration,context);this.__invokeFunctions(instance,registration,context);if(instance&®istration.singleton){registration.instance=instance}if(!instance){throw new DependencyResolverException("Failed to resolve instance by name '"+registration.name+"'")}}return instance}},__resolveDependencyName:{value:function(name){var transform=this.getNameTransformer();if(typeof transform==="function"){name=transform(name)}else{name=transform.transform(name)}if(!name){throw new DependencyResolverException("Failed to resolve dependency name")}return name}},__createInstance:{value:function(registration,context){var i,instance;var parameters=this.__getConstructorParameters(registration,context);var options=new InstanceFactoryOptions({name:registration.name,type:registration.type,parameters:parameters});var factory=null;if(registration.factory){factory=registration.factory}else{factory=this.getDefaultFactory()}if(factory){if(typeof factory==="function"){instance=factory.call(null,options)}else{instance=factory.create(options)}}else{throw new DependencyResolverException("Default factory is not defined")}return instance}},__getConstructorParameters:{value:function(registration,context){var parameters=[];if(registration&®istration.dependencies){var i,parameter,value,args,index;if(this.__autowired){args=this.__getFunctionArguments(registration.type);var dependencyName;for(i=0;i
2 |
3 |
4 |
5 | AMD
6 |
7 |
8 |
9 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/amd/require.js:
--------------------------------------------------------------------------------
1 | /*
2 | RequireJS 2.1.16 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved.
3 | Available via the MIT or new BSD license.
4 | see: http://github.com/jrburke/requirejs for details
5 | */
6 | var requirejs,require,define;
7 | (function(ba){function G(b){return"[object Function]"===K.call(b)}function H(b){return"[object Array]"===K.call(b)}function v(b,c){if(b){var d;for(d=0;dthis.depCount&&!this.defined){if(G(l)){if(this.events.error&&this.map.isDefine||g.onError!==ca)try{f=i.execCb(c,l,b,f)}catch(d){a=d}else f=i.execCb(c,l,b,f);this.map.isDefine&&void 0===f&&((b=this.module)?f=b.exports:this.usingExports&&
19 | (f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=l;this.exports=f;if(this.map.isDefine&&!this.ignore&&(r[c]=f,g.onResourceLoad))g.onResourceLoad(i,this.map,this.depMaps);y(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=
20 | this.map,b=a.id,d=p(a.prefix);this.depMaps.push(d);q(d,"defined",u(this,function(f){var l,d;d=m(aa,this.map.id);var e=this.map.name,P=this.map.parentMap?this.map.parentMap.name:null,n=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(e=f.normalize(e,function(a){return c(a,P,!0)})||""),f=p(a.prefix+"!"+e,this.map.parentMap),q(f,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=m(h,f.id)){this.depMaps.push(f);
21 | if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else d?(this.map.url=i.nameToUrl(d),this.load()):(l=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),l.error=u(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(h,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),l.fromText=u(this,function(f,c){var d=a.name,e=p(d),P=M;c&&(f=c);P&&(M=!1);s(e);t(j.config,b)&&(j.config[d]=j.config[b]);try{g.exec(f)}catch(h){return w(C("fromtexteval",
22 | "fromText eval for "+b+" failed: "+h,h,[b]))}P&&(M=!0);this.depMaps.push(e);i.completeLoad(d);n([d],l)}),f.load(a.name,n,l,j))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){V[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,u(this,function(a,b){var c,f;if("string"===typeof a){a=p(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=m(L,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;q(a,"defined",u(this,function(a){this.defineDep(b,
23 | a);this.check()}));this.errback?q(a,"error",u(this,this.errback)):this.events.error&&q(a,"error",u(this,function(a){this.emit("error",a)}))}c=a.id;f=h[c];!t(L,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,u(this,function(a){var b=m(h,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:j,contextName:b,
24 | registry:h,defined:r,urlFetched:S,defQueue:A,Module:Z,makeModuleMap:p,nextTick:g.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=j.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(j[b]||(j[b]={}),U(j[b],a,!0,!0)):j[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(aa[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);
25 | b[c]=a}),j.shim=b);a.packages&&v(a.packages,function(a){var b,a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(j.paths[b]=a.location);j.pkgs[b]=a.name+"/"+(a.main||"main").replace(ia,"").replace(Q,"")});B(h,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=p(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ba,arguments));return b||a.exports&&da(a.exports)}},makeRequire:function(a,e){function j(c,d,m){var n,
26 | q;e.enableBuildCallback&&(d&&G(d))&&(d.__requireJsBuild=!0);if("string"===typeof c){if(G(d))return w(C("requireargs","Invalid require call"),m);if(a&&t(L,c))return L[c](h[a.id]);if(g.get)return g.get(i,c,a,j);n=p(c,a,!1,!0);n=n.id;return!t(r,n)?w(C("notloaded",'Module name "'+n+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):r[n]}J();i.nextTick(function(){J();q=s(p(null,a));q.skipMap=e.skipMap;q.init(c,d,m,{enabled:!0});D()});return j}e=e||{};U(j,{isBrowser:z,toUrl:function(b){var d,
27 | e=b.lastIndexOf("."),k=b.split("/")[0];if(-1!==e&&(!("."===k||".."===k)||1e.attachEvent.toString().indexOf("[native code"))&&
34 | !Y?(M=!0,e.attachEvent("onreadystatechange",b.onScriptLoad)):(e.addEventListener("load",b.onScriptLoad,!1),e.addEventListener("error",b.onScriptError,!1)),e.src=d,J=e,D?y.insertBefore(e,D):y.appendChild(e),J=null,e;if(ea)try{importScripts(d),b.completeLoad(c)}catch(m){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,m,[c]))}};z&&!q.skipDataMain&&T(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(I=b.getAttribute("data-main"))return s=I,q.baseUrl||(E=s.split("/"),
35 | s=E.pop(),O=E.length?E.join("/")+"/":"./",q.baseUrl=O),s=s.replace(Q,""),g.jsExtRegExp.test(s)&&(s=I),q.deps=q.deps?q.deps.concat(s):[s],!0});define=function(b,c,d){var e,g;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(ka,"").replace(la,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(M){if(!(e=J))N&&"interactive"===N.readyState||T(document.getElementsByTagName("script"),function(b){if("interactive"===
36 | b.readyState)return N=b}),e=N;e&&(b||(b=e.getAttribute("data-requiremodule")),g=F[e.getAttribute("data-requirecontext")])}(g?g.defQueue:R).push([b,c,d])};define.amd={jQuery:!0};g.exec=function(b){return eval(b)};g(q)}})(this);
37 |
--------------------------------------------------------------------------------
/examples/amd/script.js:
--------------------------------------------------------------------------------
1 | define(['di4js'], function (di) {
2 |
3 | function Engine(hp) {
4 | this.hp = hp;
5 | }
6 |
7 | Engine.prototype.start = function () {
8 | console.log("Engine with " + this.hp + " hp has been started...");
9 | }
10 |
11 | di
12 | .register("engine")
13 | .as(Engine)
14 | .withConstructor()
15 | .param().val(256);
16 |
17 | var engine = di.resolve("engine");
18 |
19 | engine.start();
20 |
21 | });
--------------------------------------------------------------------------------
/examples/autowired/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Autowire
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/autowired/script.js:
--------------------------------------------------------------------------------
1 | function Engine() {
2 |
3 | }
4 |
5 | Engine.prototype.start = function () {
6 | console.log("Engine has been started...");
7 | }
8 |
9 | function Car() {
10 | this.engine = null;
11 | }
12 |
13 | Car.prototype.start = function () {
14 | if (this.engine) {
15 | this.engine.start();
16 | }
17 | console.log("Car has been started...");
18 | }
19 |
20 | di
21 | .autowired(true)
22 | .register('engine')
23 | .as(Engine)
24 | .register('car')
25 | .as(Car);
26 |
27 | var car = di.resolve('car');
28 |
29 | car.start();
--------------------------------------------------------------------------------
/examples/child container/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Child Container
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/child container/script.js:
--------------------------------------------------------------------------------
1 | var DieselEngine = function () {
2 | };
3 |
4 | DieselEngine.prototype.start = function () {
5 | console.log("Diesel engine has been started...");
6 | };
7 |
8 | var PetrolEngine = function () {
9 | };
10 |
11 | PetrolEngine.prototype.start = function () {
12 | console.log("Petrol engine has been started...");
13 | };
14 |
15 | function Car(engine) {
16 | this.engine = engine;
17 | }
18 |
19 | Car.prototype.start = function () {
20 | if (this.engine) {
21 | this.engine.start();
22 | }
23 | console.log("Car has been started...");
24 | }
25 |
26 | di
27 | .autowired(true)
28 | .register('engine')
29 | .as(DieselEngine)
30 | .register('car')
31 | .as(Car);
32 |
33 | var car = di.resolve('car');
34 | car.start();
35 |
36 | var child = di
37 | .create()
38 | .register('engine')
39 | .as(PetrolEngine);
40 |
41 | car = child.resolve('car');
42 | car.start();
43 |
--------------------------------------------------------------------------------
/examples/fluent/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Fluent
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/fluent/script.js:
--------------------------------------------------------------------------------
1 | function Engine(hp) {
2 | this.hp = hp;
3 | }
4 |
5 | Engine.prototype.start = function () {
6 | console.log("Engine with " + this.hp + " hp has been started...");
7 | }
8 |
9 | function Car(name) {
10 | this.name = name;
11 | }
12 |
13 | Car.prototype.setEngine = function (engine) {
14 | this.engine = engine;
15 | return this;
16 | };
17 |
18 | Car.prototype.start = function () {
19 | if (this.engine) {
20 | this.engine.start();
21 | }
22 | console.log("Car '" + this.name + "' has been started...");
23 | }
24 |
25 | function Driver(name) {
26 | this.name = name;
27 | }
28 |
29 | Driver.prototype.setCars = function (cars) {
30 | this.cars = cars;
31 | return this;
32 | };
33 |
34 | Driver.prototype.drive = function (name) {
35 | if (this.cars && name) {
36 | if (this.cars instanceof Array) {
37 | for (var i = 0; i < this.cars.length; i++) {
38 | if (this.cars[i].name === name) {
39 | this.cars[i].start();
40 | break;
41 | }
42 | }
43 | } else if (this.cars.name === name) {
44 | this.cars.start();
45 | }
46 | }
47 | }
48 |
49 | di
50 | .register('engine')
51 | .as(Engine)
52 | .withConstructor()
53 | .param().val(256)
54 | .register('car')
55 | .as(Car)
56 | .withConstructor()
57 | .param().val('wv')
58 | .withProperties()
59 | .func('setEngine')
60 | .param().ref('engine')
61 | .register('car')
62 | .as(Car)
63 | .withConstructor()
64 | .param().val('ford')
65 | .withProperties()
66 | .func('setEngine')
67 | .param().ref('engine')
68 | .register('tom')
69 | .as(Driver)
70 | .withConstructor()
71 | .param().val('tom')
72 | .withProperties()
73 | .func('setCars')
74 | .param().ref('car');
75 |
76 | var tom = di.resolve('tom');
77 |
78 | tom.drive('wv');
--------------------------------------------------------------------------------
/examples/injection/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Injection
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/injection/script.js:
--------------------------------------------------------------------------------
1 | function Engine() {
2 |
3 | }
4 |
5 | Engine.prototype.start = function () {
6 | console.log("Engine has been started...");
7 | }
8 |
9 | function Car() {
10 | this.engine = null;
11 | }
12 |
13 | Car.prototype.start = function () {
14 | if (this.engine) {
15 | this.engine.start();
16 | }
17 | console.log("Car has been started...");
18 | }
19 |
20 | di
21 | .autowired(true)
22 | .register('engine')
23 | .as(Engine)
24 | .register('car')
25 | .as(Car);
26 |
27 | di.inject(function (car) {
28 | car.start();
29 | });
30 |
31 | di.inject(['car', function (car) {
32 | car.start();
33 | }]);
34 |
35 | var car = new Car();
36 | di.inject(car);
37 |
38 | car.start();
39 |
40 | var car = new Car();
41 | di.inject(car, 'car');
42 |
43 | car.start();
--------------------------------------------------------------------------------
/examples/list/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | List
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/list/script.js:
--------------------------------------------------------------------------------
1 | function Engine(hp) {
2 | this.hp = hp;
3 | }
4 |
5 | Engine.prototype.start = function () {
6 | console.log("Engine with " + this.hp + " hp has been started...");
7 | }
8 |
9 | function Car(name, engine) {
10 | this.name = name;
11 | this.engine = engine;
12 | }
13 |
14 | Car.prototype.start = function () {
15 | if (this.engine) {
16 | this.engine.start();
17 | }
18 | console.log("Car '" + this.name + "' has been started...");
19 | }
20 |
21 | function Driver(name) {
22 | this.name = name;
23 | this.cars = [];
24 | }
25 |
26 | Driver.prototype.drive = function (name) {
27 | if (this.cars && name) {
28 | if (this.cars instanceof Array) {
29 | for (var i = 0; i < this.cars.length; i++) {
30 | if (this.cars[i].name === name) {
31 | this.cars[i].start();
32 | break;
33 | }
34 | }
35 | } else if (this.cars.name === name) {
36 | this.cars.start();
37 | }
38 | }
39 | }
40 |
41 | di
42 | .register('engine')
43 | .as(Engine)
44 | .withConstructor()
45 | .param().val(256)
46 | .register('car')
47 | .as(Car)
48 | .withConstructor()
49 | .param().val('wv')
50 | .param().ref('engine')
51 | .register('car')
52 | .as(Car)
53 | .withConstructor()
54 | .param().val('ford')
55 | .param().ref('engine')
56 | .register('tom')
57 | .as(Driver)
58 | .withConstructor()
59 | .param().val('tom')
60 | .withProperties()
61 | .prop('cars').ref('car');
62 |
63 | var tom = di.resolve('tom');
64 |
65 | console.log(JSON.stringify(tom.cars));
66 |
67 | tom.drive('wv');
--------------------------------------------------------------------------------
/examples/testing/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Testing
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/examples/testing/jasmine-2.2.0/boot.js:
--------------------------------------------------------------------------------
1 | /**
2 | Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
3 |
4 | If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
5 |
6 | The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
7 |
8 | [jasmine-gem]: http://github.com/pivotal/jasmine-gem
9 | */
10 |
11 | (function() {
12 |
13 | /**
14 | * ## Require & Instantiate
15 | *
16 | * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
17 | */
18 | window.jasmine = jasmineRequire.core(jasmineRequire);
19 |
20 | /**
21 | * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
22 | */
23 | jasmineRequire.html(jasmine);
24 |
25 | /**
26 | * Create the Jasmine environment. This is used to run all specs in a project.
27 | */
28 | var env = jasmine.getEnv();
29 |
30 | /**
31 | * ## The Global Interface
32 | *
33 | * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
34 | */
35 | var jasmineInterface = jasmineRequire.interface(jasmine, env);
36 |
37 | /**
38 | * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
39 | */
40 | if (typeof window == "undefined" && typeof exports == "object") {
41 | extend(exports, jasmineInterface);
42 | } else {
43 | extend(window, jasmineInterface);
44 | }
45 |
46 | /**
47 | * ## Runner Parameters
48 | *
49 | * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
50 | */
51 |
52 | var queryString = new jasmine.QueryString({
53 | getWindowLocation: function() { return window.location; }
54 | });
55 |
56 | var catchingExceptions = queryString.getParam("catch");
57 | env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
58 |
59 | /**
60 | * ## Reporters
61 | * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
62 | */
63 | var htmlReporter = new jasmine.HtmlReporter({
64 | env: env,
65 | onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
66 | addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
67 | getContainer: function() { return document.body; },
68 | createElement: function() { return document.createElement.apply(document, arguments); },
69 | createTextNode: function() { return document.createTextNode.apply(document, arguments); },
70 | timer: new jasmine.Timer()
71 | });
72 |
73 | /**
74 | * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
75 | */
76 | env.addReporter(jasmineInterface.jsApiReporter);
77 | env.addReporter(htmlReporter);
78 |
79 | /**
80 | * Filter which specs will be run by matching the start of the full name against the `spec` query param.
81 | */
82 | var specFilter = new jasmine.HtmlSpecFilter({
83 | filterString: function() { return queryString.getParam("spec"); }
84 | });
85 |
86 | env.specFilter = function(spec) {
87 | return specFilter.matches(spec.getFullName());
88 | };
89 |
90 | /**
91 | * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
92 | */
93 | window.setTimeout = window.setTimeout;
94 | window.setInterval = window.setInterval;
95 | window.clearTimeout = window.clearTimeout;
96 | window.clearInterval = window.clearInterval;
97 |
98 | /**
99 | * ## Execution
100 | *
101 | * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
102 | */
103 | var currentWindowOnload = window.onload;
104 |
105 | window.onload = function() {
106 | if (currentWindowOnload) {
107 | currentWindowOnload();
108 | }
109 | htmlReporter.initialize();
110 | env.execute();
111 | };
112 |
113 | /**
114 | * Helper function for readability above.
115 | */
116 | function extend(destination, source) {
117 | for (var property in source) destination[property] = source[property];
118 | return destination;
119 | }
120 |
121 | }());
122 |
--------------------------------------------------------------------------------
/examples/testing/jasmine-2.2.0/console.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2015 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | function getJasmineRequireObj() {
24 | if (typeof module !== 'undefined' && module.exports) {
25 | return exports;
26 | } else {
27 | window.jasmineRequire = window.jasmineRequire || {};
28 | return window.jasmineRequire;
29 | }
30 | }
31 |
32 | getJasmineRequireObj().console = function(jRequire, j$) {
33 | j$.ConsoleReporter = jRequire.ConsoleReporter();
34 | };
35 |
36 | getJasmineRequireObj().ConsoleReporter = function() {
37 |
38 | var noopTimer = {
39 | start: function(){},
40 | elapsed: function(){ return 0; }
41 | };
42 |
43 | function ConsoleReporter(options) {
44 | var print = options.print,
45 | showColors = options.showColors || false,
46 | onComplete = options.onComplete || function() {},
47 | timer = options.timer || noopTimer,
48 | specCount,
49 | failureCount,
50 | failedSpecs = [],
51 | pendingCount,
52 | ansi = {
53 | green: '\x1B[32m',
54 | red: '\x1B[31m',
55 | yellow: '\x1B[33m',
56 | none: '\x1B[0m'
57 | },
58 | failedSuites = [];
59 |
60 | print('ConsoleReporter is deprecated and will be removed in a future version.');
61 |
62 | this.jasmineStarted = function() {
63 | specCount = 0;
64 | failureCount = 0;
65 | pendingCount = 0;
66 | print('Started');
67 | printNewline();
68 | timer.start();
69 | };
70 |
71 | this.jasmineDone = function() {
72 | printNewline();
73 | for (var i = 0; i < failedSpecs.length; i++) {
74 | specFailureDetails(failedSpecs[i]);
75 | }
76 |
77 | if(specCount > 0) {
78 | printNewline();
79 |
80 | var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
81 | failureCount + ' ' + plural('failure', failureCount);
82 |
83 | if (pendingCount) {
84 | specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
85 | }
86 |
87 | print(specCounts);
88 | } else {
89 | print('No specs found');
90 | }
91 |
92 | printNewline();
93 | var seconds = timer.elapsed() / 1000;
94 | print('Finished in ' + seconds + ' ' + plural('second', seconds));
95 | printNewline();
96 |
97 | for(i = 0; i < failedSuites.length; i++) {
98 | suiteFailureDetails(failedSuites[i]);
99 | }
100 |
101 | onComplete(failureCount === 0);
102 | };
103 |
104 | this.specDone = function(result) {
105 | specCount++;
106 |
107 | if (result.status == 'pending') {
108 | pendingCount++;
109 | print(colored('yellow', '*'));
110 | return;
111 | }
112 |
113 | if (result.status == 'passed') {
114 | print(colored('green', '.'));
115 | return;
116 | }
117 |
118 | if (result.status == 'failed') {
119 | failureCount++;
120 | failedSpecs.push(result);
121 | print(colored('red', 'F'));
122 | }
123 | };
124 |
125 | this.suiteDone = function(result) {
126 | if (result.failedExpectations && result.failedExpectations.length > 0) {
127 | failureCount++;
128 | failedSuites.push(result);
129 | }
130 | };
131 |
132 | return this;
133 |
134 | function printNewline() {
135 | print('\n');
136 | }
137 |
138 | function colored(color, str) {
139 | return showColors ? (ansi[color] + str + ansi.none) : str;
140 | }
141 |
142 | function plural(str, count) {
143 | return count == 1 ? str : str + 's';
144 | }
145 |
146 | function repeat(thing, times) {
147 | var arr = [];
148 | for (var i = 0; i < times; i++) {
149 | arr.push(thing);
150 | }
151 | return arr;
152 | }
153 |
154 | function indent(str, spaces) {
155 | var lines = (str || '').split('\n');
156 | var newArr = [];
157 | for (var i = 0; i < lines.length; i++) {
158 | newArr.push(repeat(' ', spaces).join('') + lines[i]);
159 | }
160 | return newArr.join('\n');
161 | }
162 |
163 | function specFailureDetails(result) {
164 | printNewline();
165 | print(result.fullName);
166 |
167 | for (var i = 0; i < result.failedExpectations.length; i++) {
168 | var failedExpectation = result.failedExpectations[i];
169 | printNewline();
170 | print(indent(failedExpectation.message, 2));
171 | print(indent(failedExpectation.stack, 2));
172 | }
173 |
174 | printNewline();
175 | }
176 |
177 | function suiteFailureDetails(result) {
178 | for (var i = 0; i < result.failedExpectations.length; i++) {
179 | printNewline();
180 | print(colored('red', 'An error was thrown in an afterAll'));
181 | printNewline();
182 | print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
183 |
184 | }
185 | printNewline();
186 | }
187 | }
188 |
189 | return ConsoleReporter;
190 | };
191 |
--------------------------------------------------------------------------------
/examples/testing/jasmine-2.2.0/jasmine-html.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2015 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | jasmineRequire.html = function(j$) {
24 | j$.ResultsNode = jasmineRequire.ResultsNode();
25 | j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
26 | j$.QueryString = jasmineRequire.QueryString();
27 | j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
28 | };
29 |
30 | jasmineRequire.HtmlReporter = function(j$) {
31 |
32 | var noopTimer = {
33 | start: function() {},
34 | elapsed: function() { return 0; }
35 | };
36 |
37 | function HtmlReporter(options) {
38 | var env = options.env || {},
39 | getContainer = options.getContainer,
40 | createElement = options.createElement,
41 | createTextNode = options.createTextNode,
42 | onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
43 | addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
44 | timer = options.timer || noopTimer,
45 | results = [],
46 | specsExecuted = 0,
47 | failureCount = 0,
48 | pendingSpecCount = 0,
49 | htmlReporterMain,
50 | symbols,
51 | failedSuites = [];
52 |
53 | this.initialize = function() {
54 | clearPrior();
55 | htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
56 | createDom('div', {className: 'banner'},
57 | createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}),
58 | createDom('span', {className: 'version'}, j$.version)
59 | ),
60 | createDom('ul', {className: 'symbol-summary'}),
61 | createDom('div', {className: 'alert'}),
62 | createDom('div', {className: 'results'},
63 | createDom('div', {className: 'failures'})
64 | )
65 | );
66 | getContainer().appendChild(htmlReporterMain);
67 |
68 | symbols = find('.symbol-summary');
69 | };
70 |
71 | var totalSpecsDefined;
72 | this.jasmineStarted = function(options) {
73 | totalSpecsDefined = options.totalSpecsDefined || 0;
74 | timer.start();
75 | };
76 |
77 | var summary = createDom('div', {className: 'summary'});
78 |
79 | var topResults = new j$.ResultsNode({}, '', null),
80 | currentParent = topResults;
81 |
82 | this.suiteStarted = function(result) {
83 | currentParent.addChild(result, 'suite');
84 | currentParent = currentParent.last();
85 | };
86 |
87 | this.suiteDone = function(result) {
88 | if (result.status == 'failed') {
89 | failedSuites.push(result);
90 | }
91 |
92 | if (currentParent == topResults) {
93 | return;
94 | }
95 |
96 | currentParent = currentParent.parent;
97 | };
98 |
99 | this.specStarted = function(result) {
100 | currentParent.addChild(result, 'spec');
101 | };
102 |
103 | var failures = [];
104 | this.specDone = function(result) {
105 | if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
106 | console.error('Spec \'' + result.fullName + '\' has no expectations.');
107 | }
108 |
109 | if (result.status != 'disabled') {
110 | specsExecuted++;
111 | }
112 |
113 | symbols.appendChild(createDom('li', {
114 | className: noExpectations(result) ? 'empty' : result.status,
115 | id: 'spec_' + result.id,
116 | title: result.fullName
117 | }
118 | ));
119 |
120 | if (result.status == 'failed') {
121 | failureCount++;
122 |
123 | var failure =
124 | createDom('div', {className: 'spec-detail failed'},
125 | createDom('div', {className: 'description'},
126 | createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
127 | ),
128 | createDom('div', {className: 'messages'})
129 | );
130 | var messages = failure.childNodes[1];
131 |
132 | for (var i = 0; i < result.failedExpectations.length; i++) {
133 | var expectation = result.failedExpectations[i];
134 | messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message));
135 | messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack));
136 | }
137 |
138 | failures.push(failure);
139 | }
140 |
141 | if (result.status == 'pending') {
142 | pendingSpecCount++;
143 | }
144 | };
145 |
146 | this.jasmineDone = function() {
147 | var banner = find('.banner');
148 | banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
149 |
150 | var alert = find('.alert');
151 |
152 | alert.appendChild(createDom('span', { className: 'exceptions' },
153 | createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'),
154 | createDom('input', {
155 | className: 'raise',
156 | id: 'raise-exceptions',
157 | type: 'checkbox'
158 | })
159 | ));
160 | var checkbox = find('#raise-exceptions');
161 |
162 | checkbox.checked = !env.catchingExceptions();
163 | checkbox.onclick = onRaiseExceptionsClick;
164 |
165 | if (specsExecuted < totalSpecsDefined) {
166 | var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
167 | alert.appendChild(
168 | createDom('span', {className: 'bar skipped'},
169 | createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage)
170 | )
171 | );
172 | }
173 | var statusBarMessage = '';
174 | var statusBarClassName = 'bar ';
175 |
176 | if (totalSpecsDefined > 0) {
177 | statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
178 | if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
179 | statusBarClassName += (failureCount > 0) ? 'failed' : 'passed';
180 | } else {
181 | statusBarClassName += 'skipped';
182 | statusBarMessage += 'No specs found';
183 | }
184 |
185 | alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
186 |
187 | for(i = 0; i < failedSuites.length; i++) {
188 | var failedSuite = failedSuites[i];
189 | for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
190 | var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message;
191 | var errorBarClassName = 'bar errored';
192 | alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
193 | }
194 | }
195 |
196 | var results = find('.results');
197 | results.appendChild(summary);
198 |
199 | summaryList(topResults, summary);
200 |
201 | function summaryList(resultsTree, domParent) {
202 | var specListNode;
203 | for (var i = 0; i < resultsTree.children.length; i++) {
204 | var resultNode = resultsTree.children[i];
205 | if (resultNode.type == 'suite') {
206 | var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id},
207 | createDom('li', {className: 'suite-detail'},
208 | createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
209 | )
210 | );
211 |
212 | summaryList(resultNode, suiteListNode);
213 | domParent.appendChild(suiteListNode);
214 | }
215 | if (resultNode.type == 'spec') {
216 | if (domParent.getAttribute('class') != 'specs') {
217 | specListNode = createDom('ul', {className: 'specs'});
218 | domParent.appendChild(specListNode);
219 | }
220 | var specDescription = resultNode.result.description;
221 | if(noExpectations(resultNode.result)) {
222 | specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
223 | }
224 | if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
225 | specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
226 | }
227 | specListNode.appendChild(
228 | createDom('li', {
229 | className: resultNode.result.status,
230 | id: 'spec-' + resultNode.result.id
231 | },
232 | createDom('a', {href: specHref(resultNode.result)}, specDescription)
233 | )
234 | );
235 | }
236 | }
237 | }
238 |
239 | if (failures.length) {
240 | alert.appendChild(
241 | createDom('span', {className: 'menu bar spec-list'},
242 | createDom('span', {}, 'Spec List | '),
243 | createDom('a', {className: 'failures-menu', href: '#'}, 'Failures')));
244 | alert.appendChild(
245 | createDom('span', {className: 'menu bar failure-list'},
246 | createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'),
247 | createDom('span', {}, ' | Failures ')));
248 |
249 | find('.failures-menu').onclick = function() {
250 | setMenuModeTo('failure-list');
251 | };
252 | find('.spec-list-menu').onclick = function() {
253 | setMenuModeTo('spec-list');
254 | };
255 |
256 | setMenuModeTo('failure-list');
257 |
258 | var failureNode = find('.failures');
259 | for (var i = 0; i < failures.length; i++) {
260 | failureNode.appendChild(failures[i]);
261 | }
262 | }
263 | };
264 |
265 | return this;
266 |
267 | function find(selector) {
268 | return getContainer().querySelector('.jasmine_html-reporter ' + selector);
269 | }
270 |
271 | function clearPrior() {
272 | // return the reporter
273 | var oldReporter = find('');
274 |
275 | if(oldReporter) {
276 | getContainer().removeChild(oldReporter);
277 | }
278 | }
279 |
280 | function createDom(type, attrs, childrenVarArgs) {
281 | var el = createElement(type);
282 |
283 | for (var i = 2; i < arguments.length; i++) {
284 | var child = arguments[i];
285 |
286 | if (typeof child === 'string') {
287 | el.appendChild(createTextNode(child));
288 | } else {
289 | if (child) {
290 | el.appendChild(child);
291 | }
292 | }
293 | }
294 |
295 | for (var attr in attrs) {
296 | if (attr == 'className') {
297 | el[attr] = attrs[attr];
298 | } else {
299 | el.setAttribute(attr, attrs[attr]);
300 | }
301 | }
302 |
303 | return el;
304 | }
305 |
306 | function pluralize(singular, count) {
307 | var word = (count == 1 ? singular : singular + 's');
308 |
309 | return '' + count + ' ' + word;
310 | }
311 |
312 | function specHref(result) {
313 | return addToExistingQueryString('spec', result.fullName);
314 | }
315 |
316 | function defaultQueryString(key, value) {
317 | return '?' + key + '=' + value;
318 | }
319 |
320 | function setMenuModeTo(mode) {
321 | htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode);
322 | }
323 |
324 | function noExpectations(result) {
325 | return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
326 | result.status === 'passed';
327 | }
328 | }
329 |
330 | return HtmlReporter;
331 | };
332 |
333 | jasmineRequire.HtmlSpecFilter = function() {
334 | function HtmlSpecFilter(options) {
335 | var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
336 | var filterPattern = new RegExp(filterString);
337 |
338 | this.matches = function(specName) {
339 | return filterPattern.test(specName);
340 | };
341 | }
342 |
343 | return HtmlSpecFilter;
344 | };
345 |
346 | jasmineRequire.ResultsNode = function() {
347 | function ResultsNode(result, type, parent) {
348 | this.result = result;
349 | this.type = type;
350 | this.parent = parent;
351 |
352 | this.children = [];
353 |
354 | this.addChild = function(result, type) {
355 | this.children.push(new ResultsNode(result, type, this));
356 | };
357 |
358 | this.last = function() {
359 | return this.children[this.children.length - 1];
360 | };
361 | }
362 |
363 | return ResultsNode;
364 | };
365 |
366 | jasmineRequire.QueryString = function() {
367 | function QueryString(options) {
368 |
369 | this.navigateWithNewParam = function(key, value) {
370 | options.getWindowLocation().search = this.fullStringWithNewParam(key, value);
371 | };
372 |
373 | this.fullStringWithNewParam = function(key, value) {
374 | var paramMap = queryStringToParamMap();
375 | paramMap[key] = value;
376 | return toQueryString(paramMap);
377 | };
378 |
379 | this.getParam = function(key) {
380 | return queryStringToParamMap()[key];
381 | };
382 |
383 | return this;
384 |
385 | function toQueryString(paramMap) {
386 | var qStrPairs = [];
387 | for (var prop in paramMap) {
388 | qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
389 | }
390 | return '?' + qStrPairs.join('&');
391 | }
392 |
393 | function queryStringToParamMap() {
394 | var paramStr = options.getWindowLocation().search.substring(1),
395 | params = [],
396 | paramMap = {};
397 |
398 | if (paramStr.length > 0) {
399 | params = paramStr.split('&');
400 | for (var i = 0; i < params.length; i++) {
401 | var p = params[i].split('=');
402 | var value = decodeURIComponent(p[1]);
403 | if (value === 'true' || value === 'false') {
404 | value = JSON.parse(value);
405 | }
406 | paramMap[decodeURIComponent(p[0])] = value;
407 | }
408 | }
409 |
410 | return paramMap;
411 | }
412 |
413 | }
414 |
415 | return QueryString;
416 | };
417 |
--------------------------------------------------------------------------------
/examples/testing/jasmine-2.2.0/jasmine.css:
--------------------------------------------------------------------------------
1 | body { overflow-y: scroll; }
2 |
3 | .jasmine_html-reporter { background-color: #eee; padding: 5px; margin: -8px; font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333; }
4 | .jasmine_html-reporter a { text-decoration: none; }
5 | .jasmine_html-reporter a:hover { text-decoration: underline; }
6 | .jasmine_html-reporter p, .jasmine_html-reporter h1, .jasmine_html-reporter h2, .jasmine_html-reporter h3, .jasmine_html-reporter h4, .jasmine_html-reporter h5, .jasmine_html-reporter h6 { margin: 0; line-height: 14px; }
7 | .jasmine_html-reporter .banner, .jasmine_html-reporter .symbol-summary, .jasmine_html-reporter .summary, .jasmine_html-reporter .result-message, .jasmine_html-reporter .spec .description, .jasmine_html-reporter .spec-detail .description, .jasmine_html-reporter .alert .bar, .jasmine_html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }
8 | .jasmine_html-reporter .banner { position: relative; }
9 | .jasmine_html-reporter .banner .title { background: url('data:image/png;base64,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') no-repeat; background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iNjgxLjk2MjUyIgogICBoZWlnaHQ9IjE4Ny41IgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhOCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczYiPjxjbGlwUGF0aAogICAgICAgaWQ9ImNsaXBQYXRoMTgiPjxwYXRoCiAgICAgICAgIGQ9Ik0gMCwxNTAwIDAsMCBsIDU0NTUuNzQsMCAwLDE1MDAgTCAwLDE1MDAgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIgLz48L2NsaXBQYXRoPjwvZGVmcz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUsMCwwLC0xLjI1LDAsMTg3LjUpIgogICAgIGlkPSJnMTAiPjxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuMSwwLjEpIgogICAgICAgaWQ9ImcxMiI+PGcKICAgICAgICAgaWQ9ImcxNCI+PGcKICAgICAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgxOCkiCiAgICAgICAgICAgaWQ9ImcxNiI+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTU0NCw1OTkuNDM0IGMgMC45MiwtNDAuMzUyIDI1LjY4LC04MS42MDIgNzEuNTMsLTgxLjYwMiAyNy41MSwwIDQ3LjY4LDEyLjgzMiA2MS40NCwzNS43NTQgMTIuODMsMjIuOTMgMTIuODMsNTYuODUyIDEyLjgzLDgyLjUyNyBsIDAsMzI5LjE4NCAtNzEuNTIsMCAwLDEwNC41NDMgMjY2LjgzLDAgMCwtMTA0LjU0MyAtNzAuNiwwIDAsLTM0NC43NyBjIDAsLTU4LjY5MSAtMy42OCwtMTA0LjUzMSAtNDQuOTMsLTE1Mi4yMTggLTM2LjY4LC00Mi4xOCAtOTYuMjgsLTY2LjAyIC0xNTMuMTQsLTY2LjAyIC0xMTcuMzcsMCAtMjA3LjI0LDc3Ljk0MSAtMjAyLjY0LDE5Ny4xNDUgbCAxMzAuMiwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDIzMDEuNCw2NjIuNjk1IGMgMCw4MC43MDMgLTY2Ljk0LDE0NS44MTMgLTE0Ny42MywxNDUuODEzIC04My40NCwwIC0xNDcuNjMsLTY4Ljc4MSAtMTQ3LjYzLC0xNTEuMzAxIDAsLTc5Ljc4NSA2Ni45NCwtMTQ1LjgwMSAxNDUuOCwtMTQ1LjgwMSA4NC4zNSwwIDE0OS40Niw2Ny44NTIgMTQ5LjQ2LDE1MS4yODkgeiBtIC0xLjgzLC0xODEuNTQ3IGMgLTM1Ljc3LC01NC4wOTcgLTkzLjUzLC03OC44NTkgLTE1Ny43MiwtNzguODU5IC0xNDAuMywwIC0yNTEuMjQsMTE2LjQ0OSAtMjUxLjI0LDI1NC45MTggMCwxNDIuMTI5IDExMy43LDI2MC40MSAyNTYuNzQsMjYwLjQxIDYzLjI3LDAgMTE4LjI5LC0yOS4zMzYgMTUyLjIyLC04Mi41MjMgbCAwLDY5LjY4NyAxNzUuMTQsMCAwLC0xMDQuNTI3IC02MS40NCwwIDAsLTI4MC41OTggNjEuNDQsMCAwLC0xMDQuNTI3IC0xNzUuMTQsMCAwLDY2LjAxOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAyNjIyLjMzLDU1Ny4yNTggYyAzLjY3LC00NC4wMTYgMzMuMDEsLTczLjM0OCA3OC44NiwtNzMuMzQ4IDMzLjkzLDAgNjYuOTMsMjMuODI0IDY2LjkzLDYwLjUwNCAwLDQ4LjYwNiAtNDUuODQsNTYuODU2IC04My40NCw2Ni45NDEgLTg1LjI4LDIyLjAwNCAtMTc4LjgxLDQ4LjYwNiAtMTc4LjgxLDE1NS44NzkgMCw5My41MzYgNzguODYsMTQ3LjYzMyAxNjUuOTgsMTQ3LjYzMyA0NCwwIDgzLjQzLC05LjE3NiAxMTAuOTQsLTQ0LjAwOCBsIDAsMzMuOTIyIDgyLjUzLDAgMCwtMTMyLjk2NSAtMTA4LjIxLDAgYyAtMS44MywzNC44NTYgLTI4LjQyLDU3Ljc3NCAtNjMuMjYsNTcuNzc0IC0zMC4yNiwwIC02Mi4zNSwtMTcuNDIyIC02Mi4zNSwtNTEuMzQ4IDAsLTQ1Ljg0NyA0NC45MywtNTUuOTMgODAuNjksLTY0LjE4IDg4LjAyLC0yMC4xNzUgMTgyLjQ3LC00Ny42OTUgMTgyLjQ3LC0xNTcuNzM0IDAsLTk5LjAyNyAtODMuNDQsLTE1NC4wMzkgLTE3NS4xMywtMTU0LjAzOSAtNDkuNTMsMCAtOTQuNDYsMTUuNTgyIC0xMjYuNTUsNTMuMTggbCAwLC00MC4zNCAtODUuMjcsMCAwLDE0Mi4xMjkgMTE0LjYyLDAiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGgyNiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMjk4OC4xOCw4MDAuMjU0IC02My4yNiwwIDAsMTA0LjUyNyAxNjUuMDUsMCAwLC03My4zNTUgYyAzMS4xOCw1MS4zNDcgNzguODYsODUuMjc3IDE0MS4yMSw4NS4yNzcgNjcuODUsMCAxMjQuNzEsLTQxLjI1OCAxNTIuMjEsLTEwMi42OTkgMjYuNiw2Mi4zNTEgOTIuNjIsMTAyLjY5OSAxNjAuNDcsMTAyLjY5OSA1My4xOSwwIDEwNS40NiwtMjIgMTQxLjIxLC02Mi4zNTEgMzguNTIsLTQ0LjkzOCAzOC41MiwtOTMuNTMyIDM4LjUyLC0xNDkuNDU3IGwgMCwtMTg1LjIzOSA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40MiwwIDAsMTA0LjUyNyA2My4yOCwwIDAsMTU3LjcxNSBjIDAsMzIuMTAyIDAsNjAuNTI3IC0xNC42Nyw4OC45NTcgLTE4LjM0LDI2LjU4MiAtNDguNjEsNDAuMzQ0IC03OS43Nyw0MC4zNDQgLTMwLjI2LDAgLTYzLjI4LC0xMi44NDQgLTgyLjUzLC0zNi42NzIgLTIyLjkzLC0yOS4zNTUgLTIyLjkzLC01Ni44NjMgLTIyLjkzLC05Mi42MjkgbCAwLC0xNTcuNzE1IDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM4LjQxLDAgMCwxMDQuNTI3IDYzLjI4LDAgMCwxNTAuMzgzIGMgMCwyOS4zNDggMCw2Ni4wMjMgLTE0LjY3LDkxLjY5OSAtMTUuNTksMjkuMzM2IC00Ny42OSw0NC45MzQgLTgwLjcsNDQuOTM0IC0zMS4xOCwwIC01Ny43NywtMTEuMDA4IC03Ny45NCwtMzUuNzc0IC0yNC43NywtMzAuMjUzIC0yNi42LC02Mi4zNDMgLTI2LjYsLTk5Ljk0MSBsIDAsLTE1MS4zMDEgNjMuMjcsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNiwwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAzOTk4LjY2LDk1MS41NDcgLTExMS44NywwIDAsMTE4LjI5MyAxMTEuODcsMCAwLC0xMTguMjkzIHogbSAwLC00MzEuODkxIDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM5LjMzLDAgMCwxMDQuNTI3IDY0LjE5LDAgMCwyODAuNTk4IC02My4yNywwIDAsMTA0LjUyNyAxNzUuMTQsMCAwLC0zODUuMTI1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzAiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDQxNTkuMTIsODAwLjI1NCAtNjMuMjcsMCAwLDEwNC41MjcgMTc1LjE0LDAgMCwtNjkuNjg3IGMgMjkuMzUsNTQuMTAxIDg0LjM2LDgwLjY5OSAxNDQuODcsODAuNjk5IDUzLjE5LDAgMTA1LjQ1LC0yMi4wMTYgMTQxLjIyLC02MC41MjcgNDAuMzQsLTQ0LjkzNCA0MS4yNiwtODguMDMyIDQxLjI2LC0xNDMuOTU3IGwgMCwtMTkxLjY1MyA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40LDAgMCwxMDQuNTI3IDYzLjI2LDAgMCwxNTguNjM3IGMgMCwzMC4yNjIgMCw2MS40MzQgLTE5LjI2LDg4LjAzNSAtMjAuMTcsMjYuNTgyIC01My4xOCwzOS40MTQgLTg2LjE5LDM5LjQxNCAtMzMuOTMsMCAtNjguNzcsLTEzLjc1IC04OC45NCwtNDEuMjUgLTIxLjA5LC0yNy41IC0yMS4wOSwtNjkuNjg3IC0yMS4wOSwtMTAyLjcwNyBsIDAsLTE0Mi4xMjkgNjMuMjYsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNywwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDMyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA1MDgyLjQ4LDcwMy45NjUgYyAtMTkuMjQsNzAuNjA1IC04MS42LDExNS41NDcgLTE1NC4wNCwxMTUuNTQ3IC02Ni4wNCwwIC0xMjkuMywtNTEuMzQ4IC0xNDMuMDUsLTExNS41NDcgbCAyOTcuMDksMCB6IG0gODUuMjcsLTE0NC44ODMgYyAtMzguNTEsLTkzLjUyMyAtMTI5LjI3LC0xNTYuNzkzIC0yMzEuMDUsLTE1Ni43OTMgLTE0My4wNywwIC0yNTcuNjgsMTExLjg3MSAtMjU3LjY4LDI1NS44MzYgMCwxNDQuODgzIDEwOS4xMiwyNjEuMzI4IDI1NC45MSwyNjEuMzI4IDY3Ljg3LDAgMTM1LjcyLC0zMC4yNTggMTgzLjM5LC03OC44NjMgNDguNjIsLTUxLjM0NCA2OC43OSwtMTEzLjY5NSA2OC43OSwtMTgzLjM4MyBsIC0zLjY3LC0zOS40MzQgLTM5Ni4xMywwIGMgMTQuNjcsLTY3Ljg2MyA3Ny4wMywtMTE3LjM2MyAxNDYuNzIsLTExNy4zNjMgNDguNTksMCA5MC43NiwxOC4zMjggMTE4LjI4LDU4LjY3MiBsIDExNi40NCwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDY5MC44OTUsODUwLjcwMyA5MC43NSwwIDIyLjU0MywzMS4wMzUgMCwyNDMuMTIyIC0xMzUuODI5LDAgMCwtMjQzLjE0MSAyMi41MzYsLTMxLjAxNiIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA2MzIuMzk1LDc0Mi4yNTggMjguMDM5LDg2LjMwNCAtMjIuNTUxLDMxLjA0IC0yMzEuMjIzLDc1LjEyOCAtNDEuOTc2LC0xMjkuMTgzIDIzMS4yNTcsLTc1LjEzNyAzNi40NTQsMTEuODQ4IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzgiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDcxNy40NDksNjUzLjEwNSAtNzMuNDEsNTMuMzYgLTM2LjQ4OCwtMTEuODc1IC0xNDIuOTAzLC0xOTYuNjkyIDEwOS44ODMsLTc5LjgyOCAxNDIuOTE4LDE5Ni43MDMgMCwzOC4zMzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0MCIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gODI4LjUyLDcwNi40NjUgLTczLjQyNiwtNTMuMzQgMC4wMTEsLTM4LjM1OSBMIDg5OC4wMDQsNDE4LjA3IDEwMDcuOSw0OTcuODk4IDg2NC45NzMsNjk0LjYwOSA4MjguNTIsNzA2LjQ2NSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA4MTIuMDg2LDgyOC41ODYgMjguMDU1LC04Ni4zMiAzNi40ODQsLTExLjgzNiAyMzEuMjI1LDc1LjExNyAtNDEuOTcsMTI5LjE4MyAtMjMxLjIzOSwtNzUuMTQgLTIyLjU1NSwtMzEuMDA0IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNDQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDczNi4zMDEsMTMzNS44OCBjIC0zMjMuMDQ3LDAgLTU4NS44NzUsLTI2Mi43OCAtNTg1Ljg3NSwtNTg1Ljc4MiAwLC0zMjMuMTE4IDI2Mi44MjgsLTU4NS45NzcgNTg1Ljg3NSwtNTg1Ljk3NyAzMjMuMDE5LDAgNTg1LjgwOSwyNjIuODU5IDU4NS44MDksNTg1Ljk3NyAwLDMyMy4wMDIgLTI2Mi43OSw1ODUuNzgyIC01ODUuODA5LDU4NS43ODIgbCAwLDAgeiBtIDAsLTExOC42MSBjIDI1Ny45NzIsMCA0NjcuMTg5LC0yMDkuMTMgNDY3LjE4OSwtNDY3LjE3MiAwLC0yNTguMTI5IC0yMDkuMjE3LC00NjcuMzQ4IC00NjcuMTg5LC00NjcuMzQ4IC0yNTguMDc0LDAgLTQ2Ny4yNTQsMjA5LjIxOSAtNDY3LjI1NCw0NjcuMzQ4IDAsMjU4LjA0MiAyMDkuMTgsNDY3LjE3MiA0NjcuMjU0LDQ2Ny4xNzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0NiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTA5MS4xMyw2MTkuODgzIC0xNzUuNzcxLDU3LjEyMSAxMS42MjksMzUuODA4IDE3NS43NjIsLTU3LjEyMSAtMTEuNjIsLTM1LjgwOCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQ4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA4NjYuOTU3LDkwMi4wNzQgODM2LjUsOTI0LjE5OSA5NDUuMTIxLDEwNzMuNzMgOTc1LjU4NiwxMDUxLjYxIDg2Ni45NTcsOTAyLjA3NCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDUwIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA2MDcuNDY1LDkwMy40NDUgNDk4Ljg1NSwxMDUyLjk3IDUyOS4zMiwxMDc1LjEgNjM3LjkzLDkyNS41NjYgNjA3LjQ2NSw5MDMuNDQ1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDM4MC42ODgsNjIyLjEyOSAtMTEuNjI2LDM1LjgwMSAxNzUuNzU4LDU3LjA5IDExLjYyMSwtMzUuODAxIC0xNzUuNzUzLC01Ny4wOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDU0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA3MTYuMjg5LDM3Ni41OSAzNy42NDA2LDAgMCwxODQuODE2IC0zNy42NDA2LDAgMCwtMTg0LjgxNiB6IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTYiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=') no-repeat, none; -moz-background-size: 100%; -o-background-size: 100%; -webkit-background-size: 100%; background-size: 100%; display: block; float: left; width: 90px; height: 25px; }
10 | .jasmine_html-reporter .banner .version { margin-left: 14px; position: relative; top: 6px; }
11 | .jasmine_html-reporter .banner .duration { position: absolute; right: 14px; top: 6px; }
12 | .jasmine_html-reporter #jasmine_content { position: fixed; right: 100%; }
13 | .jasmine_html-reporter .version { color: #aaa; }
14 | .jasmine_html-reporter .banner { margin-top: 14px; }
15 | .jasmine_html-reporter .duration { color: #aaa; float: right; }
16 | .jasmine_html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
17 | .jasmine_html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; }
18 | .jasmine_html-reporter .symbol-summary li.passed { font-size: 14px; }
19 | .jasmine_html-reporter .symbol-summary li.passed:before { color: #007069; content: "\02022"; }
20 | .jasmine_html-reporter .symbol-summary li.failed { line-height: 9px; }
21 | .jasmine_html-reporter .symbol-summary li.failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; }
22 | .jasmine_html-reporter .symbol-summary li.disabled { font-size: 14px; }
23 | .jasmine_html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; }
24 | .jasmine_html-reporter .symbol-summary li.pending { line-height: 17px; }
25 | .jasmine_html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; }
26 | .jasmine_html-reporter .symbol-summary li.empty { font-size: 14px; }
27 | .jasmine_html-reporter .symbol-summary li.empty:before { color: #ba9d37; content: "\02022"; }
28 | .jasmine_html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
29 | .jasmine_html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
30 | .jasmine_html-reporter .bar.failed { background-color: #ca3a11; }
31 | .jasmine_html-reporter .bar.passed { background-color: #007069; }
32 | .jasmine_html-reporter .bar.skipped { background-color: #bababa; }
33 | .jasmine_html-reporter .bar.errored { background-color: #ca3a11; }
34 | .jasmine_html-reporter .bar.menu { background-color: #fff; color: #aaa; }
35 | .jasmine_html-reporter .bar.menu a { color: #333; }
36 | .jasmine_html-reporter .bar a { color: white; }
37 | .jasmine_html-reporter.spec-list .bar.menu.failure-list, .jasmine_html-reporter.spec-list .results .failures { display: none; }
38 | .jasmine_html-reporter.failure-list .bar.menu.spec-list, .jasmine_html-reporter.failure-list .summary { display: none; }
39 | .jasmine_html-reporter .running-alert { background-color: #666; }
40 | .jasmine_html-reporter .results { margin-top: 14px; }
41 | .jasmine_html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
42 | .jasmine_html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
43 | .jasmine_html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
44 | .jasmine_html-reporter.showDetails .summary { display: none; }
45 | .jasmine_html-reporter.showDetails #details { display: block; }
46 | .jasmine_html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
47 | .jasmine_html-reporter .summary { margin-top: 14px; }
48 | .jasmine_html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
49 | .jasmine_html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }
50 | .jasmine_html-reporter .summary li.passed a { color: #007069; }
51 | .jasmine_html-reporter .summary li.failed a { color: #ca3a11; }
52 | .jasmine_html-reporter .summary li.empty a { color: #ba9d37; }
53 | .jasmine_html-reporter .summary li.pending a { color: #ba9d37; }
54 | .jasmine_html-reporter .description + .suite { margin-top: 0; }
55 | .jasmine_html-reporter .suite { margin-top: 14px; }
56 | .jasmine_html-reporter .suite a { color: #333; }
57 | .jasmine_html-reporter .failures .spec-detail { margin-bottom: 28px; }
58 | .jasmine_html-reporter .failures .spec-detail .description { background-color: #ca3a11; }
59 | .jasmine_html-reporter .failures .spec-detail .description a { color: white; }
60 | .jasmine_html-reporter .result-message { padding-top: 14px; color: #333; white-space: pre; }
61 | .jasmine_html-reporter .result-message span.result { display: block; }
62 | .jasmine_html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666; border: 1px solid #ddd; background: white; white-space: pre; }
63 |
--------------------------------------------------------------------------------
/examples/testing/jasmine-2.2.0/jasmine_favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gedbac/di4js/a1071cef2f0250fed05e50e1a29ac40f779c7321/examples/testing/jasmine-2.2.0/jasmine_favicon.png
--------------------------------------------------------------------------------
/examples/testing/script.js:
--------------------------------------------------------------------------------
1 | function Car(engine) {
2 | this.engine = engine;
3 | }
4 |
5 | Car.prototype.start = function () {
6 | if (this.engine) {
7 | this.engine.start();
8 | }
9 | console.log("Car has been started...");
10 | }
11 |
12 | describe("car", function() {
13 |
14 | it("should start a car", function() {
15 |
16 | var engineMock = jasmine.createSpyObj('engine', ['start']);
17 |
18 | var car = new Car(engineMock);
19 | car.start();
20 |
21 | expect(engineMock.start).toHaveBeenCalled();
22 |
23 | });
24 |
25 | });
--------------------------------------------------------------------------------
/gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt) {
4 |
5 | var os = require('os');
6 | var path = require('path');
7 |
8 | var src = [
9 | './src/DependencyResolverException.js',
10 | './src/InstanceFactoryOptions.js',
11 | './src/IInstanceFactory.js',
12 | './src/InstanceFactory.js',
13 | './src/INameTransformer.js',
14 | './src/NameTransformer.js',
15 | './src/IDependencyResolver.js',
16 | './src/DependencyResolver.js',
17 | './src/DefaultDependencyResolver.js'
18 | ];
19 |
20 | grunt.initConfig({
21 | pkg: grunt.file.readJSON('package.json'),
22 | clean: {
23 | 'browser-lib': {
24 | src: [
25 | './<%= pkg.name %>.js',
26 | './<%= pkg.name %>.min.js'
27 | ]
28 | },
29 | 'node-lib': {
30 | src: [
31 | './lib/<%= pkg.name %>.js'
32 | ]
33 | }
34 | },
35 | concat: {
36 | 'browser-lib': {
37 | options: {
38 | separator: os.EOL + os.EOL,
39 | banner:
40 | "(function (exports) {" + os.EOL + os.EOL +
41 | " 'use strict';" + os.EOL + os.EOL +
42 | " exports = exports || {};" + os.EOL + os.EOL +
43 | " if (typeof define === 'function' && define.amd) {" + os.EOL +
44 | " define(function(){ return exports; });" + os.EOL +
45 | " } else {" + os.EOL +
46 | " window.di = exports; " + os.EOL +
47 | " }" + os.EOL + os.EOL +
48 | " if (!('version' in exports)) {" + os.EOL +
49 | " exports.version = '<%= pkg.version %>';" + os.EOL +
50 | " }" + os.EOL + os.EOL,
51 | footer:
52 | os.EOL + os.EOL +
53 | "} (window.di));",
54 | process: function (src, filepath) {
55 | var lines = src.split(os.EOL);
56 | for (var i = 0; i < lines.length; i++) {
57 | lines[i] = ' ' + lines[i];
58 | }
59 | return lines.join(os.EOL);
60 | }
61 | },
62 | src: src,
63 | dest: './<%= pkg.name %>.js',
64 | nonull: true
65 | },
66 | 'node-lib': {
67 | options: {
68 | separator: os.EOL + os.EOL,
69 | banner:
70 | "'use strict';" + os.EOL + os.EOL +
71 | "var exports = {};" + os.EOL + os.EOL +
72 | "exports.version = '<%= pkg.version %>';" + os.EOL + os.EOL,
73 | footer:
74 | os.EOL + os.EOL +
75 | "module.exports = exports;"
76 | },
77 | src: src,
78 | dest: './lib/<%= pkg.name %>.js',
79 | nonull: true
80 | }
81 | },
82 | jshint: {
83 | options: {
84 | indent: 2,
85 | curly: true,
86 | maxlen: 120,
87 | trailing: true,
88 | smarttabs: false,
89 | white: true
90 | },
91 | 'spec': {
92 | options: {
93 | strict: false,
94 | globalstrict: true,
95 | globals: {
96 | console: true,
97 | jasmine: true,
98 | describe: true,
99 | expect: true,
100 | it: true,
101 | beforeEach: true,
102 | afterEach: true,
103 | di: true,
104 | require: true
105 | },
106 | '-W087': false,
107 | '-W065': false
108 | },
109 | files: {
110 | src: [
111 | './spec/**/*.spec.js'
112 | ]
113 | }
114 | },
115 | 'src': {
116 | options: {
117 | browser: true,
118 | strict: false
119 | },
120 | files: {
121 | src: src
122 | }
123 | },
124 | 'browser-lib': {
125 | options: {
126 | browser: true,
127 | strict: true
128 | },
129 | files: {
130 | src: [ './<%= pkg.name %>.js' ]
131 | }
132 | },
133 | 'node-lib': {
134 | options: {
135 | node: true,
136 | strict: true
137 | },
138 | files: {
139 | src: [ './<%= pkg.name %>.js' ]
140 | }
141 | }
142 | },
143 | uglify: {
144 | options: {
145 | mangle: false,
146 | compress: false,
147 | sourceMap: true,
148 | sourceMapName: './<%= pkg.name %>.map'
149 | },
150 | 'browser-min-lib': {
151 | files: {
152 | './<%= pkg.name %>.min.js': [ './<%= pkg.name %>.js' ]
153 | }
154 | }
155 | },
156 | jasmine: {
157 | 'spec': {
158 | src: './<%= pkg.name %>.js',
159 | version: '2.0.1',
160 | options: {
161 | specs: './spec/**/*.spec.js',
162 | outfile: './spec-runner.html',
163 | keepRunner: true
164 | }
165 | },
166 | 'min-spec': {
167 | src: './<%= pkg.name %>.min.js',
168 | version: '2.0.1',
169 | options: {
170 | specs: './spec/**/*.spec.js',
171 | outfile: './spec-runner.html',
172 | keepRunner: true
173 | }
174 | }
175 | },
176 | jasmine_node: {
177 | spec: ['spec/']
178 | },
179 | watch: {
180 | options: {
181 | livereload: false,
182 | interrupt: true,
183 | dateFormat: function (time) {
184 | grunt.log.writeln('Completed in ' + time + 'ms ');
185 | grunt.log.writeln('Waiting...');
186 | },
187 | spawn: false
188 | },
189 | 'browser-src': {
190 | files: './src/**/*.js',
191 | tasks: [ 'jshint:src', 'clean:browser-lib', 'concat:browser-lib', 'jasmine:spec', 'clean:node-lib',
192 | 'concat:node-lib', 'jasmine_node:spec' ]
193 | },
194 | 'browser-spec': {
195 | files: './spec/**/*.spec.js',
196 | tasks: [ 'jshint:spec', 'jasmine:spec', 'jasmine_node:spec' ]
197 | }
198 | },
199 | karma: {
200 | options: {
201 | port: 9876,
202 | reporters: ['dots', 'html'],
203 | files: [
204 | './di4js.js',
205 | './spec/**/*.js'
206 | ],
207 | frameworks: [ 'jasmine' ],
208 | browsers: [ 'Chrome', 'Firefox', 'IE', 'Safari' ]
209 | },
210 | 'watch': {
211 | autoWatch: true,
212 | singleRun: false
213 | },
214 | 'single': {
215 | autoWatch: false,
216 | singleRun: true
217 | }
218 | }
219 | });
220 |
221 | grunt.event.on('watch', function (action, filepath, target) {
222 | if (target === 'src') {
223 | grunt.config('jshint.src.src', filepath);
224 | } else if (target === 'spec') {
225 | grunt.config('jshint.spec.src', filepath);
226 | }
227 | });
228 |
229 | grunt.loadNpmTasks('grunt-contrib-jshint');
230 | grunt.loadNpmTasks('grunt-contrib-clean');
231 | grunt.loadNpmTasks('grunt-contrib-concat');
232 | grunt.loadNpmTasks('grunt-contrib-watch');
233 | //grunt.loadNpmTasks('grunt-contrib-jasmine');
234 | //grunt.loadNpmTasks('grunt-jasmine-node');
235 | grunt.loadNpmTasks('grunt-contrib-uglify');
236 | //grunt.loadNpmTasks('grunt-karma');
237 |
238 | grunt.registerTask('default', [
239 | 'jshint:src',
240 | 'jshint:spec',
241 | 'clean:browser-lib',
242 | 'concat:browser-lib',
243 | 'jshint:browser-lib',
244 | /*'jasmine:spec',*/
245 | 'clean:node-lib',
246 | 'concat:node-lib',
247 | 'jshint:node-lib',
248 | /*'jasmine_node:spec',*/
249 | 'uglify:browser-min-lib',
250 | /*'jasmine:min-spec'*/
251 | ]);
252 |
253 | };
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Gediminas Backevicius
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "di4js",
3 | "description": "The di4js module is dependency injection implementation in JavaScript. Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them.",
4 | "version": "1.1.5",
5 | "author": "Gediminas Backevicius ",
6 | "bugs": {
7 | "url": "https://github.com/gedbac/di4js/issues"
8 | },
9 | "scripts": {
10 | "test": "grunt"
11 | },
12 | "keywords": [
13 | "di",
14 | "dependency",
15 | "injection",
16 | "IoC",
17 | "javascript"
18 | ],
19 | "repository": {
20 | "type": "git",
21 | "url": "https://github.com/gedbac/di4js.git"
22 | },
23 | "main": "./lib/di4js.js",
24 | "engines": {
25 | "node": ">=0.8"
26 | },
27 | "devDependencies": {
28 | "grunt": "~0.4.5",
29 | "grunt-contrib-jshint": "~0.11.0",
30 | "grunt-contrib-clean": "~0.6.0",
31 | "grunt-contrib-concat": "~0.5.0",
32 | "grunt-contrib-watch": "~0.6.1",
33 | "grunt-contrib-jasmine": "~0.8.2",
34 | "grunt-jasmine-node": "~0.2.1",
35 | "grunt-contrib-uglify": "~0.8.0",
36 | "grunt-karma": "~0.10.1",
37 | "jasmine-core": "~2.2.0",
38 | "karma": "0.12.31",
39 | "karma-chrome-launcher": "~0.1.7",
40 | "karma-firefox-launcher": "~0.1.4",
41 | "karma-ie-launcher": "~0.1.5",
42 | "karma-safari-launcher": "~0.1.1",
43 | "karma-jasmine": "~0.3.5",
44 | "karma-jasmine-html-reporter": "~0.1.6"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/spec-runner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Jasmine Spec Runner
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 |
--------------------------------------------------------------------------------
/src/DefaultDependencyResolver.js:
--------------------------------------------------------------------------------
1 | var defaultDependencyResolver = null,
2 | debug = false;
3 |
4 | Object.defineProperty(exports, 'getDefaultDependencyResolver', {
5 | value: function () {
6 | if (!defaultDependencyResolver) {
7 | defaultDependencyResolver = new DependencyResolver();
8 | }
9 | return defaultDependencyResolver;
10 | },
11 | enumerable: true
12 | });
13 |
14 | Object.defineProperty(exports, 'setDefaultDependencyResolver', {
15 | value: function (value) {
16 | defaultDependencyResolver = value;
17 | },
18 | enumerable: true
19 | });
20 |
21 | Object.defineProperty(exports, 'isAutowired', {
22 | get: function () {
23 | return exports
24 | .getDefaultDependencyResolver()
25 | .isAutowired;
26 | },
27 | enumerable: true
28 | });
29 |
30 | Object.defineProperty(exports, 'autowired', {
31 | value: function (value) {
32 | return exports
33 | .getDefaultDependencyResolver()
34 | .autowired(value);
35 | },
36 | enumerable: true
37 | });
38 |
39 | Object.defineProperty(exports, 'register', {
40 | value: function (name) {
41 | return exports
42 | .getDefaultDependencyResolver()
43 | .register(name);
44 | },
45 | enumerable: true
46 | });
47 |
48 | Object.defineProperty(exports, 'as', {
49 | value: function (type) {
50 | return exports
51 | .getDefaultDependencyResolver()
52 | .as(type);
53 | },
54 | enumerable: true
55 | });
56 |
57 | Object.defineProperty(exports, 'instance', {
58 | value: function (instance) {
59 | return exports
60 | .getDefaultDependencyResolver()
61 | .instance(instance);
62 | },
63 | enumerable: true
64 | });
65 |
66 | Object.defineProperty(exports, 'asSingleton', {
67 | value: function () {
68 | return exports
69 | .getDefaultDependencyResolver()
70 | .asSingleton();
71 | },
72 | enumerable: true
73 | });
74 |
75 | Object.defineProperty(exports, 'withConstructor', {
76 | value: function () {
77 | return exports
78 | .getDefaultDependencyResolver()
79 | .withConstructor();
80 | },
81 | enumerable: true
82 | });
83 |
84 | Object.defineProperty(exports, 'param', {
85 | value: function (name) {
86 | return exports
87 | .getDefaultDependencyResolver()
88 | .param(name);
89 | },
90 | enumerable: true
91 | });
92 |
93 | Object.defineProperty(exports, 'withProperties', {
94 | value: function () {
95 | return exports
96 | .getDefaultDependencyResolver()
97 | .withProperties();
98 | },
99 | enumerable: true
100 | });
101 |
102 | Object.defineProperty(exports, 'prop', {
103 | value: function (name) {
104 | return exports
105 | .getDefaultDependencyResolver()
106 | .prop(name);
107 | }
108 | });
109 |
110 | Object.defineProperty(exports, 'func', {
111 | value: function (name) {
112 | return exports
113 | .getDefaultDependencyResolver()
114 | .func(name);
115 | }
116 | });
117 |
118 | Object.defineProperty(exports, 'val', {
119 | value: function (instance) {
120 | return exports
121 | .getDefaultDependencyResolver()
122 | .val(instance);
123 | },
124 | enumerable: true
125 | });
126 |
127 | Object.defineProperty(exports, 'ref', {
128 | value: function (name) {
129 | return exports
130 | .getDefaultDependencyResolver()
131 | .ref(name);
132 | },
133 | enumerable: true
134 | });
135 |
136 | Object.defineProperty(exports, 'setFactory', {
137 | value: function (factory) {
138 | return exports
139 | .getDefaultDependencyResolver()
140 | .setFactory(factory);
141 | },
142 | enumerable: true
143 | });
144 |
145 | Object.defineProperty(exports, 'create', {
146 | value: function () {
147 | return exports
148 | .getDefaultDependencyResolver()
149 | .create();
150 | },
151 | enumerable: true
152 | });
153 |
154 | Object.defineProperty(exports, 'inject', {
155 | value: function (func, name) {
156 | return exports
157 | .getDefaultDependencyResolver()
158 | .inject(func, name);
159 | },
160 | enumerable: true
161 | });
162 |
163 | Object.defineProperty(exports, 'contains', {
164 | value: function (name) {
165 | return exports
166 | .getDefaultDependencyResolver()
167 | .contains(name);
168 | },
169 | enumerable: true
170 | });
171 |
172 | Object.defineProperty(exports, 'resolve', {
173 | value: function (name) {
174 | return exports
175 | .getDefaultDependencyResolver()
176 | .resolve(name);
177 | },
178 | enumerable: true
179 | });
180 |
181 | Object.defineProperty(exports, 'getDefaultFactory', {
182 | value: function () {
183 | return exports
184 | .getDefaultDependencyResolver()
185 | .getDefaultFactory();
186 | },
187 | enumerable: true
188 | });
189 |
190 | Object.defineProperty(exports, 'setDefaultFactory', {
191 | value: function (factory) {
192 | return exports
193 | .getDefaultDependencyResolver()
194 | .setDefaultFactory(factory);
195 | },
196 | enumerable: true
197 | });
198 |
199 | Object.defineProperty(exports, 'getNameTransformer', {
200 | value: function () {
201 | return exports
202 | .getDefaultDependencyResolver()
203 | .getNameTransformer();
204 | },
205 | enumerable: true
206 | });
207 |
208 | Object.defineProperty(exports, 'setNameTransformer', {
209 | value: function (transformer) {
210 | return exports
211 | .getDefaultDependencyResolver()
212 | .setNameTransformer(transformer);
213 | },
214 | enumerable: true
215 | });
216 |
217 | Object.defineProperty(exports, 'getRegistration', {
218 | value: function (name) {
219 | return exports
220 | .getDefaultDependencyResolver()
221 | .getRegistration(name);
222 | },
223 | enumerable: true
224 | });
225 |
226 | Object.defineProperty(exports, 'debug', {
227 | get: function () {
228 | return debug;
229 | },
230 | set: function (value) {
231 | debug = value;
232 | },
233 | enumerable: true
234 | });
235 |
236 | Object.defineProperty(exports, 'dispose', {
237 | value: function () {
238 | return exports
239 | .getDefaultDependencyResolver()
240 | .dispose();
241 | },
242 | enumerable: true
243 | });
--------------------------------------------------------------------------------
/src/DependencyResolver.js:
--------------------------------------------------------------------------------
1 | var DependencyResolver = function (parent) {
2 | this.__parent = parent;
3 | this.__defaultFactory = null;
4 | this.__nameTransformer = null;
5 | this.__autowired = false;
6 | this.__container = null;
7 | this.__registration = null;
8 | this.__withProperties = false;
9 | this.__withConstructor = false;
10 | this.__parameter = null;
11 | this.__property = null;
12 | this.__function = null;
13 | if (parent) {
14 | this.__autowired = parent.isAutowired;
15 | }
16 | Object.defineProperty(this, '__parent', { enumerable: false });
17 | Object.defineProperty(this, '__defaultFactory', { enumerable: false });
18 | Object.defineProperty(this, '__nameTransformer', { enumerable: false });
19 | Object.defineProperty(this, '__autowired', { enumerable: false });
20 | Object.defineProperty(this, '__container', { enumerable: false });
21 | Object.defineProperty(this, '__registration', { enumerable: false });
22 | Object.defineProperty(this, '__withProperties', { enumerable: false });
23 | Object.defineProperty(this, '__withConstructor', { enumerable: false });
24 | Object.defineProperty(this, '__parameter', { enumerable: false });
25 | Object.defineProperty(this, '__property', { enumerable: false });
26 | Object.defineProperty(this, '__function', { enumerable: false });
27 | Object.seal(this);
28 | };
29 |
30 | DependencyResolver.prototype = Object.create(Object.prototype, {
31 |
32 | isAutowired: {
33 | get: function () {
34 | return this.__autowired;
35 | },
36 | enumerable: true
37 | },
38 |
39 | autowired: {
40 | value: function (value) {
41 | if (value === undefined || value === null) {
42 | value = true;
43 | }
44 | if (typeof value !== 'boolean') {
45 | throw new DependencyResolverException("Parameter 'value' passed to the method 'autowired' has to " +
46 | "be a 'boolean'");
47 | }
48 | this.__autowired = value;
49 | return this;
50 | },
51 | enumerable: true
52 | },
53 |
54 | register: {
55 | value: function (name) {
56 | if (!name) {
57 | throw new DependencyResolverException("Parameter 'name' is not passed to the method 'register'");
58 | }
59 | if (typeof name !== 'string') {
60 | throw new DependencyResolverException("Parameter 'name' passed to the method 'register' has to be " +
61 | "a 'string'");
62 | }
63 | if (!this.__container) {
64 | this.__container = Object.create(null);
65 | }
66 | this.__registration = {
67 | name: name,
68 | singleton: false,
69 | type: null,
70 | instance: null,
71 | factory: null,
72 | dependencies: null
73 | };
74 | if (!(name in this.__container)) {
75 | this.__container[name] = this.__registration;
76 | } else {
77 | if (!(this.__container[name] instanceof Array)) {
78 | this.__container[name] = [ this.__container[name] ];
79 | }
80 | this.__container[name].push(this.__registration);
81 | }
82 | this.__withConstructor = false;
83 | this.__withProperties = false;
84 | this.__parameter = null;
85 | this.__property = null;
86 | return this;
87 | },
88 | enumerable: true
89 | },
90 |
91 | as: {
92 | value: function (type) {
93 | if (!this.__registration) {
94 | throw new DependencyResolverException("Registration's name is not defined");
95 | }
96 | if (!type) {
97 | throw new DependencyResolverException("Parameter 'type' is not passed to the method 'as' for " +
98 | "registration '" + this.__registration.name + "'");
99 | }
100 | if (typeof type !== 'function') {
101 | throw new DependencyResolverException("Parameter 'type' passed to the method 'as' has to be a 'function' " +
102 | "for registration '" + this.__registration.name + "'");
103 | }
104 | this.__registration.instance = null;
105 | this.__registration.type = type;
106 | this.__registration.singleton = false;
107 | this.__registration.dependencies = {
108 | parameters: [],
109 | properties: [],
110 | functions: []
111 | };
112 | this.__withConstructor = false;
113 | this.__withProperties = false;
114 | this.__parameter = null;
115 | this.__property = null;
116 | this.__function = null;
117 | return this;
118 | },
119 | enumerable: true
120 | },
121 |
122 | instance: {
123 | value: function (instance) {
124 | if (!this.__registration) {
125 | throw new DependencyResolverException("Registration's name is not defined");
126 | }
127 | if (instance === null || instance === undefined) {
128 | throw new DependencyResolverException("Parameter 'instance' is not passed to the method 'instance' for " +
129 | "registration '" + this.__registration.name + "'");
130 | }
131 | this.__registration.instance = instance;
132 | this.__registration.type = null;
133 | this.__registration.factory = null;
134 | this.__registration.singleton = true;
135 | this.__registration.dependencies = null;
136 | this.__withConstructor = false;
137 | this.__withProperties = false;
138 | this.__parameter = null;
139 | this.__property = null;
140 | this.__function = null;
141 | return this;
142 | },
143 | enumerable: true
144 | },
145 |
146 | asSingleton: {
147 | value: function () {
148 | if (!this.__registration) {
149 | throw new DependencyResolverException("Registration's name is not defined");
150 | }
151 | if (!this.__registration.type) {
152 | throw new DependencyResolverException("Type is not set for registration '" +
153 | this.__registration.name + "'");
154 | }
155 | this.__registration.singleton = true;
156 | this.__withConstructor = false;
157 | this.__withProperties = false;
158 | this.__parameter = null;
159 | this.__property = null;
160 | this.__function = null;
161 | return this;
162 | },
163 | enumerable: true
164 | },
165 |
166 | withConstructor: {
167 | value: function () {
168 | if (!this.__registration) {
169 | throw new DependencyResolverException("Registration's name is not defined");
170 | }
171 | if (!this.__registration.type) {
172 | throw new DependencyResolverException("Type is not set for registration '" +
173 | this.__registration.name + "'");
174 | }
175 | this.__withConstructor = true;
176 | this.__withProperties = false;
177 | this.__parameter = null;
178 | this.__property = null;
179 | this.__function = null;
180 | return this;
181 | },
182 | enumerable: true
183 | },
184 |
185 | param: {
186 | value: function (name) {
187 | if (!this.__registration) {
188 | throw new DependencyResolverException("Registration's name is not defined");
189 | }
190 | if (!this.__registration.type) {
191 | throw new DependencyResolverException("Type is not set for registration '" + this.__registration.name + "'");
192 | }
193 | var parameters = null,
194 | parameter = null,
195 | index;
196 | if (this.__withConstructor) {
197 | parameters = this.__registration.dependencies.parameters;
198 | if (this.__autowired && (name === undefined || name === null)) {
199 | throw new DependencyResolverException("Parameter 'name' has to be passed to the method, when dependency " +
200 | "container has option 'autowired' enabled");
201 | }
202 | parameter = this.__findParameter(name, parameters, this.__registration);
203 | } else if (this.__withProperties) {
204 | if (!this.__function) {
205 | throw new DependencyResolverException("Function is not defined");
206 | }
207 | parameters = this.__function.parameters;
208 | parameter = this.__findParameter(name, this.__function.parameters, this.__registration);
209 | } else {
210 | throw new DependencyResolverException("Invocation of method 'withConstructor' or 'withProperties' " +
211 | "is missing for registration '" + this.__registration.name + "'");
212 | }
213 | if (!parameter) {
214 | parameter = {
215 | index: index,
216 | name: name,
217 | value: undefined,
218 | reference: undefined
219 | };
220 | parameters.push(parameter);
221 | }
222 | this.__parameter = parameter;
223 | this.__property = null;
224 | return this;
225 | },
226 | enumerable: true
227 | },
228 |
229 | withProperties: {
230 | value: function () {
231 | if (!this.__registration) {
232 | throw new DependencyResolverException("Registration's name is not defined");
233 | }
234 | if (!this.__registration.type) {
235 | throw new DependencyResolverException("Type is not set for registration '" + this.__registration.name + "'");
236 | }
237 | this.__withProperties = true;
238 | this.__withConstructor = false;
239 | this.__parameter = null;
240 | this.__property = null;
241 | this.__function = null;
242 | return this;
243 | },
244 | enumerable: true
245 | },
246 |
247 | prop: {
248 | value: function (name) {
249 | if (!this.__registration) {
250 | throw new DependencyResolverException("Registration's name is not defined");
251 | }
252 | if (!name) {
253 | throw new DependencyResolverException("Parameter 'name' is not passed to the method 'prop' for " +
254 | "registration '" + this.__registration.name + "'");
255 | }
256 | if (typeof name !== 'string') {
257 | throw new DependencyResolverException("Parameter 'name' passed to the method 'prop' has to be" +
258 | " a 'string' for registration '" + this.__registration.name + "'");
259 | }
260 | if (!this.__registration.type) {
261 | throw new DependencyResolverException("Type is not set for registration '" + this.__registration.name + "'");
262 | }
263 | if (!this.__withProperties) {
264 | throw new DependencyResolverException("Invocation of method 'withProperties' is missing for " +
265 | "registration '" + this.__registration.name + "'");
266 | }
267 | var properties = this.__registration.dependencies.properties,
268 | property = null;
269 | for (var i = 0; i < properties.length; i++) {
270 | if (properties[i].name === name) {
271 | property = properties[i];
272 | break;
273 | }
274 | }
275 | if (!property) {
276 | property = {
277 | name: name,
278 | value: undefined,
279 | reference: undefined
280 | };
281 | properties.push(property);
282 | }
283 | this.__parameter = null;
284 | this.__property = property;
285 | this.__function = null;
286 | return this;
287 | },
288 | enumerable: true
289 | },
290 |
291 | func: {
292 | value: function (name) {
293 | if (!this.__registration) {
294 | throw new DependencyResolverException("Registration's name is not defined");
295 | }
296 | if (!name) {
297 | throw new DependencyResolverException("Parameter 'name' is not passed to the method 'func' for " +
298 | "registration '" + this.__registration.name + "'");
299 | }
300 | if (typeof name !== 'string') {
301 | throw new DependencyResolverException("Parameter 'name' passed to the method 'func' has to be" +
302 | " a 'string' for registration '" + this.__registration.name + "'");
303 | }
304 | if (!this.__registration.type) {
305 | throw new DependencyResolverException("Type is not set for registration '" + this.__registration.name + "'");
306 | }
307 | if (!this.__withProperties) {
308 | throw new DependencyResolverException("Invocation of method 'withProperties' is missing for " +
309 | "registration '" + this.__registration.name + "'");
310 | }
311 | var functions = this.__registration.dependencies.functions,
312 | func = null;
313 | for (var i = 0; i < functions.length; i++) {
314 | if (functions[i].name === name) {
315 | func = functions[i];
316 | break;
317 | }
318 | }
319 | if (!func) {
320 | func = {
321 | name: name,
322 | parameters: []
323 | };
324 | functions.push(func);
325 | }
326 | this.__parameter = null;
327 | this.__property = null;
328 | this.__function = func;
329 | return this;
330 | },
331 | enumerable: true
332 | },
333 |
334 | val: {
335 | value: function (instance) {
336 | if (!this.__registration) {
337 | throw new DependencyResolverException("Registration's name is not defined");
338 | }
339 | if (instance === null || instance === undefined) {
340 | throw new DependencyResolverException("Parameter 'instance' is not passed to the method 'val'");
341 | }
342 | if (!this.__withProperties && !this.__withConstructor) {
343 | throw new DependencyResolverException("Invocation of method withConstructor' or 'withProperties' " +
344 | "is missing");
345 | }
346 | if (this.__withConstructor && !this.__parameter) {
347 | throw new DependencyResolverException("Parameter is not defined");
348 | }
349 | if (this.__withProperties && !this.__parameter && !this.__property) {
350 | throw new DependencyResolverException("Parameter or property is not defined");
351 | }
352 | if (this.__parameter) {
353 | this.__parameter.value = instance;
354 | this.__parameter.reference = undefined;
355 | } else if (this.__property) {
356 | this.__property.value = instance;
357 | this.__property.reference = undefined;
358 | }
359 | return this;
360 | },
361 | enumerable: true
362 | },
363 |
364 | ref: {
365 | value: function (name) {
366 | if (!this.__registration) {
367 | throw new DependencyResolverException("Registration's name is not defined");
368 | }
369 | if (!name) {
370 | throw new DependencyResolverException("Parameter 'name' is not passed to the method 'ref' for " +
371 | "registration '" + this.__registration.name + "'");
372 | }
373 | if (typeof name !== 'string') {
374 | throw new DependencyResolverException("Parameter 'name' passed to the method 'ref' has to " +
375 | "be a 'string' for registration '" + this.__registration.name + "'");
376 | }
377 | if (!this.__withProperties && !this.__withConstructor) {
378 | throw new DependencyResolverException("Invocation of method 'withConstructor' or 'withProperties' " +
379 | "is missing for registration '" + this.__registration.name + "'");
380 | }
381 | if (this.__withConstructor && !this.__parameter) {
382 | throw new DependencyResolverException("Parameter is not defined");
383 | }
384 | if (this.__withProperties && !this.__parameter && !this.__property) {
385 | throw new DependencyResolverException("Parameter or property is not defined");
386 | }
387 | if (!this.contains(name)) {
388 | throw new DependencyResolverException("Type or instance is not registered with name '" + name + "'");
389 | }
390 | if (this.__parameter) {
391 | this.__parameter.value = undefined;
392 | this.__parameter.reference = name;
393 | } else if (this.__property) {
394 | this.__property.value = undefined;
395 | this.__property.reference = name;
396 | }
397 | return this;
398 | },
399 | enumerable: true
400 | },
401 |
402 | setFactory: {
403 | value: function (factory) {
404 | if (!this.__registration) {
405 | throw new DependencyResolverException("Registration's name is not defined");
406 | }
407 | if (!factory) {
408 | throw new DependencyResolverException("Parameter 'factory' is not passed to the method 'setFactory");
409 | }
410 | if (typeof factory !== 'function' && typeof factory !== 'object') {
411 | throw new DependencyResolverException("Parameter 'factory' passed to the method 'setFactory' has to be " +
412 | "a 'function' or 'object'");
413 | }
414 | if (typeof factory === 'object' && !('create' in factory)) {
415 | throw new DependencyResolverException("Factory's instance passed to the method 'setFactory' has to have " +
416 | "a method 'create'");
417 | }
418 | if (!this.__registration.type) {
419 | throw new DependencyResolverException("Type is not set for registration '" + this.__registration.name);
420 | }
421 | this.__registration.factory = factory;
422 | this.__withConstructor = false;
423 | this.__withProperties = false;
424 | this.__parameter = null;
425 | this.__property = null;
426 | this.__function = null;
427 | return this;
428 | },
429 | enumerable: true
430 | },
431 |
432 | create: {
433 | value: function () {
434 | return new DependencyResolver(this);
435 | },
436 | enumerable: true
437 | },
438 |
439 | inject: {
440 | value: function (func) {
441 | if (!func) {
442 | throw new DependencyResolverException("Parameter 'func' is not passed to method 'inject'");
443 | }
444 | var i,
445 | parameters = [],
446 | context = { resolving: [] };
447 | if (func instanceof Array) {
448 | if (func.length === 0) {
449 | throw new DependencyResolverException("The array passed to the method 'inject' can't be empty");
450 | }
451 | for (i = 0; i < func.length - 1; i++) {
452 | parameters.push(func[i]);
453 | }
454 | func = func[func.length - 1];
455 | if (typeof func !== 'function') {
456 | throw new DependencyResolverException("The last item of the array passed to the method 'inject' has " +
457 | "to be a 'function'");
458 | }
459 | for (i = 0; i < parameters.length; i++) {
460 | if (typeof parameters[i] === 'string' && this.contains(parameters[i])) {
461 | parameters[i] = this.__resolve(parameters[i], context);
462 | }
463 | }
464 | func.apply(null, parameters);
465 | } else {
466 | var registration = null;
467 | if (arguments.length === 2 && typeof arguments[1] === 'string') {
468 | var name = arguments[1];
469 | if (!this.contains(name)) {
470 | throw new DependencyResolverException("Type with name '" + name + "' is not registered");
471 | }
472 | registration = this.getRegistration(name);
473 | }
474 | var dependencyName;
475 | if (typeof func === 'function') {
476 | if (registration) {
477 | parameters = this.__getConstructorParameters(registration, context);
478 | } else {
479 | var args = this.__getFunctionArguments(func);
480 | for (i = 0; i < args.length; i++) {
481 | dependencyName = this.__resolveDependencyName(args[i]);
482 | if (this.contains(dependencyName)) {
483 | parameters.push(this.__resolve(dependencyName, context));
484 | } else {
485 | parameters.push(null);
486 | }
487 | }
488 | }
489 | func.apply(null, parameters);
490 | } else if (typeof func === 'object') {
491 | if (registration) {
492 | this.__setProperties(func, registration, context);
493 | this.__invokeFunctions(func, registration, context);
494 | } else {
495 | for (var propertyName in func) {
496 | dependencyName = this.__resolveDependencyName(propertyName);
497 | if (this.contains(dependencyName)) {
498 | parameters.push({
499 | name: propertyName,
500 | value: this.__resolve(dependencyName, context)
501 | });
502 | }
503 | }
504 | if (parameters.length > 0) {
505 | for (i = 0; i < parameters.length; i++) {
506 | func[parameters[i].name] = parameters[i].value;
507 | }
508 | }
509 | }
510 | } else {
511 | throw new DependencyResolverException("Invalid parameter has been passed to the method 'inject'");
512 | }
513 | }
514 | return this;
515 | },
516 | enumerable: true
517 | },
518 |
519 | contains: {
520 | value: function (name) {
521 | if (!name) {
522 | throw new DependencyResolverException("Parameter 'name' is not passed to the method 'contains'");
523 | }
524 | if (typeof name !== 'string') {
525 | throw new DependencyResolverException("Parameter 'name' passed to the has to be a 'string'");
526 | }
527 | var has = false;
528 | if (this.__container) {
529 | if (name in this.__container) {
530 | has = true;
531 | }
532 | }
533 | if (!has && this.__parent) {
534 | if (!('contains' in this.__parent)) {
535 | throw new DependencyResolverException("Dependency resolver's parent doesn't have a method 'contains'");
536 | }
537 | has = this.__parent.contains(name);
538 | }
539 | return has;
540 | },
541 | enumerable: true
542 | },
543 |
544 | resolve: {
545 | value: function (name) {
546 | return this.__resolve(name, {
547 | resolving: []
548 | });
549 | },
550 | enumerable: true
551 | },
552 |
553 | getDefaultFactory: {
554 | value: function () {
555 | var factory = null;
556 | if (this.__defaultFactory) {
557 | factory = this.__defaultFactory;
558 | } else if (this.__parent) {
559 | if (!('getDefaultFactory' in this.__parent)) {
560 | throw new DependencyResolverException("Dependency resolver's parent doesn't have a " +
561 | "method 'getDefaultFactory'");
562 | }
563 | factory = this.__parent.getDefaultFactory();
564 | } else {
565 | factory = new InstanceFactory();
566 | }
567 | return factory;
568 | },
569 | enumerable: true
570 | },
571 |
572 | setDefaultFactory: {
573 | value: function (factory) {
574 | if (!factory) {
575 | throw new DependencyResolverException("Parameter 'factory' is not passed to the method " +
576 | "'setDefaultFactory");
577 | }
578 | if (typeof factory !== 'function' && typeof factory !== 'object') {
579 | throw new DependencyResolverException("Parameter 'factory' passed to the method 'setDefaultFactory' has " +
580 | " to be a 'function' or 'object'");
581 | }
582 | if (typeof factory === 'object' && !('create' in factory)) {
583 | throw new DependencyResolverException("Factory's instance passed to the method 'setDefaultFactory' has " +
584 | "to have a method 'create'");
585 | }
586 | this.__defaultFactory = factory;
587 | return this;
588 | },
589 | enumerable: true
590 | },
591 |
592 | getNameTransformer: {
593 | value: function () {
594 | var transformer = null;
595 | if (this.__nameTransformer) {
596 | transformer = this.__nameTransformer;
597 | } else if (this.__parent) {
598 | if (!('getNameTransformer' in this.__parent)) {
599 | throw new DependencyResolverException("Dependency resolver's parent doesn't have a " +
600 | "method 'getNameTransformer'");
601 | }
602 | transformer = this.__parent.getNameTransformer();
603 | } else {
604 | transformer = new NameTransformer();
605 | }
606 | return transformer;
607 | },
608 | enumerable: true
609 | },
610 |
611 | setNameTransformer: {
612 | value: function (transformer) {
613 | if (!transformer) {
614 | throw new DependencyResolverException("Parameter 'transformer' is not passed to the method " +
615 | "'setNameTransformer'");
616 | }
617 | if (typeof transformer !== 'function' && typeof transformer !== 'object') {
618 | throw new DependencyResolverException("Parameter 'transformer' passed to the method 'setNameTransformer' " +
619 | "has to be a 'function' or 'object'");
620 | }
621 | if (typeof transformer === 'object' && !('transform' in transformer)) {
622 | throw new DependencyResolverException("Trabsformers's instance passed to the method 'setNameTransformer' " +
623 | "has to have a method 'transform'");
624 | }
625 | this.__nameTransformer = transformer;
626 | return this;
627 | },
628 | enumerable: true
629 | },
630 |
631 | getRegistration: {
632 | value: function (name) {
633 | var registration = null;
634 | if (this.__container && name in this.__container) {
635 | registration = this.__container[name];
636 | } else if (this.__parent) {
637 | if (!('getRegistration' in this.__parent)) {
638 | throw new DependencyResolverException("Dependency resolver's parent doesn't have a " +
639 | "method 'getRegistration'");
640 | }
641 | registration = this.__parent.getRegistration(name);
642 | }
643 | return registration;
644 | },
645 | enumerable: true
646 | },
647 |
648 | dispose: {
649 | value: function () {
650 | var registration = null,
651 | i = 0;
652 | if (this.__container) {
653 | for (var name in this.__container) {
654 | if (!(this.__container[name] instanceof Array)) {
655 | registration = this.__container[name];
656 | if (registration.instance && ('dispose' in registration.instance)) {
657 | registration.instance.dispose();
658 | }
659 | registration.instance = null;
660 | registration.factory = null;
661 | } else {
662 | var registrations = this.__container[name];
663 | for (i = 0; i < registrations.length; i++) {
664 | registration = registrations[i];
665 | if (registration.instance && ('dispose' in registration.instance)) {
666 | registration.instance.dispose();
667 | }
668 | registration.instance = null;
669 | registration.factory = null;
670 | }
671 | }
672 | }
673 | }
674 | this.__parent = null;
675 | this.__defaultFactory = null;
676 | this.__nameTransformer = null;
677 | this.__autowired = false;
678 | this.__container = null;
679 | this.__registration = null;
680 | this.__withProperties = false;
681 | this.__withConstructor = false;
682 | this.__parameter = null;
683 | this.__property = null;
684 | this.__function = null;
685 | },
686 | enumerable: true
687 | },
688 |
689 | toString: {
690 | value: function () {
691 | return '[object DependencyResolver]';
692 | },
693 | enumerable: true
694 | },
695 |
696 | __getFunctionArguments: {
697 | value: function (func) {
698 | if (func && typeof func === 'function' && 'toString' in func) {
699 | var str = null;
700 | var result = func
701 | .toString()
702 | .match(/^[\s\(]*function[^(]*\(([^)]*)\)/);
703 | if (result && result.length > 1) {
704 | str = result[1]
705 | .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
706 | .replace(/\s+/g, '');
707 | }
708 | if (str) {
709 | return str.split(',');
710 | }
711 | }
712 | return [];
713 | }
714 | },
715 |
716 | __resolve: {
717 | value: function (name, context) {
718 | if (!name) {
719 | throw new DependencyResolverException("Parameter 'name' is not passed to the method 'resolve'");
720 | }
721 | if (typeof name !== 'string') {
722 | throw new DependencyResolverException("Parameter 'name' passed to the method 'resolve' has to be " +
723 | "a 'string'");
724 | }
725 | if (debug && console && 'log' in console) {
726 | var message = "-> '" + name + "'";
727 | for (var j = 0; j < context.resolving.length; j++) {
728 | message = " " + message;
729 | }
730 | console.log(message);
731 | }
732 | if (!this.contains(name)) {
733 | throw new DependencyResolverException("Type or instance with name '" + name + "' is not registered");
734 | }
735 | var index = context.resolving.indexOf(name);
736 | if (index !== -1) {
737 | throw new DependencyResolverException("Can not resolve circular dependency '" + name + "'");
738 | }
739 | context.resolving.push(name);
740 | var instance = null,
741 | registration = this.getRegistration(name);
742 | if (!(registration instanceof Array)) {
743 | instance = this.__resolveInstance(registration, context);
744 | } else {
745 | instance = [];
746 | for (var i = 0; i < registration.length; i++) {
747 | instance.push(this.__resolveInstance(registration[i], context));
748 | }
749 | }
750 | index = context.resolving.indexOf(name);
751 | if (index > -1) {
752 | context.resolving.splice(index, 1);
753 | }
754 | return instance;
755 | }
756 | },
757 |
758 | __resolveInstance: {
759 | value: function (registration, context) {
760 | var instance = null;
761 | if (registration.instance !== null && registration.instance !== undefined) {
762 | instance = registration.instance;
763 | } else {
764 | instance = this.__createInstance(registration, context);
765 | this.__setProperties(instance, registration, context);
766 | this.__invokeFunctions(instance, registration, context);
767 | if (instance && registration.singleton) {
768 | registration.instance = instance;
769 | }
770 | if (!instance) {
771 | throw new DependencyResolverException("Failed to resolve instance by name '" + registration.name + "'");
772 | }
773 | }
774 | return instance;
775 | }
776 | },
777 |
778 | __resolveDependencyName: {
779 | value: function (name) {
780 | var transform = this.getNameTransformer();
781 | if (typeof transform === 'function') {
782 | name = transform(name);
783 | } else {
784 | name = transform.transform(name);
785 | }
786 | if (!name) {
787 | throw new DependencyResolverException("Failed to resolve dependency name");
788 | }
789 | return name;
790 | }
791 | },
792 |
793 | __createInstance: {
794 | value: function (registration, context) {
795 | var i,
796 | instance;
797 | var parameters = this.__getConstructorParameters(registration, context);
798 | var options = new InstanceFactoryOptions({
799 | name: registration.name,
800 | type: registration.type,
801 | parameters: parameters
802 | });
803 | var factory = null;
804 | if (registration.factory) {
805 | factory = registration.factory;
806 | } else {
807 | factory = this.getDefaultFactory();
808 | }
809 | if (factory) {
810 | if (typeof factory === 'function') {
811 | instance = factory.call(null, options);
812 | } else {
813 | instance = factory.create(options);
814 | }
815 | } else {
816 | throw new DependencyResolverException("Default factory is not defined");
817 | }
818 | return instance;
819 | }
820 | },
821 |
822 | __getConstructorParameters: {
823 | value: function (registration, context) {
824 | var parameters = [];
825 | if (registration && registration.dependencies) {
826 | var i,
827 | parameter,
828 | value,
829 | args,
830 | index;
831 | if (this.__autowired) {
832 | args = this.__getFunctionArguments(registration.type);
833 | var dependencyName;
834 | for (i = 0; i < args.length; i++) {
835 | dependencyName = this.__resolveDependencyName(args[i]);
836 | if (this.contains(dependencyName)) {
837 | parameters.push(this.__resolve(dependencyName, context));
838 | } else {
839 | parameters.push(null);
840 | }
841 | }
842 | }
843 | for (i = 0; i < registration.dependencies.parameters.length; i++) {
844 | parameter = registration.dependencies.parameters[i];
845 | if (parameter.value !== undefined) {
846 | value = parameter.value;
847 | } else if (parameter.reference !== undefined) {
848 | value = this.__resolve(parameter.reference, context);
849 | } else {
850 | value = null;
851 | }
852 | if (parameter.index !== undefined && parameter.index !== null) {
853 | parameters[parameter.index] = value;
854 | } else if (parameter.name) {
855 | if (!args) {
856 | args = this.__getFunctionArguments(registration.type);
857 | }
858 | index = args.indexOf(parameter.name);
859 | if (index === -1) {
860 | throw new DependencyResolverException("Constructor in registration '" + registration.name +
861 | "' doesn't have defined parameter '" + parameter.name + "'");
862 | }
863 | parameters[index] = value;
864 | } else {
865 | parameters.push(value);
866 | }
867 | }
868 | }
869 | return parameters;
870 | }
871 | },
872 |
873 | __hasProperty: {
874 | value: function (registration, name) {
875 | var has = false;
876 | if (registration.dependencies) {
877 | var property;
878 | for (var i = 0; i < registration.dependencies.properties.length; i++) {
879 | property = registration.dependencies.properties[i];
880 | if (property.name === name) {
881 | has = true;
882 | break;
883 | }
884 | }
885 | }
886 | return has;
887 | }
888 | },
889 |
890 | __findParameter: {
891 | value: function (name, parameters, registration) {
892 | var parameter = null;
893 | if (name !== null && name !== undefined && registration !== null) {
894 | if (typeof name === 'number') {
895 | index = name;
896 | name = undefined;
897 | if (index < 0) {
898 | throw new DependencyResolverException("Parameter 'name' passed to the method 'param' is out of " +
899 | "range for registration '" + registration.name + "'");
900 | }
901 | if (index < parameters.length) {
902 | parameter = parameters[index];
903 | }
904 | } else if (typeof name === 'string') {
905 | for (var i = 0; i < parameters.length; i++) {
906 | if (parameters[i].name === name) {
907 | parameter = parameters[i];
908 | break;
909 | }
910 | }
911 | } else {
912 | throw new DependencyResolverException("Parameter 'name' passed to the method 'param' has to " +
913 | "be a 'number' or a 'string' for registration '" + registration.name + "'");
914 | }
915 | }
916 | return parameter;
917 | }
918 | },
919 |
920 | __setProperties: {
921 | value: function (instance, registration, context) {
922 | if (registration.dependencies) {
923 | if (this.__autowired) {
924 | for (var propertyName in instance) {
925 | var dependencyName = this.__resolveDependencyName(propertyName);
926 | if (!this.__hasProperty(registration, propertyName) && this.contains(dependencyName)) {
927 | instance[propertyName] = this.__resolve(dependencyName, context);
928 | }
929 | }
930 | }
931 | for (var i = 0; i < registration.dependencies.properties.length; i++) {
932 | var property = registration.dependencies.properties[i];
933 | if (!(property.name in instance)) {
934 | throw new DependencyResolverException("Resolved object '" + registration.name +
935 | "' doesn't have property '" + property.name + "'");
936 | }
937 | if (property.value !== undefined) {
938 | instance[property.name] = property.value;
939 | } else if (property.reference !== undefined) {
940 | instance[property.name] = this.__resolve(property.reference, context);
941 | }
942 | }
943 | }
944 | }
945 | },
946 |
947 | __invokeFunctions: {
948 | value: function (instance, registration, context) {
949 | if (registration.dependencies) {
950 | var i,
951 | j,
952 | parameter,
953 | value;
954 | for (i = 0; i < registration.dependencies.functions.length; i++) {
955 | var func = registration.dependencies.functions[i];
956 | if (!(func.name in instance)) {
957 | throw new DependencyResolverException("Resolved object '" + registration.name +
958 | "' doesn't have function '" + func.name + "'");
959 | }
960 | var parameters = [];
961 | for (j = 0; j < func.parameters.length; j++) {
962 | parameter = func.parameters[j];
963 | if (parameter.value !== undefined) {
964 | value = parameter.value;
965 | } else if (parameter.reference !== undefined) {
966 | value = this.__resolve(parameter.reference, context);
967 | } else {
968 | value = null;
969 | }
970 | if (parameter.index !== undefined && parameter.index !== null) {
971 | parameters[parameter.index] = value;
972 | } else if (parameter.name) {
973 | if (!args) {
974 | args = this.__getFunctionArguments(instance[func.name]);
975 | }
976 | index = args.indexOf(parameter.name);
977 | if (index === -1) {
978 | throw new DependencyResolverException("Function doesn't have defined parameter '" +
979 | parameter.name + "'");
980 | }
981 | parameters[index] = value;
982 | } else {
983 | parameters.push(value);
984 | }
985 | }
986 | instance[func.name].apply(instance, parameters);
987 | }
988 | }
989 | }
990 | }
991 |
992 | });
993 |
994 | Object.seal(DependencyResolver);
995 | Object.seal(DependencyResolver.prototype);
996 |
997 | exports.DependencyResolver = DependencyResolver;
--------------------------------------------------------------------------------
/src/DependencyResolverException.js:
--------------------------------------------------------------------------------
1 | var DependencyResolverException = function (message) {
2 | this.__name = 'DependencyResolverException';
3 | this.__stack = null;
4 | this.__message = message || "A dependency resolver exception has occurred.";
5 | var lines, i, tmp;
6 | if ((typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Chrome') !== -1) ||
7 | (typeof navigator === 'undefined')) {
8 | lines = new Error().stack.split('\n');
9 | if (lines && lines.length > 2) {
10 | tmp = [];
11 | for (i = 2; i < lines.length; i++) {
12 | if (lines[i]) {
13 | tmp.push(lines[i].trim());
14 | }
15 | }
16 | this.stack = tmp.join('\n');
17 | }
18 | } else if (typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Firefox') !== -1) {
19 | lines = new Error().stack.split('\n');
20 | if (lines && lines.length > 1) {
21 | tmp = [];
22 | for (i = 1; i < lines.length; i++) {
23 | if (lines[i]) {
24 | tmp.push('at ' + lines[i].trim().replace('@', ' (') + ')');
25 | }
26 | }
27 | this.stack = tmp.join('\n');
28 | }
29 | } else if (typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Trident') !== -1) {
30 | try {
31 | throw new Error();
32 | } catch (error) {
33 | if ('stack' in error) {
34 | lines = error.stack.split('\n');
35 | if (lines && lines.length > 2) {
36 | tmp = [];
37 | for (i = 2; i < lines.length; i++) {
38 | if (lines[i]) {
39 | tmp.push(lines[i].trim());
40 | }
41 | }
42 | this.stack = tmp.join('\n');
43 | }
44 | } else {
45 | this.stack = '';
46 | }
47 | }
48 | } else {
49 | var error = new Error();
50 | if ('stack' in error) {
51 | this.stack = error.stack;
52 | } else {
53 | this.stack = '';
54 | }
55 | }
56 | Object.defineProperty(this, '__name', { enumerable: false });
57 | Object.defineProperty(this, '__message', { enumerable: false });
58 | Object.defineProperty(this, '__stack', { enumerable: false });
59 | Object.seal(this);
60 | };
61 |
62 | DependencyResolverException.prototype = Object.create(Object.prototype, {
63 |
64 | name: {
65 | get: function () {
66 | return this.__name;
67 | },
68 | set: function (value) {
69 | this.__name = value;
70 | },
71 | enumerable: true
72 | },
73 |
74 | message: {
75 | get: function () {
76 | return this.__message;
77 | },
78 | set: function (value) {
79 | this.__message = value;
80 | },
81 | enumerable: true
82 | },
83 |
84 | stack: {
85 | get: function () {
86 | return this.__stack;
87 | },
88 | set: function (value) {
89 | this.__stack = value;
90 | },
91 | enumerable: true
92 | },
93 |
94 | toString: {
95 | value: function () {
96 | var msg = this.name + ': ' + this.message;
97 | if (this.stack) {
98 | msg += '\n\t' + this.stack.replace(/\n/g, '\n\t');
99 | }
100 | return msg;
101 | },
102 | enumerable: true
103 | }
104 |
105 | });
106 |
107 | Object.seal(DependencyResolverException);
108 | Object.seal(DependencyResolverException.prototype);
109 |
110 | exports.DependencyResolverException = DependencyResolverException;
--------------------------------------------------------------------------------
/src/IDependencyResolver.js:
--------------------------------------------------------------------------------
1 | var IDependencyResolver = Object.create(Object.prototype, {
2 |
3 | isAutowired: {
4 | get: function () {},
5 | enumerable: true
6 | },
7 |
8 | autowired: {
9 | value: function (value) {},
10 | enumerable: true
11 | },
12 |
13 | register: {
14 | value: function (name) {},
15 | enumerable: true
16 | },
17 |
18 | as: {
19 | value: function (type) {},
20 | enumerable: true
21 | },
22 |
23 | instance: {
24 | value: function (instance) {},
25 | enumerable: true
26 | },
27 |
28 | asSingleton: {
29 | value: function () {},
30 | enumerable: true
31 | },
32 |
33 | withConstructor: {
34 | value: function () {},
35 | enumerable: true
36 | },
37 |
38 | param: {
39 | value: function (name) {},
40 | enumerable: true
41 | },
42 |
43 | withProperties: {
44 | value: function (name) {},
45 | enumerable: true
46 | },
47 |
48 | prop: {
49 | value: function (name) {},
50 | enumerable: true
51 | },
52 |
53 | val: {
54 | value: function (instance) {},
55 | enumerable: true
56 | },
57 |
58 | ref: {
59 | value: function (name) {},
60 | enumerable: true
61 | },
62 |
63 | setFactory: {
64 | value: function (factory) {},
65 | enumerable: true
66 | },
67 |
68 | create: {
69 | value: function () {},
70 | enumerable: true
71 | },
72 |
73 | inject: {
74 | value: function (func, name) {},
75 | enumerable: true
76 | },
77 |
78 | contains: {
79 | value: function (name) {},
80 | enumerable: true
81 | },
82 |
83 | resolve: {
84 | value: function (name) {},
85 | enumerable: true
86 | },
87 |
88 | getDefaultFactory: {
89 | value: function () {},
90 | enumerable: true
91 | },
92 |
93 | setDefaultFactory: {
94 | value: function (factory) {},
95 | enumerable: true
96 | },
97 |
98 | getNameTransformer: {
99 | value: function () {},
100 | enumerable: true
101 | },
102 |
103 | setNameTransformer: {
104 | value: function (transformer) {},
105 | enumerable: true
106 | },
107 |
108 | getRegistration: {
109 | value: function (name) {},
110 | enumerable: true
111 | },
112 |
113 | dispose: {
114 | value: function () {},
115 | enumerable: true
116 | },
117 |
118 | toString: {
119 | value: function () {
120 | return '[object IDependencyResolver]';
121 | },
122 | enumerable: true
123 | }
124 |
125 | });
126 |
127 | Object.freeze(IDependencyResolver);
128 |
129 | exports.IDependencyResolver = IDependencyResolver;
--------------------------------------------------------------------------------
/src/IInstanceFactory.js:
--------------------------------------------------------------------------------
1 | var IInstanceFactory = Object.create(Object.prototype, {
2 |
3 | create: {
4 | value: function (options) {},
5 | enumerable: true
6 | },
7 |
8 | toString: {
9 | value: function () {
10 | return '[object IInstanceFactory]';
11 | },
12 | enumerable: true
13 | }
14 |
15 | });
16 |
17 | Object.freeze(IInstanceFactory);
18 |
19 | exports.IInstanceFactory = IInstanceFactory;
--------------------------------------------------------------------------------
/src/INameTransformer.js:
--------------------------------------------------------------------------------
1 | var INameTransformer = Object.create(Object.prototype, {
2 |
3 | transform: {
4 | value: function (name) {},
5 | enumerable: true
6 | },
7 |
8 | toString: {
9 | value: function () {
10 | return '[object INameTransformer]';
11 | },
12 | enumerable: true
13 | }
14 |
15 | });
16 |
17 | Object.freeze(INameTransformer);
18 |
19 | exports.INameTransformer = INameTransformer;
--------------------------------------------------------------------------------
/src/InstanceFactory.js:
--------------------------------------------------------------------------------
1 | var InstanceFactory = function () {
2 | Object.seal(this);
3 | };
4 |
5 | InstanceFactory.prototype = Object.create(Object.prototype, {
6 |
7 | create: {
8 | value: function (options) {
9 | if (!options) {
10 | throw new DependencyResolverException("Parameter 'options' is not set");
11 | }
12 | if ('type' in options && !options.type) {
13 | throw new DependencyResolverException("Factory can't create object, because type is not set");
14 | }
15 | if (typeof options.type !== 'function') {
16 | throw new DependencyResolverException("Factory can't create object, because given type is not a function");
17 | }
18 | if (options.type === Number || options.type === Date || options.type === Boolean || options.type === String ||
19 | options.type === Array || options.type === Function || options.type === RegExp) {
20 | throw new DependencyResolverException("Basic type can not be instantiated using a factory");
21 | }
22 | var Type = options.type;
23 | if (options.parameters && options.parameters.length > 0) {
24 | Type = function () {
25 | return options.type.apply(this, options.parameters);
26 | };
27 | Type.prototype = Object.create(options.type.prototype);
28 | }
29 | return new Type();
30 | },
31 | enumerable: true
32 | },
33 |
34 | toString: {
35 | value: function () {
36 | return '[object InstanceFactory]';
37 | },
38 | enumerable: true
39 | }
40 |
41 | });
42 |
43 | Object.seal(InstanceFactory);
44 | Object.seal(InstanceFactory.prototype);
45 |
46 | exports.InstanceFactory = InstanceFactory;
--------------------------------------------------------------------------------
/src/InstanceFactoryOptions.js:
--------------------------------------------------------------------------------
1 | var InstanceFactoryOptions = function (options) {
2 | this.__name = null;
3 | this.__type = null;
4 | this.__parameters = null;
5 | if (options) {
6 | for (var propertyName in options) {
7 | if (propertyName in this) {
8 | this[propertyName] = options[propertyName];
9 | } else {
10 | throw new DependencyResolverException("Class 'InstanceFactoryOptions' doesn't have a property '" +
11 | propertyName + "'");
12 | }
13 | }
14 | }
15 | Object.defineProperty(this, '__name', { enumerable: false });
16 | Object.defineProperty(this, '__type', { enumerable: false });
17 | Object.defineProperty(this, '__parameters', { enumerable: false });
18 | Object.seal(this);
19 | };
20 |
21 | InstanceFactoryOptions.prototype = Object.create(Object.prototype, {
22 |
23 | name: {
24 | get: function () {
25 | return this.__name;
26 | },
27 | set: function (value) {
28 | this.__name = value;
29 | },
30 | enumerable: true
31 | },
32 |
33 | type: {
34 | get: function () {
35 | return this.__type;
36 | },
37 | set: function (value) {
38 | this.__type = value;
39 | },
40 | enumerable: true
41 | },
42 |
43 | parameters: {
44 | get: function () {
45 | return this.__parameters;
46 | },
47 | set: function (value) {
48 | this.__parameters = value;
49 | },
50 | enumerable: true
51 | },
52 |
53 | toString: {
54 | value: function () {
55 | return '[object InstanceFactoryOptions]';
56 | },
57 | enumerable: true
58 | }
59 |
60 | });
61 |
62 | Object.seal(InstanceFactoryOptions);
63 | Object.seal(InstanceFactoryOptions.prototype);
64 |
65 | exports.InstanceFactoryOptions = InstanceFactoryOptions;
--------------------------------------------------------------------------------
/src/NameTransformer.js:
--------------------------------------------------------------------------------
1 | var NameTransformer = function () {
2 | Object.seal(this);
3 | };
4 |
5 | NameTransformer.prototype = Object.create(Object.prototype, {
6 |
7 | transform: {
8 | value: function (name) {
9 | if (!name) {
10 | throw new DependencyResolverException("Parameter 'name' is not passed to the method 'transform'");
11 | }
12 | return name;
13 | },
14 | enumerable: true
15 | },
16 |
17 | toString: {
18 | value: function () {
19 | return '[object NameTransformer]';
20 | },
21 | enumerable: true
22 | }
23 |
24 | });
25 |
26 | Object.seal(NameTransformer);
27 | Object.seal(NameTransformer.prototype);
28 |
29 | exports.NameTransformer = NameTransformer;
--------------------------------------------------------------------------------