api-builder: add target package

This commit is contained in:
Peter Bacon Darwin
2015-11-06 21:40:30 +00:00
parent 9a6fa4b4c5
commit b68ef96472
9 changed files with 263 additions and 31 deletions
@@ -1,12 +1,13 @@
var path = require('canonical-path');
var Package = require('dgeni').Package;
var basePackage = require('../docs-package');
var targetPackage = require('../target-package');
var PROJECT_PATH = path.resolve(__dirname, "../../..");
var PUBLIC_PATH = path.resolve(PROJECT_PATH, 'public');
var DOCS_PATH = path.resolve(PUBLIC_PATH, 'docs');
module.exports = new Package('angular.io', [basePackage])
module.exports = new Package('angular.io', [basePackage, targetPackage])
.factory(require('./services/renderMarkdown'))
.processor(require('./processors/addJadeDataDocsProcessor'))
+2 -1
View File
@@ -1,7 +1,8 @@
var Package = require('dgeni').Package;
module.exports = new Package('target', [])
module.exports = new Package('target', [require('dgeni-packages/jsdoc')])
.factory(require('./services/targetEnvironments'))
.factory(require('./inline-tag-defs/target'))
.config(function(inlineTagProcessor, targetInlineTagDef) {
@@ -5,19 +5,30 @@ var _ = require('lodash');
* @description
* Process inline `target` block tags
* (of the form `{@target environment1 environment2}...{@endtarget}`),
* filtering out the blocks that do not match the containing document's
* `targetEnvironments`.
* filtering out the blocks that do not match the active `targetEnvironments`.
*/
module.exports = function targetInlineTagDef() {
module.exports = function targetInlineTagDef(targetEnvironments, log, createDocMessage) {
return {
name: 'target',
end: 'endtarget',
handler: function(doc, tagName, tagDescription) {
var targets = tagDescription && tagDescription.tag.split(' ');
if (!targets || !doc.targetEnvironments ||
_.intersection(targets, doc.targetEnvironments).length) {
return tagDescription.content;
var hasTargets = targets && targets.length;
try {
// Return the contents of this block if any of the following is true:
// * it has no targets
// * there are no targets stored in the targetEnvironments service
// * the block's targets overlap with the active targets in the targetEnvironments service
if (!hasTargets || !targetEnvironments.hasActive() || targetEnvironments.someActive(targets))
{
return tagDescription.content;
}
} catch(x) {
log.error(createDocMessage('Error processing target inline tag def - ' + x.message, doc));
}
// Otherwise return an empty string
return '';
}
};
@@ -1,24 +1,52 @@
var targetFactory = require('./target');
var mockPackage = require('../mocks/mockPackage');
var Dgeni = require('dgeni');
describe('target inline-tag-def', function() {
it('should filter out content that does not match the doc.targetEnvironments', function() {
var doc, target, result;
var dgeni, injector, targetInlineTagDef;
doc = {
targetEnvironments: ['js', 'es6']
};
beforeEach(function() {
dgeni = new Dgeni([mockPackage()]);
injector = dgeni.configureInjector();
targetInlineTagDef = injector.get('targetInlineTagDef');
});
target = targetFactory();
result = target.handler(doc, 'target', {
it('should filter out content that does not match the targetEnvironments', function() {
var doc = {};
var targetEnvironments = injector.get('targetEnvironments');
targetEnvironments.addAllowed('js', true);
targetEnvironments.addAllowed('es6', true);
targetEnvironments.addAllowed('ts', false);
var result = targetInlineTagDef.handler(doc, 'target', {
tag: 'es6 ts',
content: 'abc'
});
expect(result).toEqual('abc');
result = target.handler(doc, 'target', {
result = targetInlineTagDef.handler(doc, 'target', {
tag: 'ts',
content: 'xyz'
});
expect(result).toEqual('');
});
it('should not filter anything if there are no doc nor global target environments', function() {
var doc = {};
var result = targetInlineTagDef.handler(doc, 'target', {
tag: 'es6 ts',
content: 'abc'
});
expect(result).toEqual('abc');
result = targetInlineTagDef.handler(doc, 'target', {
tag: 'ts',
content: 'xyz'
});
expect(result).toEqual('xyz');
});
});
@@ -0,0 +1,11 @@
var Package = require('dgeni').Package;
module.exports = function mockPackage() {
return new Package('mockPackage', [require('../')])
// provide a mock log service
.factory('log', function() { return require('dgeni/lib/mocks/log')(false); })
.factory('templateEngine', function() { return {}; });
};
@@ -0,0 +1,51 @@
module.exports = function targetEnvironments() {
var _targets = Object.create(null);
var _activeCount = 0;
var checkAllowed = function(target) {
if (!(target in _targets)) {
throw new Error('Error accessing target "' + target + '". It is not in the list of allowed targets: ' + Object.keys(_targets));
}
};
var updateActiveCount = function() {
_activeCount = 0;
for(target in _targets) {
if (_targets[target]) _activeCount++;
}
};
return {
addAllowed: function(target, isActive) {
_targets[target] = !!isActive;
updateActiveCount();
},
removeAllowed: function(target) {
delete _targets[target];
updateActiveCount();
},
activate: function(target) {
checkAllowed(target);
_targets[target] = true;
updateActiveCount();
},
deactivate: function(target) {
checkAllowed(target);
_targets[target] = false;
updateActiveCount();
},
isActive: function(target) {
checkAllowed(target);
return _targets[target];
},
hasActive: function() {
return _activeCount > 0;
},
someActive: function(targets) {
for(var i=0,ii=targets.length; i<ii; i++) {
if (this.isActive(targets[i])) return true;
}
return false;
}
};
};
@@ -0,0 +1,105 @@
var mockPackage = require('../mocks/mockPackage');
var Dgeni = require('dgeni');
describe('target inline-tag-def', function() {
var dgeni, injector, te;
beforeEach(function() {
dgeni = new Dgeni([mockPackage()]);
injector = dgeni.configureInjector();
te = injector.get('targetEnvironments');
});
describe('addAllowed', function() {
it('should store the target and whether it is active', function() {
te.addAllowed('a', true);
te.addAllowed('b', false);
te.addAllowed('c');
expect(te.isActive('a')).toBe(true);
expect(te.isActive('b')).toBe(false);
expect(te.isActive('c')).toBe(false);
});
});
describe('removeAllowed', function() {
it('should disallow the target', function() {
te.addAllowed('a');
te.addAllowed('b');
te.removeAllowed('b');
expect(te.isActive('a')).toBe(false);
expect(function() { te.isActive('b'); })
.toThrowError('Error accessing target "b". It is not in the list of allowed targets: a');
});
});
describe('activate', function() {
it('should active an already allowed target', function() {
te.addAllowed('a', true);
te.addAllowed('b', false);
te.addAllowed('c');
te.activate('a');
te.activate('b');
te.activate('c');
expect(te.isActive('a')).toBe(true);
expect(te.isActive('b')).toBe(true);
expect(te.isActive('c')).toBe(true);
});
});
describe('deactivate', function() {
it('should deactive an already allowed target', function() {
te.addAllowed('a', true);
te.addAllowed('b', false);
te.addAllowed('c');
te.deactivate('a');
te.deactivate('b');
te.deactivate('c');
expect(te.isActive('a')).toBe(false);
expect(te.isActive('b')).toBe(false);
expect(te.isActive('c')).toBe(false);
});
});
describe('isActive', function() {
it('should return true if the item is allowed and active', function() {
te.addAllowed('a', true);
te.addAllowed('b', false);
expect(te.isActive('a')).toBe(true);
expect(te.isActive('b')).toBe(false);
});
});
describe('hasActive', function() {
it('should return true if there are any active targets', function() {
te.addAllowed('a', true);
te.addAllowed('b', false);
expect(te.hasActive()).toBe(true);
te.deactivate('a');
expect(te.hasActive()).toBe(false);
te.activate('b');
expect(te.hasActive()).toBe(true);
});
});
describe('someActive', function() {
it('should return true if the array of targets passed are all allowed and at least on is active', function() {
te.addAllowed('a', true);
te.addAllowed('b', false);
te.addAllowed('c');
expect(te.someActive(['a'])).toBe(true);
expect(te.someActive(['b'])).toBe(false);
expect(te.someActive(['a', 'b'])).toBe(true);
expect(te.someActive(['b', 'c'])).toBe(false);
expect(te.someActive([])).toBe(false);
expect(function() { te.someActive('d'); })
.toThrowError('Error accessing target "d". It is not in the list of allowed targets: a,b,c');
});
});
});