Skip to content

Commit

Permalink
feat(renderers): use a templating system with EJS (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kocal committed Aug 15, 2018
1 parent 21017fc commit 96a3aff
Show file tree
Hide file tree
Showing 24 changed files with 453 additions and 354 deletions.
35 changes: 35 additions & 0 deletions __tests__/core/getTemplatePath.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* eslint-disable no-console */

const getTemplatePath = require('../../lib/core/getTemplatePath');

describe('guessTemplatePath', () => {
test('guess default', () => {
expect(getTemplatePath().endsWith('lib/templates/default.ejs')).toBeTruthy();
expect(getTemplatePath('default').endsWith('lib/templates/default.ejs')).toBeTruthy();
});

test('guess docstrap', () => {
const templatePath = getTemplatePath('./node_modules/ink-docstrap/template');

expect(templatePath.endsWith('lib/templates/docstrap.ejs')).toBeTruthy();
});

test('guess minami', () => {
const templatePath = getTemplatePath('node_modules/minami');

expect(templatePath.endsWith('lib/templates/minami.ejs')).toBeTruthy();
});

test('guess tui', () => {
const templatePath = getTemplatePath('node_modules/tui-jsdoc-template');

expect(templatePath.endsWith('lib/templates/tui.ejs')).toBeTruthy();
});

test('guess unsupported', () => {
console.warn = jest.fn();

expect(getTemplatePath('foo-bar').endsWith('lib/templates/default.ejs')).toBeTruthy();
expect(console.warn).toHaveBeenCalledWith('The template "foo-bar" is not recognized by jsdoc-vuejs. Using default template as fallback.');
});
});
29 changes: 0 additions & 29 deletions __tests__/guessers/guessRenderer.test.js

This file was deleted.

6 changes: 3 additions & 3 deletions config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const config = require('jsdoc/env');
const guessRenderer = require('./lib/core/guessRenderer');
const getTemplatePath = require('./lib/core/getTemplatePath');

config['jsdoc-vuejs'] = config['jsdoc-vuejs'] || {};

// Detect JSDoc template if not specified
if (!Object.prototype.hasOwnProperty.call(config['jsdoc-vuejs'], 'renderer')) {
config['jsdoc-vuejs'].renderer = guessRenderer(config.opts.template || 'default');
if (!Object.prototype.hasOwnProperty.call(config['jsdoc-vuejs'], 'template')) {
config['jsdoc-vuejs'].template = getTemplatePath(config.opts.template || 'default');
}

module.exports = config;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable newline-per-chained-call */

describe('Renderers: default', () => {
describe('Template: default', () => {
before(() => {
cy.visit('/../../../example/docs/module-better-components_BetterCounter.html');
cy.screenshot();
Expand All @@ -19,14 +19,14 @@ describe('Renderers: default', () => {
it('should renders props correctly', () => {
const props = [
{
name: '<b>initialCounter</b>',
name: '<code>initialCounter</code>',
type: 'Number',
defaultValue: '-',
required: '<b>Yes</b>',
description: '-',
},
{
name: '<b>step</b>',
name: '<code>step</code>',
type: 'Number',
defaultValue: '<code>1</code>',
required: 'No',
Expand All @@ -43,7 +43,7 @@ describe('Renderers: default', () => {
.contains('Name')
.next().contains('Type')
.next().contains('Default value')
.next().contains('Required ?')
.next().contains('Required?')
.next().contains('Description');

cy
Expand All @@ -68,7 +68,7 @@ describe('Renderers: default', () => {
it('should renders data correctly', () => {
const data = [
{
name: '<b>counter</b>',
name: '<code>counter</code>',
type: 'Number',
defaultValue: '-',
description: "Current counter's value",
Expand Down Expand Up @@ -106,9 +106,9 @@ describe('Renderers: default', () => {

it('should renders computed correctly', () => {
const computeds = [
{ name: '<b>fooList</b>', type: 'Array.&lt;String&gt;', description: 'A list of foo' },
{ name: '<b>barList</b>', type: 'Array.&lt;String&gt;', description: 'A list of bar' },
{ name: '<b>message</b>', type: 'String', description: 'A message' },
{ name: '<code>fooList</code>', type: 'Array.&lt;String&gt;', description: 'A list of foo' },
{ name: '<code>barList</code>', type: 'Array.&lt;String&gt;', description: 'A list of bar' },
{ name: '<code>message</code>', type: 'String', description: 'A message' },
];

cy.get('[data-jsdoc-vuejs="section-computed"]').contains('Computed');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable newline-per-chained-call */

describe('Renderers: docstrap', () => {
describe('Template: docstrap', () => {
before(() => {
cy.visit('/../../../example/docs-docstrap//module-better-components_BetterCounter.html');
cy.screenshot();
Expand All @@ -19,14 +19,14 @@ describe('Renderers: docstrap', () => {
it('should renders props correctly', () => {
const props = [
{
name: '<b>initialCounter</b>',
name: '<code>initialCounter</code>',
type: 'Number',
defaultValue: '-',
required: '<b>Yes</b>',
description: '-',
},
{
name: '<b>step</b>',
name: '<code>step</code>',
type: 'Number',
defaultValue: '<code>1</code>',
required: 'No',
Expand All @@ -43,7 +43,7 @@ describe('Renderers: docstrap', () => {
.contains('Name')
.next().contains('Type')
.next().contains('Default value')
.next().contains('Required ?')
.next().contains('Required?')
.next().contains('Description');

cy
Expand All @@ -68,7 +68,7 @@ describe('Renderers: docstrap', () => {
it('should renders data correctly', () => {
const data = [
{
name: '<b>counter</b>',
name: '<code>counter</code>',
type: 'Number',
defaultValue: '-',
description: "Current counter's value",
Expand Down Expand Up @@ -106,9 +106,9 @@ describe('Renderers: docstrap', () => {

it('should renders computed correctly', () => {
const computeds = [
{ name: '<b>fooList</b>', type: 'Array.&lt;String&gt;', description: 'A list of foo' },
{ name: '<b>barList</b>', type: 'Array.&lt;String&gt;', description: 'A list of bar' },
{ name: '<b>message</b>', type: 'String', description: 'A message' },
{ name: '<code>fooList</code>', type: 'Array.&lt;String&gt;', description: 'A list of foo' },
{ name: '<code>barList</code>', type: 'Array.&lt;String&gt;', description: 'A list of bar' },
{ name: '<code>message</code>', type: 'String', description: 'A message' },
];

cy.get('[data-jsdoc-vuejs="section-computed"]').contains('Computed').should('have.class', 'subsection-title');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable newline-per-chained-call */

describe('Renderers: minami', () => {
describe('Template: minami', () => {
before(() => {
cy.visit('/../../../example/docs-minami/module-better-components_BetterCounter.html');
cy.screenshot();
Expand All @@ -19,15 +19,15 @@ describe('Renderers: minami', () => {
it('should renders props correctly', () => {
const props = [
{
name: 'initialCounter',
type: 'Number',
name: '<code>initialCounter</code>',
type: '<code>Number</code>',
defaultValue: '-',
required: '<b>Yes</b>',
description: '-',
},
{
name: 'step',
type: 'Number',
name: '<code>step</code>',
type: '<code>Number</code>',
defaultValue: '<code>1</code>',
required: 'No',
description: 'Step',
Expand All @@ -43,7 +43,7 @@ describe('Renderers: minami', () => {
.contains('Name')
.next().contains('Type')
.next().contains('Default value')
.next().contains('Required ?')
.next().contains('Required?')
.next().contains('Description');

cy
Expand All @@ -69,8 +69,8 @@ describe('Renderers: minami', () => {
it('should renders data correctly', () => {
const data = [
{
name: 'counter',
type: 'Number',
name: '<code>counter</code>',
type: '<code>Number</code>',
defaultValue: '-',
description: "Current counter's value",
},
Expand Down Expand Up @@ -107,9 +107,9 @@ describe('Renderers: minami', () => {

it('should renders computed correctly', () => {
const computeds = [
{ name: 'fooList', type: 'Array.&lt;String&gt;', description: 'A list of foo' },
{ name: 'barList', type: 'Array.&lt;String&gt;', description: 'A list of bar' },
{ name: 'message', type: 'String', description: 'A message' },
{ name: '<code>fooList</code>', type: '<code>Array.&lt;String&gt;</code>', description: 'A list of foo' },
{ name: '<code>barList</code>', type: '<code>Array.&lt;String&gt;</code>', description: 'A list of bar' },
{ name: '<code>message</code>', type: '<code>String</code>', description: 'A message' },
];

cy.get('[data-jsdoc-vuejs="section-computed"]').contains('Computed').should('have.class', 'subsection-title');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable newline-per-chained-call */

describe('Renderers: tui', () => {
describe('Template: tui', () => {
before(() => {
cy.visit('/../../../example/docs-tui/module-better-components_BetterCounter.html');
cy.screenshot();
Expand All @@ -23,31 +23,31 @@ describe('Renderers: tui', () => {
it('should renders props correctly', () => {
const props = [
{
name: '<b>initialCounter</b>',
type: 'Number',
name: '<code>initialCounter</code>',
type: '<span class="param-type">Number</span>',
defaultValue: '-',
required: '<b>Yes</b>',
description: '-',
},
{
name: '<b>step</b>',
type: 'Number',
name: '<code>step</code>',
type: '<span class="param-type">Number</span>',
defaultValue: '<code>1</code>',
required: 'No',
description: 'Step',
},
];

cy.get('[data-jsdoc-vuejs="section-props"]').contains('Props').should('have.class', 'subsection-title');
cy.get('[data-jsdoc-vuejs="table-props"]').as('table-props').should('have.class', 'tui-grid-table');
cy.get('[data-jsdoc-vuejs="table-props"]').as('table-props').should('have.class', 'params');

cy
.get('@table-props')
.find('> thead > tr > th')
.contains('Name')
.next().contains('Type')
.next().contains('Default value')
.next().contains('Required ?')
.next().contains('Required?')
.next().contains('Description');

cy
Expand All @@ -72,15 +72,15 @@ describe('Renderers: tui', () => {
it('should renders data correctly', () => {
const data = [
{
name: '<b>counter</b>',
type: 'Number',
name: '<code>counter</code>',
type: '<span class="param-type">Number</span>',
defaultValue: '-',
description: "Current counter's value",
},
];

cy.get('[data-jsdoc-vuejs="section-data"]').contains('Data').should('have.class', 'subsection-title');
cy.get('[data-jsdoc-vuejs="table-data"]').as('table-data').should('have.class', 'tui-grid-table');
cy.get('[data-jsdoc-vuejs="table-data"]').as('table-data').should('have.class', 'params');

cy
.get('@table-data')
Expand Down Expand Up @@ -110,13 +110,13 @@ describe('Renderers: tui', () => {

it('should renders computed correctly', () => {
const computeds = [
{ name: '<b>fooList</b>', type: 'Array.&lt;String&gt;', description: 'A list of foo' },
{ name: '<b>barList</b>', type: 'Array.&lt;String&gt;', description: 'A list of bar' },
{ name: '<b>message</b>', type: 'String', description: 'A message' },
{ name: '<code>fooList</code>', type: '<span class="param-type">Array.&lt;String&gt;</span>', description: 'A list of foo' },
{ name: '<code>barList</code>', type: '<span class="param-type">Array.&lt;String&gt;</span>', description: 'A list of bar' },
{ name: '<code>message</code>', type: '<span class="param-type">String</span>', description: 'A message' },
];

cy.get('[data-jsdoc-vuejs="section-computed"]').contains('Computed').should('have.class', 'subsection-title');
cy.get('[data-jsdoc-vuejs="table-computed"]').as('table-computed').should('have.class', 'tui-grid-table');
cy.get('[data-jsdoc-vuejs="table-computed"]').as('table-computed').should('have.class', 'params');

cy
.get('@table-computed')
Expand Down
16 changes: 11 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,18 @@ exports.handlers = {
// It can be the main doclet before `export default {}`
// with at least one `@vue-*` tag
if (e.doclet._isVueDoc) {
const { renderer } = config['jsdoc-vuejs'];
const props = e.doclet._vueProps || [];
const data = e.doclet._vueData || [];
const computed = e.doclet._vueComputed || [];
const { template } = config['jsdoc-vuejs'];
const data = {
props: e.doclet._vueProps || [],
data: e.doclet._vueData || [],
computed: e.doclet._vueComputed || [],
};

e.doclet.description = render(renderer, e.doclet.description || '', props, data, computed);
render(template, data, (err, str) => {
if (err) throw err;

e.doclet.description = str;
});

// Remove meta for not rendering source for this doclet
delete e.doclet.meta;
Expand Down
25 changes: 25 additions & 0 deletions lib/core/getTemplatePath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const { resolve } = require('path');

module.exports = function getTemplatePath(template) {
// eslint-disable-next-line no-param-reassign
template = template || 'default';

const path = (() => {
switch (true) {
case template === 'default':
return `${__dirname}/../templates/default.ejs`;
case /ink-docstrap\/template/.test(template):
return `${__dirname}/../templates/docstrap.ejs`;
case /minami/.test(template):
return `${__dirname}/../templates/minami.ejs`;
case /tui-jsdoc-template/.test(template):
return `${__dirname}/../templates/tui.ejs`;
default:
// eslint-disable-next-line no-console
console.warn(`The template "${template}" is not recognized by jsdoc-vuejs. Using default template as fallback.`);
return `${__dirname}/../templates/default.ejs`;
}
})();

return resolve(path);
};
Loading

0 comments on commit 96a3aff

Please sign in to comment.