From e69d9da91b545c9648c19ac3f8a8f62516ded3cd Mon Sep 17 00:00:00 2001 From: Alexey Mulyukin Date: Tue, 10 Dec 2019 15:35:40 +0300 Subject: [PATCH] Fix eslint run on CI Fix all eslint issues Fix tests Update version and docs --- CHANGELOG.md | 8 ++ README.md | 13 ++- lib/detector.js | 6 +- lib/helpers.js | 6 +- lib/jsdoc.js | 90 ++++++++----------- lib/parser.js | 79 ++++++++-------- lib/v3/parser.js | 6 +- package.json | 4 +- test/integration/detector/detector.spec.js | 6 +- test/svelte2/integration/data/data.spec.js | 36 ++++---- .../svelte2/integration/events/events.spec.js | 4 +- .../integration/locations/locations.spec.js | 9 +- .../integration/overall/overall.main.doc.json | 6 ++ test/svelte2/integration/store/store.spec.js | 18 ++-- test/svelte3/integration/bind/bind.spec.js | 4 +- .../components/components.importable.js | 5 +- .../integration/components/components.spec.js | 2 + .../integration/computed/computed.spec.js | 3 + test/svelte3/integration/data/data.spec.js | 15 +++- test/svelte3/integration/data/importable.js | 10 ++- .../svelte3/integration/events/events.spec.js | 1 + .../integration/locations/locations.spec.js | 13 +-- .../integration/methods/methods.spec.js | 11 ++- test/svelte3/integration/refs/refs.spec.js | 2 +- test/svelte3/integration/slots/slots.spec.js | 2 + test/unit/helpers/helpers.spec.js | 17 ++-- test/unit/jsdoc/jsdoc.spec.js | 31 ++++--- 27 files changed, 232 insertions(+), 175 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22cae7f..f6dc3c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to the "svelte-intellisense" extension will be documented in Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. +## [2.3.4] 10.12.2019 + +- [Fixed] Now `keywords` feature correctly supported. + +Thanks to [hontas](https://github.com/hontas) for following changes: + +- [Fixed] Svelte V3: Fix parsing of types for data items, defined by `@type` keyword. + ## [2.3.3] 05.12.2019 Thanks to [hontas](https://github.com/hontas) for following changes: diff --git a/README.md b/README.md index 0e2bd8d..e5371e3 100644 --- a/README.md +++ b/README.md @@ -16,19 +16,27 @@ Generate a JSON documentation for a Svelte file - [Fixed] Svelte V3: Fix parsing issues when anonymous functions are used in event handlers at markup (Issue #18) -## [2.3.2] 02.12.2019 +### [2.3.2] 02.12.2019 Thanks to [hontas](https://github.com/hontas) for following fixes: - [Fixed] Svelte V3: Improve type parsing for properties with default values. - [Fixed] Svelte V3: In some cases `type` property was setup with wrong structure and data, now it fixed. -## [2.3.3] 05.12.2019 +### [2.3.3] 05.12.2019 Thanks to [hontas](https://github.com/hontas) for following changes: - [Added] Svelte V3: Implement component documentation parsing provided by top level comment in HTML markup or in the JS section, marked with `@component` JSDoc attribute. +### [2.3.4] 10.12.2019 + +- [Fixed] Now `keywords` feature correctly supported. + +Thanks to [hontas](https://github.com/hontas) for following changes: + +- [Fixed] Svelte V3: Fix parsing of types for data items, defined by `@type` keyword. + Full changelog of release versions can be found [here](/CHANGELOG.md) ## Install @@ -100,6 +108,7 @@ npm install --save sveltedoc-parser - `'helpers'` - Extract the list of component helpers (_Supported by Svelte 2_). - `'components'` - Extract the list of imported components (_Supported by Svelte 2 and Svelte 3_). - `'description'` - Extract the component description (_Supported by Svelte 2 and Svelte 3_). +- `'keywords'` - Extract the component keywords (_Supported by Svelte 2 and Svelte 3_). - `'events'` - Extract the list of events that fired by this component (_Supported by Svelte 2 and Svelte 3_). - `'slots'` - Extract the list of slots provided by this component (_Supported by Svelte 2 and Svelte 3_). - `'transitions'` - Extract the list of transitions used by this component (_Supported by Svelte 2_). diff --git a/lib/detector.js b/lib/detector.js index b5e5558..7147bb2 100644 --- a/lib/detector.js +++ b/lib/detector.js @@ -4,7 +4,7 @@ const SVELTE_VERSION_2 = 2; const SVELTE_VERSION_3 = 3; function isElseIfWithoutSpaceInTemplate(template) { - return /\{\:elseif\s/gi.test(template); + return /\{:elseif\s/gi.test(template); } function isElseIfWithSpaceInTemplate(template) { @@ -16,11 +16,11 @@ function isRefsIsUsedInTemplate(template) { } function isLetUsedForSlotInTemplate(template) { - return /\slet\:[^=]+=/gi.test(template); + return /\slet:[^=]+=/gi.test(template); } function isContextUsedForScriptBlock(scriptBlock) { - return /\scontext\=/gi.test(scriptBlock.attributes); + return /\scontext=/gi.test(scriptBlock.attributes); } function isExportDefaultUsedInBlock(scriptBlock) { diff --git a/lib/helpers.js b/lib/helpers.js index 135eb72..63546e5 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -23,6 +23,7 @@ function loadFileStructureFromOptions(options) { }; } else { const buffer = fs.readFileSync(options.filename, options.encoding); + return parseFileStructureFromContent(buffer.toString()); } } @@ -32,6 +33,7 @@ function loadFileStructureFromOptions(options) { function extractHtmlBlock(content, blockName, searchStartIndex) { const blockOuterStartIndex = content.indexOf(`<${blockName}`, searchStartIndex); + if (blockOuterStartIndex >= 0) { const blockInnerEndIndex = content.indexOf(``, blockOuterStartIndex + blockName.length + 1); @@ -67,10 +69,12 @@ function extractAllHtmlBlocks(content, blockName) { const blocks = []; let searchResult = extractHtmlBlock(content, blockName); + while (searchResult.block) { blocks.push(searchResult.block); const searchStartIndex = searchResult.block.outerPosition.end; + searchResult = extractHtmlBlock(content, blockName, searchStartIndex); } @@ -88,7 +92,7 @@ function parseFileStructureFromContent(fileContent) { template: fileContent, scripts: scriptBlocksSearchResult.blocks, styles: styleBlocksSearchResult.blocks - } + }; } module.exports = { diff --git a/lib/jsdoc.js b/lib/jsdoc.js index 01d09bd..8708233 100644 --- a/lib/jsdoc.js +++ b/lib/jsdoc.js @@ -5,7 +5,7 @@ const TYPE = '\\{([^\\}]*)\\}'; const PARAM_TYPE = '\\{((?:\\.\\.\\.)?[^\\}]*)=?\\}'; const TYPE_RE = new RegExp(`^\\s*${TYPE}`, 'i'); -const PARAM_RE = new RegExp(`^\\s*(?:${PARAM_TYPE}\\s+)?(?:\\[\\s*(${PARAM_NAME})\\s*(?:=\s*([^\\]]+))?\\]|(${PARAM_NAME}))(?:\\s+(?:\\-\\s+)?(.*))?`, 'i'); +const PARAM_RE = new RegExp(`^\\s*(?:${PARAM_TYPE}\\s+)?(?:\\[\\s*(${PARAM_NAME})\\s*(?:=\\s*([^\\]]+))?\\]|(${PARAM_NAME}))(?:\\s+(?:\\-\\s+)?(.*))?`, 'i'); const RETURN_RE = new RegExp(`^\\s*(${TYPE}\\s+)?-?(.*)`, 'i'); const DEFAULT_TYPE = 'any'; @@ -25,6 +25,7 @@ function parseType(type, param) { function parseJSDocType(typeValue) { typeValue = typeValue.trim(); + if (typeValue.indexOf('|') > -1) { if (typeValue.startsWith('(') && typeValue.endsWith(')')) { typeValue = typeValue.substring(1, typeValue.length - 1).trim(); @@ -33,36 +34,36 @@ function parseJSDocType(typeValue) { const types = typeValue.split('|'); return { - 'kind': 'union', - 'text': typeValue, - 'type': types + kind: 'union', + text: typeValue, + type: types .map(type => parseJSDocType(type)) .filter(type => type != null) - } + }; } if (typeValue.startsWith('\'') && typeValue.endsWith('\'')) { return { - 'kind': 'const', - 'text': typeValue, - 'type': 'string', - 'value': typeValue.substr(1, typeValue.length - 2) - } + kind: 'const', + text: typeValue, + type: 'string', + value: typeValue.substr(1, typeValue.length - 2) + }; } if (typeValue === '*') { return { - 'kind': 'type', - 'text': typeValue, - 'type': DEFAULT_TYPE - } + kind: 'type', + text: typeValue, + type: DEFAULT_TYPE + }; } return { - 'kind': 'type', - 'text': typeValue, - 'type': typeValue - } + kind: 'type', + text: typeValue, + type: typeValue + }; } function parseJSTypeFromValueNode(valueNode) { @@ -72,24 +73,24 @@ function parseJSTypeFromValueNode(valueNode) { if (valueNode.type === 'ArrayExpression') { return { - 'kind': 'type', - 'text': 'Array', - 'type': 'Array' + kind: 'type', + text: 'Array', + type: 'Array' }; } - if (typeof(valueNode) === 'object') { + if (typeof (valueNode) === 'object') { return { - 'kind': 'type', - 'text': 'any', - 'type': 'any' + kind: 'type', + text: 'any', + type: 'any' }; } return { - 'kind': 'type', - 'text': typeof(valueNode), - 'type': typeof(valueNode) + kind: 'type', + text: typeof (valueNode), + type: typeof (valueNode) }; } @@ -110,16 +111,16 @@ function parseTypeKeyword(text) { function parseParamKeyword(text) { const param = { type: { - 'kind': 'type', - 'text': '*', - 'type': DEFAULT_TYPE + kind: 'type', + text: '*', + type: DEFAULT_TYPE }, - name: null, + name: null, optional: false, default: null, description: null }; - + const match = PARAM_RE.exec(text); if (match) { @@ -163,27 +164,6 @@ function parseParamKeyword(text) { } return param; - - if (match) { - if (match[2]) { - param.type = parseJSDocType(match[2]); - } - - if (match[3][0] === '[') { - param.optional = true; - param.name = match[4] || match[3].substring(1, match[3].length - 1); - - if (match[6]) { - param.default = match[6]; - } - } else { - param.name = match[3]; - } - - param.description = match[7]; - } - - return param; } function parseReturnKeyword(text) { @@ -207,4 +187,4 @@ module.exports = { parseJSTypeFromValueNode, DEFAULT_TYPE -}; \ No newline at end of file +}; diff --git a/lib/parser.js b/lib/parser.js index 802591d..1b778d4 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -5,6 +5,8 @@ const path = require('path'); const utils = require('./utils'); const jsdoc = require('./jsdoc'); +const hasOwnProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); + const DEFAULT_OPTIONS = { /** * Flag, indicating that source locations should be extracted from source. @@ -30,17 +32,18 @@ const DEFAULT_OPTIONS = { const SUPPORTED_FEATURES = [ 'name', - 'data', - 'computed', - 'methods', - 'actions', - 'helpers', - 'components', - 'description', - 'events', - 'slots', - 'transitions', - 'refs', + 'data', + 'computed', + 'methods', + 'actions', + 'helpers', + 'components', + 'description', + 'keywords', + 'events', + 'slots', + 'transitions', + 'refs', 'store' ]; @@ -57,7 +60,7 @@ class Parser extends EventEmitter { this.source = options.source; this.features = options.features || SUPPORTED_FEATURES; - if (options.source.hasOwnProperty('script') && options.source.script) { + if (hasOwnProperty(options.source, 'script') && options.source.script) { this.scriptOffset = options.source.scriptOffset || 0; try { @@ -181,7 +184,7 @@ class Parser extends EventEmitter { keywords: entry.keywords }; - if (this.eventsEmmited.hasOwnProperty(event.name)) { + if (hasOwnProperty(this.eventsEmmited, event.name)) { const emitedEvent = this.eventsEmmited[event.name]; if (emitedEvent.parent) { @@ -204,7 +207,7 @@ class Parser extends EventEmitter { return; } else if (property.key.name === 'components') { if (p.value && p.value.type === 'Identifier') { - if (this.imports.hasOwnProperty(p.value.name)) { + if (hasOwnProperty(this.imports, p.value.name)) { // TODO: 3.*, Backward compatibility: Remove this property entry.importPath = this.imports[p.value.name].sourceFilename; entry.value = entry.importPath; @@ -214,8 +217,10 @@ class Parser extends EventEmitter { entry.args = entry.value.params.map((param) => param.name); } else if (property.key.name === 'data') { const typeKeyword = entry.keywords.find(kw => kw.name === 'type'); + if (typeKeyword) { const parsedType = jsdoc.parseTypeKeyword(typeKeyword.description); + if (parsedType) { entry.type = parsedType; } @@ -223,23 +228,23 @@ class Parser extends EventEmitter { // If type can't be pased, but value are suplied, try to parse it if (!entry.type) { - if (entry.hasOwnProperty('value')) { + if (hasOwnProperty(entry, 'value')) { const parsedType = jsdoc.parseJSTypeFromValueNode(entry.value); - + if (parsedType) { entry.type = parsedType; } else { entry.type = { - 'kind': 'type', - 'text': 'any', - 'type': 'any' + kind: 'type', + text: 'any', + type: 'any' }; } } else { entry.type = { - 'kind': 'type', - 'text': 'any', - 'type': 'any' + kind: 'type', + text: 'any', + type: 'any' }; } } @@ -279,7 +284,7 @@ class Parser extends EventEmitter { parseProperty(property) { const propertyValue = utils.value(property); - if (propertyValue.hasOwnProperty('name') && !this.componentName) { + if (hasOwnProperty(propertyValue, 'name') && !this.componentName) { this.componentName = propertyValue.name; return; @@ -292,7 +297,7 @@ class Parser extends EventEmitter { extractProperties(property) { switch (property.value.type) { - case 'FunctionExpression': + case 'FunctionExpression': { const expression = property.value.body.body.find((p) => { return p.type === 'ReturnStatement'; }); @@ -308,6 +313,7 @@ class Parser extends EventEmitter { this.parseProperty(property); break; + } case 'ArrowFunctionExpression': if (property.value.body.type === 'ObjectExpression') { @@ -350,7 +356,7 @@ class Parser extends EventEmitter { process.nextTick(() => { try { this.internalWalk(); - } catch(error) { + } catch (error) { this.emit('failure', error); } }); @@ -398,7 +404,7 @@ class Parser extends EventEmitter { sourceFilename: source.value }; - if (!this.imports.hasOwnProperty(importEntry.identifier)) { + if (!hasOwnProperty(this.imports, importEntry.identifier)) { this.imports[importEntry.identifier] = importEntry; this.emit('import', importEntry); } @@ -421,7 +427,7 @@ class Parser extends EventEmitter { break; case 'Identifier': - if (this.identifiers.hasOwnProperty(body.declaration.name)) { + if (hasOwnProperty(this.identifiers, body.declaration.name)) { this.identifiers[body.declaration.name].properties.forEach((property) => this.extractProperties(property)); } @@ -529,7 +535,7 @@ class Parser extends EventEmitter { if (!event.name) { event.name = '****unhandled-event-name****'; } else { - if (this.eventsEmmited.hasOwnProperty(event.name)) { + if (hasOwnProperty(this.eventsEmmited, event.name)) { const emitedEvent = this.eventsEmmited[event.name]; if (emitedEvent.visibility === 'public') { @@ -603,11 +609,11 @@ class Parser extends EventEmitter { .map(name => ({ name: name.substr(4), parent: tagName, - locations: this.includeSourceLocations && lastAttributeLocations.hasOwnProperty(name) + locations: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, name) ? [lastAttributeLocations[name]] : null, // TODO: Deprication - Remove this property with V3.* - loc: this.includeSourceLocations && lastAttributeLocations.hasOwnProperty(name) + loc: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, name) ? lastAttributeLocations[name] : null })); @@ -645,14 +651,14 @@ class Parser extends EventEmitter { name: nameWithModificators[0], parent: tagName, modificators: nameWithModificators.slice(1), - locations: this.includeSourceLocations && lastAttributeLocations.hasOwnProperty(name) + locations: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, name) ? [lastAttributeLocations[name]] : null, // TODO: Deprication - Remove this property with V3.* - loc: this.includeSourceLocations && lastAttributeLocations.hasOwnProperty(name) + loc: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, name) ? lastAttributeLocations[name] : null - } + }; }); // Expose event firing from template methods @@ -661,6 +667,7 @@ class Parser extends EventEmitter { .map(name => { const value = attrs[name]; const matches = EVENT_EMIT_RE.exec(value); + if (!matches) { return null; } @@ -668,11 +675,11 @@ class Parser extends EventEmitter { return { name: matches[1].substr(1, matches[1].length - 2).trim(), parent: null, - locations: this.includeSourceLocations && lastAttributeLocations.hasOwnProperty(name) + locations: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, name) ? [lastAttributeLocations[name]] : null, // TODO: Deprication - Remove this property with V3.* - loc: this.includeSourceLocations && lastAttributeLocations.hasOwnProperty(name) + loc: this.includeSourceLocations && hasOwnProperty(lastAttributeLocations, name) ? lastAttributeLocations[name] : null }; @@ -693,7 +700,7 @@ class Parser extends EventEmitter { event.description = comment.description || ''; event.keywords = comment.keywords; - if (!this.eventsEmmited.hasOwnProperty(event.name)) { + if (!hasOwnProperty(this.eventsEmmited, event.name)) { this.eventsEmmited[event.name] = event; this.parseKeywords(comment.keywords, event); diff --git a/lib/v3/parser.js b/lib/v3/parser.js index 95be979..d06a93f 100644 --- a/lib/v3/parser.js +++ b/lib/v3/parser.js @@ -13,12 +13,12 @@ const DEFAULT_OPTIONS = {}; const SUPPORTED_FEATURES = [ 'name', - 'keywords', 'data', 'computed', 'methods', 'components', 'description', + 'keywords', 'events', 'slots', 'refs' @@ -237,9 +237,7 @@ class Parser extends EventEmitter { this.emit('description', comment.description); } - if (this.features.includes('keywords')) { - this.emit('keywords', comment.keywords); - } + this.emit('keywords', comment.keywords); } } diff --git a/package.json b/package.json index e3dc303..5736804 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "sveltedoc-parser", - "version": "2.3.3", + "version": "2.3.4", "description": "Generate a JSON documentation for a Svelte file", "main": "index.js", "scripts": { - "lint": "eslint ./*.js", + "lint": "eslint ./**/*.js", "test": "mocha ./test/**/*.spec.js", "test:unit": "mocha ./test/unit/**/*.spec.js", "test:integration": "mocha ./test/**/integration/**/*.spec.js", diff --git a/test/integration/detector/detector.spec.js b/test/integration/detector/detector.spec.js index 5ea1f2e..eea2e2a 100644 --- a/test/integration/detector/detector.spec.js +++ b/test/integration/detector/detector.spec.js @@ -17,6 +17,7 @@ describe('SvelteDoc file version detector', () => { describe('Svelte V2 files check', () => { const folderPath = path.resolve(__dirname, 'v2'); const files = fs.readdirSync(folderPath); + files .filter(file => file.endsWith('.svelte')) .forEach(file => { @@ -31,8 +32,9 @@ describe('SvelteDoc file version detector', () => { }); describe('Svelte V3 files check', () => { - const folderPath = path.resolve(__dirname + '/v3'); + const folderPath = path.resolve(__dirname, 'v3'); const files = fs.readdirSync(folderPath); + files .filter(file => file.endsWith('.svelte')) .forEach(file => { @@ -45,4 +47,4 @@ describe('SvelteDoc file version detector', () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/svelte2/integration/data/data.spec.js b/test/svelte2/integration/data/data.spec.js index ecd25e0..a4cc279 100644 --- a/test/svelte2/integration/data/data.spec.js +++ b/test/svelte2/integration/data/data.spec.js @@ -75,9 +75,9 @@ describe('SvelteDoc - Component data model', () => { expect(firstProperty.name).to.be.equal('inlineTest'); expect(firstProperty.type).to.be.exist; expect(firstProperty.type).to.be.deep.equal({ - 'kind': 'type', - 'text': 'string', - 'type': 'string' + kind: 'type', + text: 'string', + type: 'string' }); expect(firstProperty.visibility).to.be.equal('public'); @@ -86,20 +86,20 @@ describe('SvelteDoc - Component data model', () => { expect(secondProperty.name).to.be.equal('kind'); expect(secondProperty.type).to.be.exist; expect(secondProperty.type).to.be.deep.equal({ - 'kind': 'union', - 'text': '\'white\'|\'black\'', - 'type': [ + kind: 'union', + text: '\'white\'|\'black\'', + type: [ { - 'kind': 'const', - 'text': '\'white\'', - 'type': 'string', - 'value': 'white' + kind: 'const', + text: '\'white\'', + type: 'string', + value: 'white' }, { - 'kind': 'const', - 'text': '\'black\'', - 'type': 'string', - 'value': 'black' + kind: 'const', + text: '\'black\'', + type: 'string', + value: 'black' }, ] }); @@ -127,13 +127,13 @@ describe('SvelteDoc - Component data model', () => { const validatePropertyType = (propertyName, expectedType) => { const property = properties.find(p => p.name === propertyName); - + expect(property, `Data property "${propertyName}" should be exist`).to.be.exist; expect(property.type, `Type property for "${propertyName}" should be exist`).to.be.exist; expect(property.type, `Type property for "${propertyName}" should be parsed`).to.be.deep.equal({ - 'kind': 'type', - 'text': expectedType, - 'type': expectedType + kind: 'type', + text: expectedType, + type: expectedType }); }; diff --git a/test/svelte2/integration/events/events.spec.js b/test/svelte2/integration/events/events.spec.js index f4113ef..ddd1509 100644 --- a/test/svelte2/integration/events/events.spec.js +++ b/test/svelte2/integration/events/events.spec.js @@ -7,11 +7,11 @@ const parser = require('../../../../index'); describe('SvelteDoc - Events', () => { it('Fired events in markup should be parsed', (done) => { parser.parse({ + version: 2, filename: path.resolve(__dirname, 'event.markup.fire.svelte'), features: ['events'], ignoredVisibilities: [] }).then((doc) => { - version: 2, expect(doc, 'Document should be provided').to.exist; expect(doc.events, 'Document events should be parsed').to.exist; @@ -123,7 +123,7 @@ describe('SvelteDoc - Events', () => { expect(event.visibility).to.equal('public'); expect(event.parent).to.be.equal('button'); expect(event.description).to.equal('Event fired when user clicked on button.'); - + expect(event.modificators).to.eql([ 'once', 'preventDefault' ]); diff --git a/test/svelte2/integration/locations/locations.spec.js b/test/svelte2/integration/locations/locations.spec.js index 8e01f29..486225a 100644 --- a/test/svelte2/integration/locations/locations.spec.js +++ b/test/svelte2/integration/locations/locations.spec.js @@ -102,21 +102,24 @@ describe('SvelteDoc - Source locations', () => { ignoredVisibilities: [] }).then((doc) => { expect(doc.events.length).is.equals(3); - const markupPropogatedEvent = doc.events.find(e => e.name === "mousemove"); + const markupPropogatedEvent = doc.events.find(e => e.name === 'mousemove'); + expect(markupPropogatedEvent).is.not.empty; expect(markupPropogatedEvent.loc).is.deep.equals({ start: 44, end: 58 }); - const codeEvent = doc.events.find(e => e.name === "codeEvent"); + const codeEvent = doc.events.find(e => e.name === 'codeEvent'); + expect(codeEvent).is.not.empty; expect(codeEvent.loc).is.deep.equals({ start: 287, end: 298 }); - const markupEvent = doc.events.find(e => e.name === "markupEvent"); + const markupEvent = doc.events.find(e => e.name === 'markupEvent'); + expect(markupEvent).is.not.empty; expect(markupEvent.loc).is.deep.equals({ start: 15, diff --git a/test/svelte2/integration/overall/overall.main.doc.json b/test/svelte2/integration/overall/overall.main.doc.json index 952c115..6c9d622 100644 --- a/test/svelte2/integration/overall/overall.main.doc.json +++ b/test/svelte2/integration/overall/overall.main.doc.json @@ -433,6 +433,12 @@ } ], "description": "The entry-point component for 'Overall' page of Web-Application.", + "keywords": [ + { + "name": "author", + "description": "Alexey Mulyukin" + } + ], "events": [ { "name": "skinChanged", diff --git a/test/svelte2/integration/store/store.spec.js b/test/svelte2/integration/store/store.spec.js index 12a7d22..cbd31ee 100644 --- a/test/svelte2/integration/store/store.spec.js +++ b/test/svelte2/integration/store/store.spec.js @@ -14,10 +14,12 @@ xdescribe('SvelteDoc - Store', () => { }).then((doc) => { expect(doc, 'Document should be provided').to.exist; expect(doc.store, 'Store information should be provided').to.exist; - expect(storeDoc.length).to.equal(1); + const storeDoc = doc.store; + + expect(storeDoc.length).to.equal(1); const storeProperty = storeDoc[0]; - + expect(storeProperty).to.exist; expect(storeProperty.name).to.equal('ApplicationName'); expect(storeProperty.read).is.true; @@ -38,10 +40,12 @@ xdescribe('SvelteDoc - Store', () => { }).then((doc) => { expect(doc, 'Document should be provided').to.exist; expect(doc.store, 'Store information should be provided').to.exist; - expect(storeDoc.length).to.equal(1); + const storeDoc = doc.store; + + expect(storeDoc.length).to.equal(1); const storeProperty = storeDoc[0]; - + expect(storeProperty).to.exist; expect(storeProperty.name).to.equal('ApplicationName'); expect(storeProperty.read).is.false; @@ -62,10 +66,12 @@ xdescribe('SvelteDoc - Store', () => { }).then((doc) => { expect(doc, 'Document should be provided').to.exist; expect(doc.store, 'Store information should be provided').to.exist; - expect(storeDoc.length).to.equal(1); + const storeDoc = doc.store; + + expect(storeDoc.length).to.equal(1); const storeProperty = storeDoc[0]; - + expect(storeProperty).to.exist; expect(storeProperty.name).to.equal('ApplicationName'); expect(storeProperty.read).is.true; diff --git a/test/svelte3/integration/bind/bind.spec.js b/test/svelte3/integration/bind/bind.spec.js index 1a46978..8b27abf 100644 --- a/test/svelte3/integration/bind/bind.spec.js +++ b/test/svelte3/integration/bind/bind.spec.js @@ -108,10 +108,12 @@ describe('SvelteDoc v3 - Bind', () => { expect(item.bind.length, 'Bind should be an array').to.be.equal(2); const bindInput = item.bind.find(b => b.source === 'input'); + expect(bindInput.source).to.equal('input'); expect(bindInput.property).to.equal('value'); const bindControl = item.bind.find(b => b.source === 'PlusMinusControl'); + expect(bindControl.source).to.equal('PlusMinusControl'); expect(bindControl.property).to.equal('numberValue'); @@ -148,4 +150,4 @@ describe('SvelteDoc v3 - Bind', () => { done(e); }); }); -}); \ No newline at end of file +}); diff --git a/test/svelte3/integration/components/components.importable.js b/test/svelte3/integration/components/components.importable.js index 5e8945e..7f8ea95 100644 --- a/test/svelte3/integration/components/components.importable.js +++ b/test/svelte3/integration/components/components.importable.js @@ -1,2 +1,3 @@ -export let X = 1; -export let y = 2; +export const X = 1; + +export const y = 2; diff --git a/test/svelte3/integration/components/components.spec.js b/test/svelte3/integration/components/components.spec.js index 798107b..581990c 100644 --- a/test/svelte3/integration/components/components.spec.js +++ b/test/svelte3/integration/components/components.spec.js @@ -18,6 +18,7 @@ describe('SvelteDoc v3 - Components', () => { expect(doc.components.length).to.equal(1); const component = doc.components[0]; + expect(component.name).to.equal('Nested'); expect(component.value).to.equal('./components.nested.svelte'); expect(component.importPath).to.equal('./components.nested.svelte'); @@ -29,6 +30,7 @@ describe('SvelteDoc v3 - Components', () => { expect(component.locations.length).to.be.equal(1); const location = component.locations[0]; + expect(location, 'Location should be correct identified').is.deep.equals({ start: 53, end: 59 }); done(); diff --git a/test/svelte3/integration/computed/computed.spec.js b/test/svelte3/integration/computed/computed.spec.js index d9b40d5..ff575d4 100644 --- a/test/svelte3/integration/computed/computed.spec.js +++ b/test/svelte3/integration/computed/computed.spec.js @@ -18,6 +18,7 @@ describe('SvelteDoc v3 - Computed', () => { expect(doc.computed.length).to.equal(1); const prop = doc.computed[0]; + expect(prop.name).to.equal('area'); expect(prop.visibility).to.equal('private'); expect(prop.static).to.be.false; @@ -31,6 +32,7 @@ describe('SvelteDoc v3 - Computed', () => { expect(prop.locations.length).to.be.equal(1); const location = prop.locations[0]; + expect(location, 'Location should be correct identified').is.deep.equals({ start: 124, end: 128 }); done(); @@ -51,6 +53,7 @@ describe('SvelteDoc v3 - Computed', () => { expect(doc.computed.length).to.equal(1); const prop = doc.computed[0]; + expect(prop.name).to.equal('area'); expect(prop.visibility).to.equal('private'); expect(prop.static).to.be.false; diff --git a/test/svelte3/integration/data/data.spec.js b/test/svelte3/integration/data/data.spec.js index 4f41cee..bd0c5cc 100644 --- a/test/svelte3/integration/data/data.spec.js +++ b/test/svelte3/integration/data/data.spec.js @@ -18,6 +18,7 @@ describe('SvelteDoc v3 - Props', () => { expect(doc.data.length).to.equal(1); const prop = doc.data[0]; + expect(prop.name).to.equal('variableWithDefault'); expect(prop.visibility).to.equal('private'); expect(prop.static).to.be.false; @@ -31,6 +32,7 @@ describe('SvelteDoc v3 - Props', () => { expect(prop.locations.length).to.be.equal(1); const location = prop.locations[0]; + expect(location, 'Location should be correct identified').is.deep.equals({ start: 84, end: 103 }); done(); @@ -51,6 +53,7 @@ describe('SvelteDoc v3 - Props', () => { expect(doc.data.length).to.equal(2); const variableItem = doc.data.find(item => item.name === 'variable'); + expect(variableItem).to.be.not.null; expect(variableItem.visibility).to.equal('public'); expect(variableItem.static).to.be.false; @@ -59,6 +62,7 @@ describe('SvelteDoc v3 - Props', () => { expect(variableItem.defaultValue).to.equal('hello'); const variableWithCommentItem = doc.data.find(item => item.name === 'propertyWithComment'); + expect(variableWithCommentItem).to.be.not.null; expect(variableWithCommentItem.visibility).to.equal('public'); expect(variableWithCommentItem.static).to.be.false; @@ -84,6 +88,7 @@ describe('SvelteDoc v3 - Props', () => { expect(doc.data.length).to.equal(1); const prop = doc.data[0]; + expect(prop.name).to.equal('staticVariable'); expect(prop.static).to.be.true; @@ -104,7 +109,7 @@ describe('SvelteDoc v3 - Props', () => { expect(doc.data, 'Document events should be parsed').to.exist; expect(doc.data.length).to.equal(3); - + expect(doc.data[0].name).to.equal('a'); expect(doc.data[0].visibility).to.equal('private'); @@ -131,7 +136,7 @@ describe('SvelteDoc v3 - Props', () => { expect(doc.data, 'Document events should be parsed').to.exist; expect(doc.data.length).to.equal(3); - + expect(doc.data[0].name).to.equal('a'); expect(doc.data[0].visibility).to.equal('private'); @@ -160,6 +165,7 @@ describe('SvelteDoc v3 - Props', () => { expect(doc.data.length).to.equal(1); const prop = doc.data[0]; + expect(prop.name).to.equal('x'); expect(prop.originalName).to.equal('x'); expect(prop.importPath).to.equal('./importable.js'); @@ -191,6 +197,7 @@ describe('SvelteDoc v3 - Props', () => { expect(doc.data.length).to.equal(1); const prop = doc.data[0]; + expect(prop.name).to.equal('altY'); expect(prop.originalName).to.equal('y'); expect(prop.importPath).to.equal('./importable.js'); @@ -219,6 +226,7 @@ describe('SvelteDoc v3 - Props', () => { expect(doc.data.length).to.equal(2); const prop1 = doc.data[0]; + expect(prop1.name).to.equal('y'); expect(prop1.visibility).to.equal('private'); expect(prop1.static).to.be.false; @@ -228,6 +236,7 @@ describe('SvelteDoc v3 - Props', () => { expect(prop1.locations[0]).is.deep.equals({ start: 64, end: 65 }); const prop2 = doc.data[1]; + expect(prop2.name).to.equal('z'); expect(prop2.visibility).to.equal('private'); expect(prop2.static).to.be.false; @@ -238,4 +247,4 @@ describe('SvelteDoc v3 - Props', () => { done(e); }); }); -}); \ No newline at end of file +}); diff --git a/test/svelte3/integration/data/importable.js b/test/svelte3/integration/data/importable.js index ccea985..fdb13d9 100644 --- a/test/svelte3/integration/data/importable.js +++ b/test/svelte3/integration/data/importable.js @@ -1,3 +1,7 @@ -export default x = 1; -export let y = 1; -export let z = 1; \ No newline at end of file +const x = 1; + +export default x; + +export const y = 1; + +export const z = 1; diff --git a/test/svelte3/integration/events/events.spec.js b/test/svelte3/integration/events/events.spec.js index 800cd32..bdeabda 100644 --- a/test/svelte3/integration/events/events.spec.js +++ b/test/svelte3/integration/events/events.spec.js @@ -81,6 +81,7 @@ describe('SvelteDoc v3 - Events', () => { expect(event.locations.length).to.be.equal(1); const location = event.locations[0]; + expect(location, 'Location should be correct identified').is.deep.equals({ start: 126, end: 134 }); done(); diff --git a/test/svelte3/integration/locations/locations.spec.js b/test/svelte3/integration/locations/locations.spec.js index fc58484..bcf621d 100644 --- a/test/svelte3/integration/locations/locations.spec.js +++ b/test/svelte3/integration/locations/locations.spec.js @@ -8,6 +8,7 @@ function assertDataItemLocation(dataItem, expectedLocationStart, expectedLocatio expect(dataItem.locations, `Code location for data item should be included for "${dataItem.name}"`).to.be.exist; expect(dataItem.locations.length, `Code location for data item have values for "${dataItem.name}"`).to.be.equal(1); const location = dataItem.locations[0]; + expect(location, `Location should be correct identified for "${dataItem.name}"`).is.deep.equals({ start: expectedLocationStart, end: expectedLocationEnd }); } @@ -23,12 +24,14 @@ describe('SvelteDoc v3 - Locations', () => { expect(doc, 'Document should be provided').to.exist; expect(doc.data, 'Document events should be parsed').to.exist; - const static = doc.data.find(p => p.name === 'staticVariable'); - expect(static, '"staticVariable" should be presented in data items of the doc').to.exist; - expect(static.static).to.be.true; - assertDataItemLocation(static, 79, 93); + const staticVariable = doc.data.find(p => p.name === 'staticVariable'); + + expect(staticVariable, '"staticVariable" should be presented in data items of the doc').to.exist; + expect(staticVariable.static).to.be.true; + assertDataItemLocation(staticVariable, 79, 93); const local = doc.data.find(p => p.name === 'variable'); + expect(local, '"variable" should be presented in data items of the doc').to.exist; expect(local.static).to.be.false; assertDataItemLocation(local, 127, 135); @@ -38,4 +41,4 @@ describe('SvelteDoc v3 - Locations', () => { done(e); }); }); -}); \ No newline at end of file +}); diff --git a/test/svelte3/integration/methods/methods.spec.js b/test/svelte3/integration/methods/methods.spec.js index 00c239e..493bb7e 100644 --- a/test/svelte3/integration/methods/methods.spec.js +++ b/test/svelte3/integration/methods/methods.spec.js @@ -17,7 +17,8 @@ describe('SvelteDoc v3 - Methods', () => { expect(doc.methods, 'Document methods should be parsed').to.exist; expect(doc.methods.length).to.equal(1); - const method = doc.methods[0]; + const method = doc.methods[0]; + expect(method.name).to.equal('privateMethod'); expect(method.visibility).to.equal('private'); expect(method.static).to.be.false; @@ -32,7 +33,8 @@ describe('SvelteDoc v3 - Methods', () => { expect(method.locations, 'Code location should be included').to.be.exist; expect(method.locations.length).to.be.equal(1); - const location = method.locations[0]; + const location = method.locations[0]; + expect(location, 'Location should be correct identified').is.deep.equals({ start: 65, end: 78 }); done(); @@ -52,7 +54,8 @@ describe('SvelteDoc v3 - Methods', () => { expect(doc.methods, 'Document methods should be parsed').to.exist; expect(doc.methods.length).to.equal(1); - const method = doc.methods[0]; + const method = doc.methods[0]; + expect(method.name).to.equal('publicMethod'); expect(method.visibility).to.equal('public'); expect(method.static).to.be.false; @@ -68,4 +71,4 @@ describe('SvelteDoc v3 - Methods', () => { done(e); }); }); -}); \ No newline at end of file +}); diff --git a/test/svelte3/integration/refs/refs.spec.js b/test/svelte3/integration/refs/refs.spec.js index 854e33f..55c6cba 100644 --- a/test/svelte3/integration/refs/refs.spec.js +++ b/test/svelte3/integration/refs/refs.spec.js @@ -76,4 +76,4 @@ describe('SvelteDoc v3 - Refs', () => { done(e); }); }); -}); \ No newline at end of file +}); diff --git a/test/svelte3/integration/slots/slots.spec.js b/test/svelte3/integration/slots/slots.spec.js index 0133ac2..9ea896b 100644 --- a/test/svelte3/integration/slots/slots.spec.js +++ b/test/svelte3/integration/slots/slots.spec.js @@ -46,10 +46,12 @@ describe('SvelteDoc v3 - Slots', () => { expect(slot.visibility).to.equal('public'); const parameters = slot.parameters; + expect(parameters).to.exist; expect(parameters.length).to.equal(1); const parameter = parameters[0]; + expect(parameter).to.exist; expect(parameter.name).to.equal('item'); expect(parameter.visibility).to.equal('public'); diff --git a/test/unit/helpers/helpers.spec.js b/test/unit/helpers/helpers.spec.js index acc4778..c57cb8d 100644 --- a/test/unit/helpers/helpers.spec.js +++ b/test/unit/helpers/helpers.spec.js @@ -1,7 +1,7 @@ const chai = require('chai'); const expect = chai.expect; -const helpers = require("../../../lib/helpers"); +const helpers = require('../../../lib/helpers'); describe('Helpers parser module tests', () => { describe('helpers.extractHtmlBlock', () => { @@ -14,9 +14,10 @@ let variable = 1; `; const result = helpers.extractHtmlBlock(content, 'script'); - + expect(result).is.exist; const block = result.block; + expect(block).is.exist; expect(block.content).is.eq('\nlet variable = 1;\n'); expect(block.offset).is.eq(34); @@ -35,9 +36,10 @@ let variable = 1; `; const result = helpers.extractHtmlBlock(content, 'script'); - + expect(result).is.exist; const block = result.block; + expect(block).is.exist; expect(block.attributes).is.eq(' scope="module"'); }); @@ -57,6 +59,7 @@ let variable = 2; expect(result).is.exist; const block = result.block; + expect(block).is.exist; expect(block.content).is.eq('\nlet variable = 2;\n'); expect(block.offset).is.eq(71); @@ -76,12 +79,13 @@ let variable = 1; `; const result = helpers.extractAllHtmlBlocks(content, 'script'); - + expect(result).is.exist; expect(result.blocks).is.exist; expect(result.blocks.length).is.eq(1); const block = result.blocks[0]; + expect(block).is.exist; expect(block.offset).is.eq(34); expect(block.content).is.eq('\nlet variable = 1;\n'); @@ -99,12 +103,13 @@ let variable = 2; `; const result = helpers.extractAllHtmlBlocks(content, 'script'); - + expect(result).is.exist; expect(result.blocks).is.exist; expect(result.blocks.length).is.eq(2); let block = result.blocks[0]; + expect(block).is.exist; expect(block.offset).is.eq(34); expect(block.content).is.eq('\nlet variable = 1;\n'); @@ -117,4 +122,4 @@ let variable = 2; expect(block.attributes).is.empty; }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/jsdoc/jsdoc.spec.js b/test/unit/jsdoc/jsdoc.spec.js index 1f5b0c8..d9986f3 100644 --- a/test/unit/jsdoc/jsdoc.spec.js +++ b/test/unit/jsdoc/jsdoc.spec.js @@ -1,8 +1,7 @@ -const path = require('path'); const chai = require('chai'); const expect = chai.expect; -const jsdoc = require("../../../lib/jsdoc"); +const jsdoc = require('../../../lib/jsdoc'); describe('JSDoc parser module tests', () => { describe('Parse type keyword', () => { @@ -45,7 +44,7 @@ describe('JSDoc parser module tests', () => { expect(type.kind).is.equal('type'); expect(type.type).is.equal('Array>'); }); - + it('Array with bracet declaration', () => { const type = jsdoc.parseTypeKeyword('{string[]}'); @@ -115,7 +114,7 @@ describe('JSDoc parser module tests', () => { describe('Parse parameter keyword', () => { it('Parameter name should be parsed', () => { const param = jsdoc.parseParamKeyword('{string} parameter'); - + expect(param).is.exist; expect(param.name).is.equal('parameter'); expect(param.optional).is.not.true; @@ -123,7 +122,7 @@ describe('JSDoc parser module tests', () => { it('Description should be parsed', () => { const param = jsdoc.parseParamKeyword('{string} parameter Description'); - + expect(param).is.exist; expect(param.name).is.equal('parameter'); expect(param.description).is.equal('Description'); @@ -132,7 +131,7 @@ describe('JSDoc parser module tests', () => { it('Description with hyphen should be parsed', () => { const param = jsdoc.parseParamKeyword('{string} parameter - Description'); - + expect(param).is.exist; expect(param.name).is.equal('parameter'); expect(param.description).is.equal('Description'); @@ -159,7 +158,7 @@ describe('JSDoc parser module tests', () => { it('Optional parameter name should be parsed', () => { const param = jsdoc.parseParamKeyword('{string} [parameter]'); - + expect(param).is.exist; expect(param.name).is.equal('parameter'); expect(param.default).is.not.exist; @@ -168,7 +167,7 @@ describe('JSDoc parser module tests', () => { it('(Google Closure Compiler syntax) Optional parameter name should be parsed', () => { const param = jsdoc.parseParamKeyword('{string=} parameter'); - + expect(param).is.exist; expect(param.name).is.equal('parameter'); expect(param.default).is.not.exist; @@ -181,7 +180,7 @@ describe('JSDoc parser module tests', () => { it('Optional parameter name with default value should be parsed', () => { const param = jsdoc.parseParamKeyword('{string} [parameter=Default value]'); - + expect(param).is.exist; expect(param.name).is.equal('parameter'); expect(param.default).is.equal('Default value'); @@ -194,7 +193,7 @@ describe('JSDoc parser module tests', () => { it('Parameter without type', () => { const param = jsdoc.parseParamKeyword('parameter'); - + expect(param.name).is.equal('parameter'); expect(param.type).is.exist; expect(param.type.kind).is.equal('type'); @@ -212,7 +211,7 @@ describe('JSDoc parser module tests', () => { it('Any object with star declaration', () => { const param = jsdoc.parseParamKeyword('{*} parameter'); - + expect(param.type).is.exist; expect(param.type.kind).is.equal('type'); expect(param.type.type).is.equal('any'); @@ -249,7 +248,7 @@ describe('JSDoc parser module tests', () => { expect(param.type.kind).is.equal('type'); expect(param.type.type).is.equal('Array>'); }); - + it('Array with bracet declaration', () => { const param = jsdoc.parseParamKeyword('{string[]} parameter'); @@ -304,7 +303,7 @@ describe('JSDoc parser module tests', () => { it('Union of string constants', () => { const param = jsdoc.parseParamKeyword('{\'plain\'|\'primary\'|\'secondary\'|\'plain-inverse\'} parameter'); - + expect(param.type).is.exist; expect(param.type.kind).is.equal('union'); expect(param.type.type.length).is.equal(4); @@ -317,7 +316,7 @@ describe('JSDoc parser module tests', () => { it('Union of string constants with missing quote', () => { const param = jsdoc.parseParamKeyword('{\'plain\'|\'primary\'|secondary\'|\'plain-inverse\'} parameter'); - + expect(param.type).is.exist; expect(param.type.kind).is.equal('union'); expect(param.type.type.length).is.equal(4); @@ -330,8 +329,8 @@ describe('JSDoc parser module tests', () => { it('Union of string constants with figure bracet', () => { const param = jsdoc.parseParamKeyword('{\'plain\'|\'primary\'|\'seco{ndary}\'|\'plain-inverse\'} parameter'); - + expect(param.type).is.exist; }); }); -}); \ No newline at end of file +});