diff --git a/.eslintrc.json b/.eslintrc.json index 6dfe513..93c27ec 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -29,7 +29,8 @@ "_isVueDoc", "_vueProps", "_vueData", - "_vueComputed" + "_vueComputed", + "_vueEvent" ] }] } diff --git a/README.md b/README.md index 78859b8..3065283 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Update your .vue files with one of the following tags: - `@vue-prop` - `@vue-data` - `@vue-computed` +- `@vue-event` All of those tags work the same way than [`@param` tag](http://usejsdoc.org/tags-param.html). diff --git a/__tests__/core/renderer.test.js b/__tests__/core/renderer.test.js index 0ca1081..3fbe905 100644 --- a/__tests__/core/renderer.test.js +++ b/__tests__/core/renderer.test.js @@ -9,7 +9,9 @@ describe('code.renderer', () => { it('should call ejs render method', () => { const cb = () => {}; - renderer('my-template', { props: ['props'], data: ['data'], computed: ['computed'] }, cb); + renderer('my-template', { + props: ['props'], data: ['data'], computed: ['computed'], event: ['event'], + }, cb); expect(ejs.renderFile).toHaveBeenCalledTimes(1); expect(ejs.renderFile).toHaveBeenCalledWith( @@ -18,6 +20,7 @@ describe('code.renderer', () => { props: ['props'], data: ['data'], computed: ['computed'], + event: ['event'], // an helper function, it should be under keys "utils" or "helpers" btw renderType: expect.any(Function), }, diff --git a/cypress/integration/templates/default.spec.js b/cypress/integration/templates/default.spec.js index 656c18f..855bd3c 100644 --- a/cypress/integration/templates/default.spec.js +++ b/cypress/integration/templates/default.spec.js @@ -144,6 +144,39 @@ describe('Template: default', () => { }); }); + it('should renders event correctly', () => { + const events = [ + { name: 'increment', type: 'Number', description: 'Emit value of counter after increment' }, + { name: 'decrement', type: 'Number', description: 'Emit value of counter after decrement' }, + ]; + + cy.get('[data-jsdoc-vuejs="section-event"]').contains('Events'); + cy.get('[data-jsdoc-vuejs="table-event"]').as('table-event'); + + cy + .get('@table-event') + .find('> thead > tr > th') + .contains('Name') + .next().contains('Payload-type') + .next().contains('Description'); + + cy + .get('@table-event') + .find('> tbody > tr') + .then(($rows) => { + expect($rows).to.have.length(3); + + events.forEach((event, i) => { + const $row = $rows.eq(i); + const $children = $row.children(); + + expect($children.eq(0).html()).to.eq(event.name); + expect($children.eq(1).html()).to.eq(event.type); + expect($children.eq(2).html()).to.eq(event.description); + }); + }); + }); + it('should render methods properly', () => { cy.contains('h3', 'Methods').should('have.attr', 'class', 'subsection-title'); diff --git a/example/src/better-components/BetterCounter.vue b/example/src/better-components/BetterCounter.vue index 0c756d4..03e3552 100644 --- a/example/src/better-components/BetterCounter.vue +++ b/example/src/better-components/BetterCounter.vue @@ -19,6 +19,8 @@ * @vue-computed {Array.} fooList - A list of foo * @vue-computed {Array.} barList - A list of bar * @vue-computed {String} message A message + * @vue-event {Number} increment - Emit value of counter after increment + * @vue-event {Number} decrement - Emit value of counter after decrement */ export default { props: { @@ -41,17 +43,19 @@ }, methods: { /** - * Increment counter. + * Increment counter and emit event 'increment' */ increment() { this.counter += this.step; + this.$emit('increment', this.counter); }, /** - * Decrement counter. + * Decrement counter and emit event 'decrement' */ decrement() { this.counter -= this.step; + this.$emit('decrement', this.counter); }, /** diff --git a/index.js b/index.js index 3125777..2205f33 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,7 @@ const { isSingleFileComponent, isJSComponent } = require('./lib/core/issers'); const vueDataTag = require('./lib/tags/vue-data'); const vuePropTag = require('./lib/tags/vue-prop'); const vueComputedTag = require('./lib/tags/vue-computed'); +const vueEventTag = require('./lib/tags/vue-event'); // Used to compute good line number for Vue methods const exportDefaultLines = {}; @@ -22,7 +23,6 @@ exports.handlers = { newDoclet(e) { const fileIsSingleFileComponent = isSingleFileComponent(e.doclet); const fileIsJSComponent = isJSComponent(e.doclet); - if (!fileIsSingleFileComponent && !fileIsJSComponent) { return; } @@ -53,6 +53,7 @@ exports.handlers = { props: e.doclet._vueProps || [], data: e.doclet._vueData || [], computed: e.doclet._vueComputed || [], + event: e.doclet._vueEvent || [], }; render(template, data, (err, str) => { @@ -84,4 +85,5 @@ exports.defineTags = function defineTags(dictionary) { dictionary.defineTag(vueDataTag.name, vueDataTag.options); dictionary.defineTag(vuePropTag.name, vuePropTag.options); dictionary.defineTag(vueComputedTag.name, vueComputedTag.options); + dictionary.defineTag(vueEventTag.name, vueEventTag.options); }; diff --git a/lib/core/renderer.js b/lib/core/renderer.js index d510ff3..c679023 100644 --- a/lib/core/renderer.js +++ b/lib/core/renderer.js @@ -1,7 +1,9 @@ const ejs = require('ejs'); const renderType = require('../templates/utils/renderType'); -module.exports = function render(template, { props, data, computed }, cb) { +module.exports = function render(template, { + props, data, computed, event, +}, cb) { ejs.renderFile( template, { @@ -9,6 +11,7 @@ module.exports = function render(template, { props, data, computed }, cb) { props, data, computed, + event, }, cb, ); diff --git a/lib/tags/vue-event.js b/lib/tags/vue-event.js new file mode 100644 index 0000000..334dc43 --- /dev/null +++ b/lib/tags/vue-event.js @@ -0,0 +1,11 @@ +exports.name = 'vue-event'; + +exports.options = { + canHaveType: true, // type of event-payload + canHaveName: true, // name of emitted event + onTagged(doclet, tag) { + doclet._isVueDoc = true; + doclet._vueEvent = doclet._vueEvent || []; + doclet._vueEvent.push(tag.value || {}); + }, +}; diff --git a/lib/templates/default.ejs b/lib/templates/default.ejs index 6e99f5b..8b24135 100644 --- a/lib/templates/default.ejs +++ b/lib/templates/default.ejs @@ -72,4 +72,27 @@ <% } %> + +<% if(event.length > 0) { %> +

Events

+ + + + + + + + + + <% event.forEach(function(c) { %> + + + + + + <% }) %> + +
NamePayload-typeDescription
<%- c.name %><%- renderType(c.type) %><%- typeof c.description === 'undefined' ? '-' : c.description %>
+<% } %> +

<%# Re-open JSDoc template tags %> diff --git a/lib/templates/docstrap.ejs b/lib/templates/docstrap.ejs index ea57206..0525841 100644 --- a/lib/templates/docstrap.ejs +++ b/lib/templates/docstrap.ejs @@ -72,4 +72,26 @@ <% } %> +<% if(event.length > 0) { %> +

Events

+ + + + + + + + + + <% event.forEach(function(c) { %> + + + + + + <% }) %> + +
NamePayload-typeDescription
<%- c.name %><%- renderType(c.type) %><%- typeof c.description === 'undefined' ? '-' : c.description %>
+<% } %> +

<%# Re-open JSDoc template tags %> diff --git a/lib/templates/minami.ejs b/lib/templates/minami.ejs index 529806b..ed135ec 100644 --- a/lib/templates/minami.ejs +++ b/lib/templates/minami.ejs @@ -72,4 +72,26 @@ <% } %> +<% if(event.length > 0) { %> +

Events

+ + + + + + + + + + <% event.forEach(function(c) { %> + + + + + + <% }) %> + +
NamePayload-typeDescription
<%- c.name %><%- renderType(c.type) %><%- typeof c.description === 'undefined' ? '-' : c.description %>
+<% } %> +

<%# Re-open JSDoc template tags %> diff --git a/lib/templates/tui.ejs b/lib/templates/tui.ejs index 9499013..bc964ef 100644 --- a/lib/templates/tui.ejs +++ b/lib/templates/tui.ejs @@ -91,4 +91,28 @@

<% } %> +<% if(computed.length > 0) { %> +

Events

+
+ + + + + + + + + + <% event.forEach(function(c) { %> + + + + + + <% }) %> + +
NamePayload-typeDescription
<%- c.name %><%- renderType(c.type) %><%- typeof c.description === 'undefined' ? '-' : c.description %>
+
+<% } %> +

<%# Re-open JSDoc template tags %>