feat(docs-infra): generate Angular CLI command reference (#25363)
PR Close #25363
This commit is contained in:

committed by
Kara Erickson

parent
39a67548ac
commit
f29b218060
@ -0,0 +1,7 @@
|
||||
const shelljs = require('shelljs');
|
||||
const {resolve} = require('canonical-path');
|
||||
const {CONTENTS_PATH} = require('../config');
|
||||
|
||||
shelljs.cd(resolve(CONTENTS_PATH, 'cli-src'));
|
||||
shelljs.exec('git clean -Xfd');
|
||||
shelljs.exec('yarn install');
|
48
aio/tools/transforms/cli-docs-package/index.js
Normal file
48
aio/tools/transforms/cli-docs-package/index.js
Normal file
@ -0,0 +1,48 @@
|
||||
const {resolve} = require('canonical-path');
|
||||
const Package = require('dgeni').Package;
|
||||
const basePackage = require('../angular-base-package');
|
||||
const contentPackage = require('../content-package');
|
||||
const {CONTENTS_PATH, TEMPLATES_PATH, requireFolder} = require('../config');
|
||||
|
||||
|
||||
// Define the dgeni package for generating the docs
|
||||
module.exports = new Package('cli-docs', [basePackage, contentPackage])
|
||||
|
||||
// Register the services and file readers
|
||||
.factory(require('./readers/cli-command'))
|
||||
|
||||
// Register the processors
|
||||
.processor(require('./processors/processCliContainerDoc'))
|
||||
.processor(require('./processors/processCliCommands'))
|
||||
.processor(require('./processors/filterHiddenCommands'))
|
||||
|
||||
// Configure file reading
|
||||
.config(function(readFilesProcessor, cliCommandFileReader) {
|
||||
const CLI_SOURCE_PATH = resolve(CONTENTS_PATH, 'cli-src/node_modules/@angular/cli/help');
|
||||
readFilesProcessor.fileReaders.push(cliCommandFileReader);
|
||||
readFilesProcessor.sourceFiles = readFilesProcessor.sourceFiles.concat([
|
||||
{
|
||||
basePath: CLI_SOURCE_PATH,
|
||||
include: resolve(CLI_SOURCE_PATH, '*.json'),
|
||||
fileReader: 'cliCommandFileReader'
|
||||
},
|
||||
{
|
||||
basePath: CONTENTS_PATH,
|
||||
include: resolve(CONTENTS_PATH, 'cli/**'),
|
||||
fileReader: 'contentFileReader'
|
||||
},
|
||||
]);
|
||||
})
|
||||
|
||||
.config(function(templateFinder, templateEngine, getInjectables) {
|
||||
// Where to find the templates for the CLI doc rendering
|
||||
templateFinder.templateFolders.unshift(resolve(TEMPLATES_PATH, 'cli'));
|
||||
// Add in templating filters and tags
|
||||
templateEngine.filters = templateEngine.filters.concat(getInjectables(requireFolder(__dirname, './rendering')));
|
||||
})
|
||||
|
||||
|
||||
.config(function(convertToJsonProcessor, postProcessHtml) {
|
||||
convertToJsonProcessor.docTypes = convertToJsonProcessor.docTypes.concat(['cli-command', 'cli-overview']);
|
||||
postProcessHtml.docTypes = postProcessHtml.docTypes.concat(['cli-command', 'cli-overview']);
|
||||
});
|
@ -0,0 +1,9 @@
|
||||
module.exports = function filterHiddenCommands() {
|
||||
return {
|
||||
$runAfter: ['files-read'],
|
||||
$runBefore: ['processCliContainerDoc'],
|
||||
$process(docs) {
|
||||
return docs.filter(doc => doc.docType !== 'cli-command' || doc.hidden !== true);
|
||||
}
|
||||
};
|
||||
};
|
@ -0,0 +1,40 @@
|
||||
const testPackage = require('../../helpers/test-package');
|
||||
const processorFactory = require('./filterHiddenCommands');
|
||||
const Dgeni = require('dgeni');
|
||||
|
||||
describe('filterHiddenCommands processor', () => {
|
||||
|
||||
it('should be available on the injector', () => {
|
||||
const dgeni = new Dgeni([testPackage('cli-docs-package')]);
|
||||
const injector = dgeni.configureInjector();
|
||||
const processor = injector.get('filterHiddenCommands');
|
||||
expect(processor.$process).toBeDefined();
|
||||
});
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runAfter).toEqual(['files-read']);
|
||||
});
|
||||
|
||||
it('should run before the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runBefore).toEqual(['processCliContainerDoc']);
|
||||
});
|
||||
|
||||
it('should remove CLI command docs that are hidden', () => {
|
||||
const processor = processorFactory();
|
||||
const filtered = processor.$process([
|
||||
{ docType: 'cli-command', id: 'one' },
|
||||
{ docType: 'cli-command', id: 'two', hidden: true },
|
||||
{ docType: 'cli-command', id: 'three', hidden: false },
|
||||
{ docType: 'other-doc', id: 'four', hidden: true },
|
||||
{ docType: 'other-doc', id: 'five', hidden: false },
|
||||
]);
|
||||
expect(filtered).toEqual([
|
||||
{ docType: 'cli-command', id: 'one' },
|
||||
{ docType: 'cli-command', id: 'three', hidden: false },
|
||||
{ docType: 'other-doc', id: 'four', hidden: true },
|
||||
{ docType: 'other-doc', id: 'five', hidden: false },
|
||||
]);
|
||||
});
|
||||
});
|
@ -0,0 +1,68 @@
|
||||
module.exports = function processCliCommands() {
|
||||
return {
|
||||
$runAfter: ['extra-docs-added'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process(docs) {
|
||||
const navigationDoc = docs.find(doc => doc.docType === 'navigation-json');
|
||||
const navigationNode = navigationDoc && navigationDoc.data['SideNav'].find(node => node.title === 'CLI Commands');
|
||||
|
||||
docs.forEach(doc => {
|
||||
if (doc.docType === 'cli-command') {
|
||||
doc.names = collectNames(doc.name, doc.commandAliases);
|
||||
|
||||
// Recursively process the options
|
||||
processOptions(doc, doc.options);
|
||||
|
||||
// Add to navigation doc
|
||||
if (navigationNode) {
|
||||
navigationNode.children.push({ url: doc.path, title: `ng ${doc.name}` });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function processOptions(container, options) {
|
||||
container.positionalOptions = [];
|
||||
container.namedOptions = [];
|
||||
|
||||
options.forEach(option => {
|
||||
|
||||
if (option.type === 'boolean' && option.default === undefined) {
|
||||
option.default = false;
|
||||
}
|
||||
|
||||
// Ignore any hidden options
|
||||
if (option.hidden) { return; }
|
||||
|
||||
option.types = option.types || [option.type];
|
||||
option.names = collectNames(option.name, option.aliases);
|
||||
|
||||
// Now work out what kind of option it is: positional/named
|
||||
if (option.positional !== undefined) {
|
||||
container.positionalOptions[option.positional] = option;
|
||||
} else {
|
||||
container.namedOptions.push(option);
|
||||
}
|
||||
|
||||
// Recurse if there are subcommands
|
||||
if (option.subcommands) {
|
||||
option.subcommands = getValues(option.subcommands);
|
||||
option.subcommands.forEach(subcommand => {
|
||||
subcommand.names = collectNames(subcommand.name, subcommand.aliases);
|
||||
processOptions(subcommand, subcommand.options);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
container.namedOptions.sort((a, b) => a.name > b.name ? 1 : -1);
|
||||
}
|
||||
|
||||
function collectNames(name, aliases) {
|
||||
return [name].concat(aliases);
|
||||
}
|
||||
|
||||
function getValues(obj) {
|
||||
return Object.keys(obj).map(key => obj[key]);
|
||||
}
|
@ -0,0 +1,264 @@
|
||||
const testPackage = require('../../helpers/test-package');
|
||||
const processorFactory = require('./processCliCommands');
|
||||
const Dgeni = require('dgeni');
|
||||
|
||||
describe('processCliCommands processor', () => {
|
||||
|
||||
it('should be available on the injector', () => {
|
||||
const dgeni = new Dgeni([testPackage('cli-docs-package')]);
|
||||
const injector = dgeni.configureInjector();
|
||||
const processor = injector.get('processCliCommands');
|
||||
expect(processor.$process).toBeDefined();
|
||||
});
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added']);
|
||||
});
|
||||
|
||||
it('should run before the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runBefore).toEqual(['rendering-docs']);
|
||||
});
|
||||
|
||||
it('should collect the names (name + aliases)', () => {
|
||||
const processor = processorFactory();
|
||||
const doc = {
|
||||
docType: 'cli-command',
|
||||
name: 'name',
|
||||
commandAliases: ['alias1', 'alias2'],
|
||||
options: [],
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.names).toEqual(['name', 'alias1', 'alias2']);
|
||||
});
|
||||
|
||||
describe('options', () => {
|
||||
it('should remove the hidden options', () => {
|
||||
const processor = processorFactory();
|
||||
const doc = {
|
||||
docType: 'cli-command',
|
||||
name: 'name',
|
||||
commandAliases: [],
|
||||
options: [
|
||||
{ name: 'option1' },
|
||||
{ name: 'option2', hidden: true },
|
||||
{ name: 'option3' },
|
||||
{ name: 'option4', hidden: true },
|
||||
],
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.namedOptions).toEqual([
|
||||
jasmine.objectContaining({ name: 'option1' }),
|
||||
jasmine.objectContaining({ name: 'option3' }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should collect the non-hidden positional and named options', () => {
|
||||
const processor = processorFactory();
|
||||
const doc = {
|
||||
docType: 'cli-command',
|
||||
name: 'name',
|
||||
commandAliases: [],
|
||||
options: [
|
||||
{ name: 'named1' },
|
||||
{ name: 'positional1', positional: 0},
|
||||
{ name: 'named2', hidden: true },
|
||||
{ name: 'positional2', hidden: true, positional: 1},
|
||||
],
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.positionalOptions).toEqual([
|
||||
jasmine.objectContaining({ name: 'positional1', positional: 0}),
|
||||
]);
|
||||
expect(doc.namedOptions).toEqual([
|
||||
jasmine.objectContaining({ name: 'named1' }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should sort the named options into order by name', () => {
|
||||
const processor = processorFactory();
|
||||
const doc = {
|
||||
docType: 'cli-command',
|
||||
name: 'name',
|
||||
commandAliases: [],
|
||||
options: [
|
||||
{ name: 'c' },
|
||||
{ name: 'a' },
|
||||
{ name: 'b' },
|
||||
],
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.namedOptions).toEqual([
|
||||
jasmine.objectContaining({ name: 'a' }),
|
||||
jasmine.objectContaining({ name: 'b' }),
|
||||
jasmine.objectContaining({ name: 'c' }),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('subcommands', () => {
|
||||
it('should convert subcommands hash into a collection', () => {
|
||||
const processor = processorFactory();
|
||||
const doc = {
|
||||
docType: 'cli-command',
|
||||
name: 'name',
|
||||
commandAliases: [],
|
||||
options: [{
|
||||
name: 'supercommand',
|
||||
subcommands: {
|
||||
subcommand1: {
|
||||
name: 'subcommand1',
|
||||
options: [
|
||||
{ name: 'subcommand1-option1' },
|
||||
{ name: 'subcommand1-option2' },
|
||||
],
|
||||
},
|
||||
subcommand2: {
|
||||
name: 'subcommand2',
|
||||
options: [
|
||||
{ name: 'subcommand2-option1' },
|
||||
{ name: 'subcommand2-option2' },
|
||||
],
|
||||
}
|
||||
},
|
||||
}],
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.options[0].subcommands).toEqual([
|
||||
jasmine.objectContaining({ name: 'subcommand1' }),
|
||||
jasmine.objectContaining({ name: 'subcommand2' }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should remove the hidden subcommand options', () => {
|
||||
const processor = processorFactory();
|
||||
const doc = {
|
||||
docType: 'cli-command',
|
||||
name: 'name',
|
||||
commandAliases: [],
|
||||
options: [{
|
||||
name: 'supercommand',
|
||||
subcommands: {
|
||||
subcommand1: {
|
||||
name: 'subcommand1',
|
||||
options: [
|
||||
{ name: 'subcommand1-option1' },
|
||||
{ name: 'subcommand1-option2', hidden: true },
|
||||
],
|
||||
},
|
||||
subcommand2: {
|
||||
name: 'subcommand2',
|
||||
options: [
|
||||
{ name: 'subcommand2-option1', hidden: true },
|
||||
{ name: 'subcommand2-option2' },
|
||||
],
|
||||
}
|
||||
},
|
||||
}],
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.options[0].subcommands[0].namedOptions).toEqual([
|
||||
jasmine.objectContaining({ name: 'subcommand1-option1' }),
|
||||
]);
|
||||
expect(doc.options[0].subcommands[1].namedOptions).toEqual([
|
||||
jasmine.objectContaining({ name: 'subcommand2-option2' }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should collect the non-hidden positional arguments and named options', () => {
|
||||
const processor = processorFactory();
|
||||
const doc = {
|
||||
docType: 'cli-command',
|
||||
name: 'name',
|
||||
commandAliases: [],
|
||||
options: [{
|
||||
name: 'supercommand',
|
||||
subcommands: {
|
||||
subcommand1: {
|
||||
name: 'subcommand1',
|
||||
options: [
|
||||
{ name: 'subcommand1-option1' },
|
||||
{ name: 'subcommand1-option2', positional: 0 },
|
||||
],
|
||||
},
|
||||
subcommand2: {
|
||||
name: 'subcommand2',
|
||||
options: [
|
||||
{ name: 'subcommand2-option1', hidden: true },
|
||||
{ name: 'subcommand2-option2', hidden: true, positional: 1 },
|
||||
],
|
||||
}
|
||||
},
|
||||
}],
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.options[0].subcommands[0].positionalOptions).toEqual([
|
||||
jasmine.objectContaining({ name: 'subcommand1-option2', positional: 0}),
|
||||
]);
|
||||
expect(doc.options[0].subcommands[0].namedOptions).toEqual([
|
||||
jasmine.objectContaining({ name: 'subcommand1-option1' }),
|
||||
]);
|
||||
|
||||
expect(doc.options[0].subcommands[1].positionalOptions).toEqual([]);
|
||||
expect(doc.options[0].subcommands[1].namedOptions).toEqual([]);
|
||||
});
|
||||
|
||||
it('should sort the named subcommand options into order by name', () => {
|
||||
const processor = processorFactory();
|
||||
const doc = {
|
||||
docType: 'cli-command',
|
||||
name: 'name',
|
||||
commandAliases: [],
|
||||
options: [{
|
||||
name: 'supercommand',
|
||||
subcommands: {
|
||||
subcommand1: {
|
||||
name: 'subcommand1',
|
||||
options: [
|
||||
{ name: 'c' },
|
||||
{ name: 'a' },
|
||||
{ name: 'b' },
|
||||
]
|
||||
}
|
||||
}
|
||||
}],
|
||||
};
|
||||
processor.$process([doc]);
|
||||
expect(doc.options[0].subcommands[0].namedOptions).toEqual([
|
||||
jasmine.objectContaining({ name: 'a' }),
|
||||
jasmine.objectContaining({ name: 'b' }),
|
||||
jasmine.objectContaining({ name: 'c' }),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should add the command to the CLI node in the navigation doc', () => {
|
||||
const processor = processorFactory();
|
||||
const command = {
|
||||
docType: 'cli-command',
|
||||
name: 'command1',
|
||||
commandAliases: ['alias1', 'alias2'],
|
||||
options: [],
|
||||
path: 'cli/command1',
|
||||
};
|
||||
const navigation = {
|
||||
docType: 'navigation-json',
|
||||
data: {
|
||||
SideNav: [
|
||||
{ url: 'some/page', title: 'Some Page' },
|
||||
{ url: 'cli', title: 'CLI Commands', children: [
|
||||
{ url: 'cli', title: 'Using the CLI' },
|
||||
]},
|
||||
{ url: 'other/page', title: 'Other Page' },
|
||||
]
|
||||
}
|
||||
};
|
||||
processor.$process([command, navigation]);
|
||||
expect(navigation.data.SideNav[1].title).toEqual('CLI Commands');
|
||||
expect(navigation.data.SideNav[1].children).toEqual([
|
||||
{ url: 'cli', title: 'Using the CLI' },
|
||||
{ url: 'cli/command1', title: 'ng command1' },
|
||||
]);
|
||||
});
|
||||
});
|
@ -0,0 +1,11 @@
|
||||
module.exports = function processCliContainerDoc() {
|
||||
return {
|
||||
$runAfter: ['extra-docs-added'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process(docs) {
|
||||
const cliDoc = docs.find(doc => doc.id === 'cli/index');
|
||||
cliDoc.id = 'cli-container';
|
||||
cliDoc.commands = docs.filter(doc => doc.docType === 'cli-command');
|
||||
}
|
||||
};
|
||||
};
|
@ -0,0 +1,23 @@
|
||||
const testPackage = require('../../helpers/test-package');
|
||||
const processorFactory = require('./processCliContainerDoc');
|
||||
const Dgeni = require('dgeni');
|
||||
|
||||
describe('processCliContainerDoc processor', () => {
|
||||
|
||||
it('should be available on the injector', () => {
|
||||
const dgeni = new Dgeni([testPackage('cli-docs-package')]);
|
||||
const injector = dgeni.configureInjector();
|
||||
const processor = injector.get('processCliContainerDoc');
|
||||
expect(processor.$process).toBeDefined();
|
||||
});
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added']);
|
||||
});
|
||||
|
||||
it('should run before the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runBefore).toEqual(['rendering-docs']);
|
||||
});
|
||||
});
|
47
aio/tools/transforms/cli-docs-package/readers/cli-command.js
Normal file
47
aio/tools/transforms/cli-docs-package/readers/cli-command.js
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* This file reader will pull the contents from a cli command json file
|
||||
*
|
||||
* The doc will initially have the form:
|
||||
* ```
|
||||
* {
|
||||
* startingLine: 1,
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
module.exports = function cliCommandFileReader(log) {
|
||||
const json5 = require('json5');
|
||||
return {
|
||||
name: 'cliCommandFileReader',
|
||||
defaultPattern: /\.json$/,
|
||||
getDocs(fileInfo) {
|
||||
try {
|
||||
const doc = json5.parse(fileInfo.content);
|
||||
const name = fileInfo.baseName;
|
||||
const path = `cli/${name}`;
|
||||
// We return a single element array because content files only contain one document
|
||||
const result = Object.assign(doc, {
|
||||
content: doc.description,
|
||||
docType: 'cli-command',
|
||||
startingLine: 1,
|
||||
id: `cli-${doc.name}`,
|
||||
commandAliases: doc.aliases || [],
|
||||
aliases: computeAliases(doc),
|
||||
path,
|
||||
outputPath: `${path}.json`,
|
||||
breadCrumbs: [
|
||||
{ text: 'CLI', path: 'cli' },
|
||||
{ text: name, path },
|
||||
]
|
||||
});
|
||||
return [result];
|
||||
} catch (e) {
|
||||
log.warn(`Failed to read cli command file: "${fileInfo.relativePath}" - ${e.message}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function computeAliases(doc) {
|
||||
return [doc.name].concat(doc.aliases || []).map(alias => `cli-${alias}`);
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
const cliCommandReaderFactory = require('./cli-command');
|
||||
const reader = cliCommandReaderFactory();
|
||||
|
||||
const content = `
|
||||
{
|
||||
"name": "add",
|
||||
"description": "Add support for a library to your project.",
|
||||
"longDescription": "Add support for a library in your project, for example adding \`@angular/pwa\` which would configure\\nyour project for PWA support.\\n",
|
||||
"hidden": false,
|
||||
"type": "custom",
|
||||
"options": [
|
||||
{
|
||||
"name": "collection",
|
||||
"description": "The package to be added.",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"aliases": [],
|
||||
"hidden": false,
|
||||
"positional": 0
|
||||
},
|
||||
{
|
||||
"name": "help",
|
||||
"description": "Shows a help message.",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"aliases": [],
|
||||
"hidden": false
|
||||
},
|
||||
{
|
||||
"name": "helpJson",
|
||||
"description": "Shows the metadata associated with each flags, in JSON format.",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"aliases": [],
|
||||
"hidden": false
|
||||
}
|
||||
],
|
||||
"aliases": ['a'],
|
||||
"scope": "in"
|
||||
}
|
||||
`;
|
||||
|
||||
const fileInfo = {content, baseName: 'add'};
|
||||
|
||||
describe('cli-command reader', () => {
|
||||
describe('getDocs', () => {
|
||||
it('should return an array containing a single doc', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return a cli-command doc', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0]).toEqual(jasmine.objectContaining({
|
||||
id: 'cli-add',
|
||||
docType: 'cli-command',
|
||||
}));
|
||||
});
|
||||
|
||||
it('should extract the name from the fileInfo', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].name).toEqual('add');
|
||||
});
|
||||
|
||||
it('should compute the id and aliases', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].id).toEqual('cli-add');
|
||||
expect(docs[0].aliases).toEqual(['cli-add', 'cli-a']);
|
||||
});
|
||||
|
||||
it('should compute the path and outputPath', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].path).toEqual('cli/add');
|
||||
expect(docs[0].outputPath).toEqual('cli/add.json');
|
||||
});
|
||||
|
||||
it('should compute the bread crumbs', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].breadCrumbs).toEqual([
|
||||
{ text: 'CLI', path: 'cli' },
|
||||
{ text: 'add', path: 'cli/add' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should start at line 1', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].startingLine).toEqual(1);
|
||||
});
|
||||
|
||||
it('should extract the short description into the content', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].content).toEqual('Add support for a library to your project.');
|
||||
});
|
||||
|
||||
it('should extract the long description', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].longDescription).toEqual('Add support for a library in your project, for example adding `@angular/pwa` which would configure\nyour project for PWA support.\n');
|
||||
});
|
||||
|
||||
it('should extract the command type', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].type).toEqual('custom');
|
||||
});
|
||||
|
||||
it('should extract the command scope', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].scope).toEqual('in');
|
||||
});
|
||||
|
||||
it('should extract the command aliases', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].commandAliases).toEqual(['a']);
|
||||
});
|
||||
|
||||
it('should extract the options', () => {
|
||||
const docs = reader.getDocs(fileInfo);
|
||||
expect(docs[0].options).toEqual([
|
||||
jasmine.objectContaining({ name: 'collection' }),
|
||||
jasmine.objectContaining({ name: 'help' }),
|
||||
jasmine.objectContaining({ name: 'helpJson' }),
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,6 @@
|
||||
module.exports = function cliNegate() {
|
||||
return {
|
||||
name: 'cliNegate',
|
||||
process: function(str) { return 'no' + str.charAt(0).toUpperCase() + str.slice(1); }
|
||||
};
|
||||
};
|
@ -0,0 +1,17 @@
|
||||
var factory = require('./cliNegate');
|
||||
|
||||
describe('cliNegate filter', function() {
|
||||
var filter;
|
||||
|
||||
beforeEach(function() { filter = factory(); });
|
||||
|
||||
it('should be called "cliNegate"', function() { expect(filter.name).toEqual('cliNegate'); });
|
||||
|
||||
it('should make the first char uppercase and add `no` to the front', function() {
|
||||
expect(filter.process('abc')).toEqual('noAbc');
|
||||
});
|
||||
|
||||
it('should make leave the rest of the chars alone', function() {
|
||||
expect(filter.process('abCdE')).toEqual('noAbCdE');
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user