mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
feature(@jsdoc/core): add simple inversion of control (IoC) tool
Currently unused. Intended to be used for JSDoc core dependencies that must be available everywhere, such as the config and the event bus.
This commit is contained in:
parent
470d3c801e
commit
b850fa14b9
@ -5,9 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const config = require('./lib/config');
|
const config = require('./lib/config');
|
||||||
|
const dependencies = require('./lib/dependencies');
|
||||||
const name = require('./lib/name');
|
const name = require('./lib/name');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
config,
|
config,
|
||||||
|
dependencies,
|
||||||
name,
|
name,
|
||||||
};
|
};
|
||||||
|
|||||||
42
packages/jsdoc-core/lib/dependencies.js
Normal file
42
packages/jsdoc-core/lib/dependencies.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
const yaioc = require('yaioc');
|
||||||
|
|
||||||
|
let dependencies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for JSDoc classes, objects, and values that can be injected into other modules.
|
||||||
|
*
|
||||||
|
* @alias module:@jsdoc/core.deps
|
||||||
|
*/
|
||||||
|
class Dependencies {
|
||||||
|
constructor() {
|
||||||
|
// This class provides a lightweight facade for the `yaioc` package.
|
||||||
|
this._container = yaioc.container();
|
||||||
|
}
|
||||||
|
|
||||||
|
get(name) {
|
||||||
|
const dep = this._container.get(name);
|
||||||
|
|
||||||
|
if (dep === undefined) {
|
||||||
|
throw new Error(`No dependency registered for the name "${name}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dep;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerClass(klass, opts = {}) {
|
||||||
|
if (opts.singleton) {
|
||||||
|
this._container.cache().register(klass);
|
||||||
|
} else {
|
||||||
|
this._container.register(klass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerValue(name, value) {
|
||||||
|
this._container.register(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies = new Dependencies();
|
||||||
|
dependencies.Dependencies = Dependencies;
|
||||||
|
|
||||||
|
module.exports = dependencies;
|
||||||
1111
packages/jsdoc-core/package-lock.json
generated
1111
packages/jsdoc-core/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,8 @@
|
|||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"strip-bom": "^4.0.0",
|
"strip-bom": "^4.0.0",
|
||||||
"strip-json-comments": "^3.1.1"
|
"strip-json-comments": "^3.1.1",
|
||||||
|
"yaioc": "^1.10.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=v14.17.6"
|
"node": ">=v14.17.6"
|
||||||
|
|||||||
@ -13,6 +13,14 @@ describe('@jsdoc/core', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('dependencies', () => {
|
||||||
|
it('is lib/dependencies', () => {
|
||||||
|
const dependencies = require('../../lib/dependencies');
|
||||||
|
|
||||||
|
expect(core.dependencies).toBe(dependencies);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('name', () => {
|
describe('name', () => {
|
||||||
it('is lib/name', () => {
|
it('is lib/name', () => {
|
||||||
const name = require('../../lib/name');
|
const name = require('../../lib/name');
|
||||||
|
|||||||
100
packages/jsdoc-core/test/specs/lib/dependencies.js
Normal file
100
packages/jsdoc-core/test/specs/lib/dependencies.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
const dependencies = require('../../../lib/dependencies');
|
||||||
|
|
||||||
|
describe('@jsdoc/core/lib/dependencies', () => {
|
||||||
|
let container;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
container = new dependencies.Dependencies();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('is an object', () => {
|
||||||
|
expect(dependencies).toBeObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Dependencies', () => {
|
||||||
|
it('is the constructor of the dependencies object', () => {
|
||||||
|
expect(dependencies.Dependencies).toBe(dependencies.constructor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('get', () => {
|
||||||
|
it('throws an error if the name is missing', () => {
|
||||||
|
expect(() => container.get()).toThrowError();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws an error if the name is unrecognized', () => {
|
||||||
|
expect(() => container.get('foo')).toThrowError();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns an instance of classes', () => {
|
||||||
|
class Foo {}
|
||||||
|
|
||||||
|
let instance;
|
||||||
|
|
||||||
|
container.registerClass(Foo);
|
||||||
|
instance = container.get('foo');
|
||||||
|
|
||||||
|
expect(instance).toBeInstanceOf(Foo);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes dependencies to instance constructors', () => {
|
||||||
|
class Foo {
|
||||||
|
constructor(bar) {
|
||||||
|
this.bar = bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar {}
|
||||||
|
|
||||||
|
let instance;
|
||||||
|
|
||||||
|
container.registerClass(Foo);
|
||||||
|
container.registerClass(Bar);
|
||||||
|
instance = container.get('foo');
|
||||||
|
|
||||||
|
expect(instance.bar).toBeInstanceOf(Bar);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the same instance every time for singletons', () => {
|
||||||
|
class Foo {}
|
||||||
|
|
||||||
|
let instance1;
|
||||||
|
let instance2;
|
||||||
|
|
||||||
|
container.registerClass(Foo, { singleton: true });
|
||||||
|
instance1 = container.get('foo');
|
||||||
|
instance2 = container.get('foo');
|
||||||
|
|
||||||
|
expect(instance2).toBe(instance1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns static values', () => {
|
||||||
|
const value = new Set();
|
||||||
|
|
||||||
|
container.registerValue('foo', value);
|
||||||
|
|
||||||
|
expect(container.get('foo')).toBe(value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('registerClass', () => {
|
||||||
|
// The tests for `get()` also test the behavior of these methods more extensively.
|
||||||
|
it('accepts a constructor', () => {
|
||||||
|
class Foo {}
|
||||||
|
|
||||||
|
expect(() => container.registerClass(Foo)).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts a `singleton` option', () => {
|
||||||
|
class Foo {}
|
||||||
|
|
||||||
|
expect(() => container.registerClass(Foo, { singleton: true })).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('registerValue', () => {
|
||||||
|
it('accepts a name and value', () => {
|
||||||
|
expect(() => container.registerValue('name', new Set())).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user