Repository: BRIKEV/express-jsdoc-swagger
Pull request #22 (2020-06-03 22:25:25)

Components examples
This PR includes: 

- Components examples.

- Tested more component options.


Patch:
diff --git a/examples/README.md b/examples/README.md
index 4cfc573..6077e94 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -4,7 +4,7 @@ This page will includes some examples on how to use this package.
 
 - [configuration](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/configuration)
 - [responses](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/responses)
-- components - WIP
+- [components](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/components)
 - request body - WIP
 - [parameters](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/parameters)
 - [security](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/security)
diff --git a/examples/components/simple.js b/examples/components/simple.js
new file mode 100644
index 0000000..b0b0de1
--- /dev/null
+++ b/examples/components/simple.js
@@ -0,0 +1,45 @@
+const express = require('express');
+
+const logger = require('../utils/logger');
+const expressJSDocSwagger = require('../..');
+
+const options = {
+  info: {
+    version: '1.0.0',
+    title: 'Albums store',
+    license: {
+      name: 'MIT',
+    },
+  },
+  file: './simple.js',
+  baseDir: __dirname,
+};
+
+const app = express();
+const port = 3000;
+
+expressJSDocSwagger(app)(options);
+
+/**
+ * A song
+ * @typedef {object} Song
+ * @property {string} title.required - The title
+ * @property {string} artist - The artist
+ * @property {number} year - The year - int64
+ */
+
+/**
+ * Author model
+ * @typedef {object} Author
+ * @property {string} name.required - Author name
+ * @property {number} age - Author age - int64
+ */
+
+/**
+ * Album
+ * @typedef {object} Album
+ * @property {Song} firstSong
+ * @property {Author} author
+ */
+
+app.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));
diff --git a/examples/package.json b/examples/package.json
index b0359bf..0247e86 100644
--- a/examples/package.json
+++ b/examples/package.json
@@ -12,7 +12,8 @@
     "responses:multiple": "node responses/multiple.js",
     "responses:components": "node responses/components.js",
     "responses:full-example": "node responses/full-example.js",
-    "security:basic-auth": "node security/basic-auth.js"
+    "security:basic-auth": "node security/basic-auth.js",
+    "components:simple": "node components/simple.js"
   },
   "keywords": [],
   "author": "",
diff --git a/transforms/components/index.js b/transforms/components/index.js
index ccda444..ac0bfd0 100644
--- a/transforms/components/index.js
+++ b/transforms/components/index.js
@@ -12,13 +12,13 @@ const formatProperties = properties => {
   if (!properties || !Array.isArray(properties)) return {};
   return properties.reduce((acum, property) => {
     const name = getPropertyName(property);
-    const propertyName = property.type.name;
-    const [description, format] = property.description.split(' - ');
+    const type = property.type.name;
+    const [description, format] = (property.description || '').split(' - ');
     return {
       ...acum,
       [name]: {
         description,
-        ...refSchema(propertyName),
+        ...refSchema(type),
         ...(format ? { format } : {}),
       },
     };


Test patch:
diff --git a/test/transforms/components/index.test.js b/test/transforms/components/index.test.js
index 7e0b2f1..6c58678 100644
--- a/test/transforms/components/index.test.js
+++ b/test/transforms/components/index.test.js
@@ -256,4 +256,156 @@ describe('parseComponents method', () => {
     const result = parseComponents({}, parsedJSDocs);
     expect(result).toEqual(expected);
   });
+
+  it('Should parse empty string when description is not defined', () => {
+    const jsodInput = [`
+      /**
+       * A song
+       * @typedef {object} Song
+       * @property {string} title.required
+       * @property {string} artist
+       * @property {number} year
+       */
+    `,
+    `
+      /**
+       * Album
+       * @typedef {object} Album
+       * @property {Song} firstSong
+       */
+    `];
+    const expected = {
+      components: {
+        schemas: {
+          Song: {
+            type: 'object',
+            required: [
+              'title',
+            ],
+            description: 'A song',
+            properties: {
+              title: {
+                type: 'string',
+                description: '',
+              },
+              artist: {
+                type: 'string',
+                description: '',
+              },
+              year: {
+                type: 'number',
+                description: '',
+              },
+            },
+          },
+          Album: {
+            type: 'object',
+            required: [],
+            description: 'Album',
+            properties: {
+              firstSong: {
+                $ref: '#/components/schemas/Song',
+                description: '',
+              },
+            },
+          },
+        },
+      },
+    };
+    const parsedJSDocs = jsdocInfo()(jsodInput);
+    const result = parseComponents({}, parsedJSDocs);
+    expect(result).toEqual(expected);
+  });
+
+  it('Should parse two reference for one jsdoc component', () => {
+    const jsodInput = [`
+      /**
+       * A song
+       * @typedef {object} Song
+       * @property {string} title.required - The title
+       * @property {string} artist - The artist
+       * @property {number} year - The year - int64
+       */
+    `,
+    `
+      /**
+       * Author model
+       * @typedef {object} Author
+       * @property {string} name.required - Author name
+       * @property {number} age - Author age - int64
+       */
+    `,
+    `
+      /**
+       * Album
+       * @typedef {object} Album
+       * @property {Song} firstSong
+       * @property {Author} author
+       */
+    `];
+    const expected = {
+      components: {
+        schemas: {
+          Song: {
+            type: 'object',
+            required: [
+              'title',
+            ],
+            description: 'A song',
+            properties: {
+              title: {
+                type: 'string',
+                description: 'The title',
+              },
+              artist: {
+                type: 'string',
+                description: 'The artist',
+              },
+              year: {
+                type: 'number',
+                description: 'The year',
+                format: 'int64',
+              },
+            },
+          },
+          Author: {
+            type: 'object',
+            required: [
+              'name',
+            ],
+            description: 'Author model',
+            properties: {
+              name: {
+                type: 'string',
+                description: 'Author name',
+              },
+              age: {
+                type: 'number',
+                description: 'Author age',
+                format: 'int64',
+              },
+            },
+          },
+          Album: {
+            type: 'object',
+            required: [],
+            description: 'Album',
+            properties: {
+              firstSong: {
+                $ref: '#/components/schemas/Song',
+                description: '',
+              },
+              author: {
+                $ref: '#/components/schemas/Author',
+                description: '',
+              },
+            },
+          },
+        },
+      },
+    };
+    const parsedJSDocs = jsdocInfo()(jsodInput);
+    const result = parseComponents({}, parsedJSDocs);
+    expect(result).toEqual(expected);
+  });
 });