diff --git a/README.md b/README.md index 1e44996f3..16dfab7aa 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,7 @@ This repository is a monorepo. It contains multiple npm packages. | [`@ckeditor/ckeditor5-dev-utils`](/packages/ckeditor5-dev-utils) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-utils.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-utils) | | [`@ckeditor/ckeditor5-dev-translations`](/packages/ckeditor5-dev-translations) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-translations.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-translations) | | [`@ckeditor/ckeditor5-dev-web-crawler`](/packages/ckeditor5-dev-web-crawler) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-dev-web-crawler.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-web-crawler) | -| [`@ckeditor/jsdoc-plugins`](/packages/jsdoc-plugins) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Fjsdoc-plugins.svg)](https://www.npmjs.com/package/@ckeditor/jsdoc-plugins) | -| [`@ckeditor/typedoc-plugins`](/packages/typedoc-plugins) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Ftypedoc-plugins.svg)](https://www.npmjs.com/package/@ckeditor/jsdoc-plugins) | +| [`@ckeditor/typedoc-plugins`](/packages/typedoc-plugins) | [![npm version](https://badge.fury.io/js/%40ckeditor%2Ftypedoc-plugins.svg)](https://www.npmjs.com/package/@ckeditor/typedoc-plugins) | ## Cloning diff --git a/packages/ckeditor5-dev-docs/lib/build.js b/packages/ckeditor5-dev-docs/lib/build.js index dc6932645..b920fe6e1 100644 --- a/packages/ckeditor5-dev-docs/lib/build.js +++ b/packages/ckeditor5-dev-docs/lib/build.js @@ -3,49 +3,96 @@ * For licensing, see LICENSE.md. */ +import glob from 'fast-glob'; +import TypeDoc from 'typedoc'; +import typedocPlugins from '@ckeditor/typedoc-plugins'; + +import validators from './validators/index.js'; + /** - * Builds CKEditor 5 documentation. + * Builds CKEditor 5 documentation using `typedoc`. * - * @param {JSDocConfig|TypedocConfig} config + * @param {TypedocConfig} config * @returns {Promise} */ export default async function build( config ) { - const type = config.type || 'jsdoc'; - - if ( type === 'jsdoc' ) { - return ( await import( './buildjsdoc.js' ) ).default( config ); - } else if ( type === 'typedoc' ) { - return ( await import( './buildtypedoc.js' ) ).default( config ); - } else { - throw new Error( `Unknown documentation tool (${ type }).` ); + const { plugins } = typedocPlugins; + const sourceFilePatterns = config.sourceFiles.filter( Boolean ); + const strictMode = config.strict || false; + const extraPlugins = config.extraPlugins || []; + const validatorOptions = config.validatorOptions || {}; + + const files = await glob( sourceFilePatterns ); + const typeDoc = new TypeDoc.Application(); + + typeDoc.options.addReader( new TypeDoc.TSConfigReader() ); + typeDoc.options.addReader( new TypeDoc.TypeDocReader() ); + + typeDoc.bootstrap( { + tsconfig: config.tsconfig, + excludeExternals: true, + entryPoints: files, + logLevel: 'Warn', + basePath: config.cwd, + blockTags: [ + '@eventName', + '@default' + ], + inlineTags: [ + '@link', + '@glink' + ], + modifierTags: [ + '@publicApi', + '@skipSource', + '@internal' + ], + plugin: [ + // Fixes `"name": 'default" in the output project. + 'typedoc-plugin-rename-defaults', + + plugins[ 'typedoc-plugin-module-fixer' ], + plugins[ 'typedoc-plugin-symbol-fixer' ], + plugins[ 'typedoc-plugin-interface-augmentation-fixer' ], + plugins[ 'typedoc-plugin-tag-error' ], + plugins[ 'typedoc-plugin-tag-event' ], + plugins[ 'typedoc-plugin-tag-observable' ], + plugins[ 'typedoc-plugin-purge-private-api-docs' ], + + // The `event-inheritance-fixer` plugin must be loaded after `tag-event` plugin, as it depends on its output. + plugins[ 'typedoc-plugin-event-inheritance-fixer' ], + + // The `event-param-fixer` plugin must be loaded after `tag-event` and `tag-observable` plugins, as it depends on their output. + plugins[ 'typedoc-plugin-event-param-fixer' ], + + ...extraPlugins + ] + } ); + + console.log( 'Typedoc started...' ); + + const conversionResult = typeDoc.convert(); + + if ( !conversionResult ) { + throw 'Something went wrong with TypeDoc.'; } -} -/** - * @typedef {Object} JSDocConfig - * - * @property {'jsdoc'} type - * - * @property {Array.} sourceFiles Glob pattern with source files. - * - * @property {String} readmePath Path to `README.md`. - * - * @property {Boolean} [validateOnly=false] Whether JSDoc should only validate the documentation and finish - * with error code `1`. If not passed, the errors will be printed to the console but the task will finish with `0`. - * - * @property {Boolean} [strict=false] If `true`, errors found during the validation will finish the process - * and exit code will be changed to `1`. - * - * @property {String} [outputPath='docs/api/output.json'] A path to the place where extracted doclets will be saved. - * - * @property {String} [extraPlugins=[]] An array of path to extra plugins that will be added to JSDoc. - */ + const validationResult = validators.validate( conversionResult, typeDoc, validatorOptions ); + + if ( !validationResult && strictMode ) { + throw 'Something went wrong with TypeDoc.'; + } + + if ( config.outputPath ) { + await typeDoc.generateJson( conversionResult, config.outputPath ); + } + + console.log( `Documented ${ files.length } files!` ); +} /** * @typedef {Object} TypedocConfig * - * @property {'typedoc'} type - * * @property {Object} config * * @property {String} cwd diff --git a/packages/ckeditor5-dev-docs/lib/buildjsdoc.js b/packages/ckeditor5-dev-docs/lib/buildjsdoc.js deleted file mode 100644 index def803965..000000000 --- a/packages/ckeditor5-dev-docs/lib/buildjsdoc.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import { createRequire } from 'module'; -import fs from 'fs-extra'; -import tmp from 'tmp'; -import glob from 'fast-glob'; -import { tools } from '@ckeditor/ckeditor5-dev-utils'; - -const require = createRequire( import.meta.url ); - -/** - * Builds CKEditor 5 documentation using `jsdoc`. - * - * @param {JSDocConfig} config - * @returns {Promise} - */ -export default async function build( config ) { - const sourceFilePatterns = [ - config.readmePath, - ...config.sourceFiles - ]; - - const extraPlugins = config.extraPlugins || []; - const outputPath = config.outputPath || 'docs/api/output.json'; - const validateOnly = config.validateOnly || false; - const strictCheck = config.strict || false; - - // Pass options to plugins via env variables. - // Since plugins are added using `require` calls other forms are currently impossible. - process.env.JSDOC_OUTPUT_PATH = outputPath; - - if ( validateOnly ) { - process.env.JSDOC_VALIDATE_ONLY = 'true'; - } - - if ( strictCheck ) { - process.env.JSDOC_STRICT_CHECK = 'true'; - } - - const files = await glob( sourceFilePatterns ); - - const jsDocConfig = { - plugins: [ - require.resolve( 'jsdoc/plugins/markdown' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/purge-private-api-docs' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/export-fixer/export-fixer' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/custom-tags/error' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/custom-tags/observable' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/observable-event-provider' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/longname-fixer/longname-fixer' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/fix-code-snippets' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/relation-fixer' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/event-extender/event-extender' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/cleanup' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/validator/validator' ), - require.resolve( '@ckeditor/jsdoc-plugins/lib/utils/doclet-logger' ), - ...extraPlugins - ], - source: { - include: files - }, - opts: { - encoding: 'utf8', - recurse: true, - access: 'all', - template: 'templates/silent' - } - }; - - const tmpConfig = tmp.fileSync(); - - await fs.writeFile( tmpConfig.name, JSON.stringify( jsDocConfig ) ); - - console.log( 'JSDoc started...' ); - - try { - // Not so beautiful API as for 2020... - // See more in https://github.com/jsdoc/jsdoc/issues/938. - const cmd = require.resolve( 'jsdoc/jsdoc.js' ); - - // The `node` command is used for explicitly needed for Windows. - // See https://github.com/ckeditor/ckeditor5/issues/7212. - tools.shExec( `node ${ cmd } -c ${ tmpConfig.name }`, { verbosity: 'info' } ); - } catch ( error ) { - console.error( 'An error was thrown by JSDoc:' ); - - throw error; - } - - console.log( `Documented ${ files.length } files!` ); -} diff --git a/packages/ckeditor5-dev-docs/lib/buildtypedoc.js b/packages/ckeditor5-dev-docs/lib/buildtypedoc.js deleted file mode 100644 index e952b2cbd..000000000 --- a/packages/ckeditor5-dev-docs/lib/buildtypedoc.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import glob from 'fast-glob'; -import TypeDoc from 'typedoc'; -import typedocPlugins from '@ckeditor/typedoc-plugins'; - -import validators from './validators/index.js'; - -/** - * Builds CKEditor 5 documentation using `typedoc`. - * - * @param {TypedocConfig} config - * @returns {Promise} - */ -export default async function build( config ) { - const { plugins } = typedocPlugins; - const sourceFilePatterns = config.sourceFiles.filter( Boolean ); - const strictMode = config.strict || false; - const extraPlugins = config.extraPlugins || []; - const validatorOptions = config.validatorOptions || {}; - - const files = await glob( sourceFilePatterns ); - const typeDoc = new TypeDoc.Application(); - - typeDoc.options.addReader( new TypeDoc.TSConfigReader() ); - typeDoc.options.addReader( new TypeDoc.TypeDocReader() ); - - typeDoc.bootstrap( { - tsconfig: config.tsconfig, - excludeExternals: true, - entryPoints: files, - logLevel: 'Warn', - basePath: config.cwd, - blockTags: [ - '@eventName', - '@default' - ], - inlineTags: [ - '@link', - '@glink' - ], - modifierTags: [ - '@publicApi', - '@skipSource', - '@internal' - ], - plugin: [ - // Fixes `"name": 'default" in the output project. - 'typedoc-plugin-rename-defaults', - - plugins[ 'typedoc-plugin-module-fixer' ], - plugins[ 'typedoc-plugin-symbol-fixer' ], - plugins[ 'typedoc-plugin-interface-augmentation-fixer' ], - plugins[ 'typedoc-plugin-tag-error' ], - plugins[ 'typedoc-plugin-tag-event' ], - plugins[ 'typedoc-plugin-tag-observable' ], - plugins[ 'typedoc-plugin-purge-private-api-docs' ], - - // The `event-inheritance-fixer` plugin must be loaded after `tag-event` plugin, as it depends on its output. - plugins[ 'typedoc-plugin-event-inheritance-fixer' ], - - // The `event-param-fixer` plugin must be loaded after `tag-event` and `tag-observable` plugins, as it depends on their output. - plugins[ 'typedoc-plugin-event-param-fixer' ], - - ...extraPlugins - ] - } ); - - console.log( 'Typedoc started...' ); - - const conversionResult = typeDoc.convert(); - - if ( !conversionResult ) { - throw 'Something went wrong with TypeDoc.'; - } - - const validationResult = validators.validate( conversionResult, typeDoc, validatorOptions ); - - if ( !validationResult && strictMode ) { - throw 'Something went wrong with TypeDoc.'; - } - - if ( config.outputPath ) { - await typeDoc.generateJson( conversionResult, config.outputPath ); - } - - console.log( `Documented ${ files.length } files!` ); -} diff --git a/packages/ckeditor5-dev-docs/package.json b/packages/ckeditor5-dev-docs/package.json index 38f278950..bd214341d 100644 --- a/packages/ckeditor5-dev-docs/package.json +++ b/packages/ckeditor5-dev-docs/package.json @@ -23,11 +23,9 @@ ], "dependencies": { "@ckeditor/ckeditor5-dev-utils": "^43.0.0", - "@ckeditor/jsdoc-plugins": "^43.0.0", "@ckeditor/typedoc-plugins": "^43.0.0", "fast-glob": "^3.2.4", "fs-extra": "^11.2.0", - "jsdoc": "ckeditor/jsdoc#fixed-trailing-comment-doclets", "tmp": "^0.2.1", "typedoc": "^0.23.15", "typedoc-plugin-rename-defaults": "0.6.6" diff --git a/packages/ckeditor5-dev-docs/tests/validators/fires-validator/index.js b/packages/ckeditor5-dev-docs/tests/validators/fires-validator/index.js index ef8614dcf..c80cfd7cc 100644 --- a/packages/ckeditor5-dev-docs/tests/validators/fires-validator/index.js +++ b/packages/ckeditor5-dev-docs/tests/validators/fires-validator/index.js @@ -7,7 +7,7 @@ import { describe, it, expect, vi } from 'vitest'; import { fileURLToPath } from 'url'; import path from 'path'; import testUtils from '../../_utils.js'; -import build from '../../../lib/buildtypedoc.js'; +import build from '../../../lib/build.js'; const __filename = fileURLToPath( import.meta.url ); const __dirname = path.dirname( __filename ); @@ -39,7 +39,6 @@ describe( 'dev-docs/validators/fires-validator', function() { it( 'should warn if fired event does not exist', async () => { await build( { - type: 'typedoc', cwd: FIXTURES_PATH, tsconfig: TSCONFIG_PATH, sourceFiles: [ SOURCE_FILES ], diff --git a/packages/ckeditor5-dev-docs/tests/validators/link-validator/index.js b/packages/ckeditor5-dev-docs/tests/validators/link-validator/index.js index 1620653e8..3ad28d4cf 100644 --- a/packages/ckeditor5-dev-docs/tests/validators/link-validator/index.js +++ b/packages/ckeditor5-dev-docs/tests/validators/link-validator/index.js @@ -7,7 +7,7 @@ import { describe, it, expect, vi } from 'vitest'; import { fileURLToPath } from 'url'; import path from 'path'; import testUtils from '../../_utils.js'; -import build from '../../../lib/buildtypedoc.js'; +import build from '../../../lib/build.js'; const __filename = fileURLToPath( import.meta.url ); const __dirname = path.dirname( __filename ); @@ -40,7 +40,6 @@ describe( 'dev-docs/validators/link-validator', function() { it( 'should warn if link is not valid', async () => { await build( { - type: 'typedoc', cwd: FIXTURES_PATH, tsconfig: TSCONFIG_PATH, sourceFiles: [ SOURCE_FILES ], @@ -133,7 +132,6 @@ describe( 'dev-docs/validators/link-validator', function() { it( 'should not call error callback for derived class when there are errors in inherited class', async () => { await build( { - type: 'typedoc', cwd: FIXTURES_PATH, tsconfig: TSCONFIG_PATH, sourceFiles: [ DERIVED_FILE ], diff --git a/packages/ckeditor5-dev-docs/tests/validators/module-validator/index.js b/packages/ckeditor5-dev-docs/tests/validators/module-validator/index.js index 1d17bfd81..b194c2eb8 100644 --- a/packages/ckeditor5-dev-docs/tests/validators/module-validator/index.js +++ b/packages/ckeditor5-dev-docs/tests/validators/module-validator/index.js @@ -7,7 +7,7 @@ import { describe, it, expect, vi } from 'vitest'; import { fileURLToPath } from 'url'; import path from 'path'; import testUtils from '../../_utils.js'; -import build from '../../../lib/buildtypedoc.js'; +import build from '../../../lib/build.js'; const __filename = fileURLToPath( import.meta.url ); const __dirname = path.dirname( __filename ); @@ -39,7 +39,6 @@ describe( 'dev-docs/validators/module-validator', function() { it( 'should warn if module name is not valid', async () => { await build( { - type: 'typedoc', cwd: FIXTURES_PATH, tsconfig: TSCONFIG_PATH, sourceFiles: [ SOURCE_FILES ], diff --git a/packages/ckeditor5-dev-docs/tests/validators/overloads-validator/index.js b/packages/ckeditor5-dev-docs/tests/validators/overloads-validator/index.js index 52b846e40..0f11bfc67 100644 --- a/packages/ckeditor5-dev-docs/tests/validators/overloads-validator/index.js +++ b/packages/ckeditor5-dev-docs/tests/validators/overloads-validator/index.js @@ -7,7 +7,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { fileURLToPath } from 'url'; import path from 'path'; import testUtils from '../../_utils.js'; -import build from '../../../lib/buildtypedoc.js'; +import build from '../../../lib/build.js'; const __filename = fileURLToPath( import.meta.url ); const __dirname = path.dirname( __filename ); @@ -39,7 +39,6 @@ describe( 'dev-docs/validators/overloads-validator', function() { beforeEach( async () => { await build( { - type: 'typedoc', cwd: FIXTURES_PATH, tsconfig: TSCONFIG_PATH, sourceFiles: [ SOURCE_FILES ], diff --git a/packages/ckeditor5-dev-docs/tests/validators/see-validator/index.js b/packages/ckeditor5-dev-docs/tests/validators/see-validator/index.js index 4787c959f..78ab261ad 100644 --- a/packages/ckeditor5-dev-docs/tests/validators/see-validator/index.js +++ b/packages/ckeditor5-dev-docs/tests/validators/see-validator/index.js @@ -7,7 +7,7 @@ import { describe, it, expect, vi } from 'vitest'; import { fileURLToPath } from 'url'; import path from 'path'; import testUtils from '../../_utils.js'; -import build from '../../../lib/buildtypedoc.js'; +import build from '../../../lib/build.js'; const __filename = fileURLToPath( import.meta.url ); const __dirname = path.dirname( __filename ); @@ -39,7 +39,6 @@ describe( 'dev-docs/validators/see-validator', function() { it( 'should warn if link is not valid', async () => { await build( { - type: 'typedoc', cwd: FIXTURES_PATH, tsconfig: TSCONFIG_PATH, sourceFiles: [ SOURCE_FILES ], diff --git a/packages/jsdoc-plugins/CHANGELOG.md b/packages/jsdoc-plugins/CHANGELOG.md deleted file mode 100644 index 36118c29a..000000000 --- a/packages/jsdoc-plugins/CHANGELOG.md +++ /dev/null @@ -1,250 +0,0 @@ -Changelog -========= - -All changes in the package are documented in the main repository. See: https://github.com/ckeditor/ckeditor5-dev/blob/master/CHANGELOG.md. - -Changes for the past releases are available below. - -## [3.0.9](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@3.0.8...@ckeditor/jsdoc-plugins@3.0.9) (2020-02-26) - -Internal changes only (updated dependencies, documentation, etc.). - - -## [3.0.8](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@3.0.7...@ckeditor/jsdoc-plugins@3.0.8) (2020-01-09) - -Internal changes only (updated dependencies, documentation, etc.). - - -## [3.0.7](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@3.0.6...@ckeditor/jsdoc-plugins@3.0.7) (2019-09-09) - -### Other changes - -* Adjusted dev tools to work with "ckeditor-" prefix. See [ckeditor/ckeditor5#924](https://github.com/ckeditor/ckeditor5/issues/924). ([75b226f](https://github.com/ckeditor/ckeditor5-dev/commit/75b226f)) - - -## [3.0.6](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@3.0.5...@ckeditor/jsdoc-plugins@3.0.6) (2019-09-02) - -### Bug fixes - -* JSDoc validator will end with proper exit code if, during the validation, any error occurred. Closes [#550](https://github.com/ckeditor/ckeditor5-dev/issues/550). ([30f02e7](https://github.com/ckeditor/ckeditor5-dev/commit/30f02e7)) - - -## [3.0.5](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@3.0.4...@ckeditor/jsdoc-plugins@3.0.5) (2019-08-12) - -### Other changes - -* The doclet validator is improved. Now, during parameters linting it logs an error if the doclet cannot be a valid type (e.g. a method, property or a mixin cannot be a valid type). It also checks now whether the [@extends](https://github.com/extends) tag points to the valid reference. Closes [#507](https://github.com/ckeditor/ckeditor5-dev/issues/507). ([c5a8b08](https://github.com/ckeditor/ckeditor5-dev/commit/c5a8b08)) - - -## [3.0.4](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@3.0.3...@ckeditor/jsdoc-plugins@3.0.4) (2019-08-09) - -### Other changes - -* Added `ErrorEvent` and `PromiseRejectionEvent` types to the JSDoc validator. Part of [ckeditor/ckeditor5-watchdog#3](https://github.com/ckeditor/ckeditor5-watchdog/issues/3). ([799b272](https://github.com/ckeditor/ckeditor5-dev/commit/799b272)) - - -## [3.0.3](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@3.0.2...@ckeditor/jsdoc-plugins@3.0.3) (2019-07-15) - -### Other changes - -* Upgraded dependencies for most of the packages. Merged Lerna + Yarn and they can work together now. Closes [#527](https://github.com/ckeditor/ckeditor5-dev/issues/527). Closes [#466](https://github.com/ckeditor/ckeditor5-dev/issues/466). ([dcc3215](https://github.com/ckeditor/ckeditor5-dev/commit/dcc3215)) - - -## [3.0.2](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@3.0.1...@ckeditor/jsdoc-plugins@3.0.2) (2019-07-09) - -### Other changes - -* Enabled doclets generation out of typedef properties. Closes [#504](https://github.com/ckeditor/ckeditor5-dev/issues/504). ([2f480d1](https://github.com/ckeditor/ckeditor5-dev/commit/2f480d1)) - - -## [3.0.1](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@3.0.0...@ckeditor/jsdoc-plugins@3.0.1) (2019-02-28) - -Internal changes only (updated dependencies, documentation, etc.). - - -## [3.0.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@2.1.1...@ckeditor/jsdoc-plugins@3.0.0) (2019-02-19) - -### Bug fixes - -* Fixed inheritance mechanism and filtered out internal doclets. Closes [#465](https://github.com/ckeditor/ckeditor5-dev/issues/465). ([04a147b](https://github.com/ckeditor/ckeditor5-dev/commit/04a147b)) - -### BREAKING CHANGES - -* Upgraded minimal versions of Node to `8.0.0` and npm to `5.7.1`. See: [ckeditor/ckeditor5#1507](https://github.com/ckeditor/ckeditor5/issues/1507). ([612ea3c](https://github.com/ckeditor/ckeditor5-cloud-services/commit/612ea3c)) - - -## [2.1.1](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@2.1.0...@ckeditor/jsdoc-plugins@2.1.1) (2019-02-12) - -Internal changes only (updated dependencies, documentation, etc.). - - -## [2.1.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@2.0.2...@ckeditor/jsdoc-plugins@2.1.0) (2018-10-09) - -### Features - -* Added missing `@link` part validation to JSDoc validation. Closes [#433](https://github.com/ckeditor/ckeditor5-dev/issues/433). ([41c3014](https://github.com/ckeditor/ckeditor5-dev/commit/41c3014)) - - -## [2.0.2](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@2.0.1...@ckeditor/jsdoc-plugins@2.0.2) (2018-10-02) - -### Other changes - -* Improved performance of the `relation-fixer` plugin by the factor of 10x. Closes [#438](https://github.com/ckeditor/ckeditor5-dev/issues/438). ([ef1dc21](https://github.com/ckeditor/ckeditor5-dev/commit/ef1dc21)) - - -## [2.0.1](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@2.0.0...@ckeditor/jsdoc-plugins@2.0.1) (2018-09-24) - -Internal changes only (updated dependencies, documentation, etc.). - - -## [2.0.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.9.7...@ckeditor/jsdoc-plugins@2.0.0) (2018-08-23) - -Updated required Node.js version to `>=6.9.0`. - - -## [1.9.7](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.9.6...@ckeditor/jsdoc-plugins@1.9.7) (2018-07-17) - -Internal changes only (updated dependencies, documentation, etc.). - - -## [1.9.6](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.9.5...@ckeditor/jsdoc-plugins@1.9.6) (2018-07-03) - -### Other changes - -* Added FocusEvent to known types. ([9dd3b90](https://github.com/ckeditor/ckeditor5-dev/commit/9dd3b90)) - - -## [1.9.5](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.9.4...@ckeditor/jsdoc-plugins@1.9.5) (2018-06-28) - -### Other changes - -* Added NodeList to known types. ([158f60b](https://github.com/ckeditor/ckeditor5-dev/commit/158f60b)) - - -## [1.9.4](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.9.3...@ckeditor/jsdoc-plugins@1.9.4) (2018-03-27) - -Internal changes only (updated dependencies, documentation, etc.). - - -## [1.9.3](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.9.2...@ckeditor/jsdoc-plugins@1.9.3) (2018-02-20) - -### Bug fixes - -* Improved links detection and validation. Closes [#365](https://github.com/ckeditor/ckeditor5-dev/issues/365). ([00d5b10](https://github.com/ckeditor/ckeditor5-dev/commit/00d5b10)) - - -## [1.9.2](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.9.1...@ckeditor/jsdoc-plugins@1.9.2) (2018-02-16) - -### Bug fixes - -* Fixed inheritance in event doclets for observables. Closes [#368](https://github.com/ckeditor/ckeditor5-dev/issues/368). ([3fc1acc](https://github.com/ckeditor/ckeditor5-dev/commit/3fc1acc)) - - -## [1.9.1](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.9.0...@ckeditor/jsdoc-plugins@1.9.1) (2018-02-12) - -### Bug fixes - -* Fixed JSDoc relation-fixer plugin to not include interfaces in inheritance hierarchy. Closes [#361](https://github.com/ckeditor/ckeditor5-dev/issues/361). ([e46efbf](https://github.com/ckeditor/ckeditor5-dev/commit/e46efbf) and [d22fd7d](https://github.com/ckeditor/ckeditor5-dev/commit/d22fd7d)) - - -## [1.9.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.8.3...@ckeditor/jsdoc-plugins@1.9.0) (2018-01-22) - -### Features - -* JSDoc: Added support for using `@extends` with `@typedef`s. Closes [#355](https://github.com/ckeditor/ckeditor5-dev/issues/355). ([a3dd8c5](https://github.com/ckeditor/ckeditor5-dev/commit/a3dd8c5)) - - -## [1.8.3](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.8.2...@ckeditor/jsdoc-plugins@1.8.3) (2017-11-28) - -### Bug fixes - -* Improved linting the `memberof` property. Closes [ckeditor/ckeditor5-utils#209](https://github.com/ckeditor/ckeditor5-utils/issues/209). ([b57fe29](https://github.com/ckeditor/ckeditor5-dev/commit/b57fe29)) - - -## [1.8.2](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.8.1...@ckeditor/jsdoc-plugins@1.8.2) (2017-11-24) - -### Bug fixes - -* Optimized doclet validator plugin. Closes [#306](https://github.com/ckeditor/ckeditor5-dev/issues/306). ([664fb2d](https://github.com/ckeditor/ckeditor5-dev/commit/664fb2d)) -* Optimized Relation Fixer plugin. Closes [#312](https://github.com/ckeditor/ckeditor5-dev/issues/312). ([f575d77](https://github.com/ckeditor/ckeditor5-dev/commit/f575d77)) - - -## [1.8.1](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.8.0...@ckeditor/jsdoc-plugins@1.8.1) (2017-11-10) - -### Bug fixes - -* Add access property to events generated from observables. Closes [#300](https://github.com/ckeditor/ckeditor5-dev/issues/300). ([a80fe6e](https://github.com/ckeditor/ckeditor5-dev/commit/a80fe6e)) - - -## [1.8.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.7.1...@ckeditor/jsdoc-plugins@1.8.0) (2017-10-10) - -### Features - -* Provided support for `@observable` tag. Closes [#285](https://github.com/ckeditor/ckeditor5-dev/issues/285). ([fed57af](https://github.com/ckeditor/ckeditor5-dev/commit/fed57af)) - - -## [1.7.1](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.7.0...@ckeditor/jsdoc-plugins@1.7.1) (2017-10-01) - -Internal changes only (updated dependencies, documentation, etc.). - -## [1.7.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.6.1...@ckeditor/jsdoc-plugins@1.7.0) (2017-09-20) - -### Features - -* Provided `[@error](https://github.com/error)` tag detection in JSDoc. Closes [#280](https://github.com/ckeditor/ckeditor5-dev/issues/280). ([b7a0cf5](https://github.com/ckeditor/ckeditor5-dev/commit/b7a0cf5)) - - -## [1.6.1](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.6.0...@ckeditor/jsdoc-plugins@1.6.1) (2017-08-23) - -### Bug fixes - -* Remove duplicates in JSDoc relation-fixer plugin. Closes [#261](https://github.com/ckeditor/ckeditor5-dev/issues/261). ([e2a921a](https://github.com/ckeditor/ckeditor5-dev/commit/e2a921a)) - - -## [1.6.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.5.2...@ckeditor/jsdoc-plugins@1.6.0) (2017-08-18) - -### Features - -* All events will be automatically extended with `EventInfo` parameter. Closes [#257](https://github.com/ckeditor/ckeditor5-dev/issues/257). ([3968bd0](https://github.com/ckeditor/ckeditor5-dev/commit/3968bd0)) - - -## [1.5.2](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.5.0...@ckeditor/jsdoc-plugins@1.5.2) (2017-08-16) - -### Other changes - -* Added Window type to JSDoc validator. Closes [#250](https://github.com/ckeditor/ckeditor5-dev/issues/250). ([fdec4a0](https://github.com/ckeditor/ckeditor5-dev/commit/fdec4a0)) - - -## [1.5.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.4.0...@ckeditor/jsdoc-plugins@1.5.0) (2017-06-20) - -### Features - -* Static and mixed method, properties and events will be inherited too. Closes [#226](https://github.com/ckeditor/ckeditor5-dev/issues/226). ([a160840](https://github.com/ckeditor/ckeditor5-dev/commit/a160840)) - - -## [1.4.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.3.1...@ckeditor/jsdoc-plugins@1.4.0) (2017-05-29) - -### Features - -* Allow breaking the process if API docs validation fails. Closes [#221](https://github.com/ckeditor/ckeditor5-dev/issues/221). ([e2f0dec](https://github.com/ckeditor/ckeditor5-dev/commit/e2f0dec)) - - -## [1.3.1](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.3.0...@ckeditor/jsdoc-plugins@1.3.1) (2017-05-24) - -Internal changes only (updated dependencies, documentation, etc.). - -## [1.3.0](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.2.1...@ckeditor/jsdoc-plugins@1.3.0) (2017-05-18) - -### Features - -* Introduced JSDoc plugin enabling inheritance of static members. Closes [#201](https://github.com/ckeditor/ckeditor5-dev/issues/201). ([08c0a21](https://github.com/ckeditor/ckeditor5-dev/commit/08c0a21)) - - -## [1.2.1](https://github.com/ckeditor/ckeditor5-dev/compare/@ckeditor/jsdoc-plugins@1.2.0...@ckeditor/jsdoc-plugins@1.2.1) (2017-04-27) - -Internal changes only (updated dependencies, documentation, etc.). - - -## 1.2.0 - -The big bang. diff --git a/packages/jsdoc-plugins/LICENSE.md b/packages/jsdoc-plugins/LICENSE.md deleted file mode 100644 index e536047e7..000000000 --- a/packages/jsdoc-plugins/LICENSE.md +++ /dev/null @@ -1,39 +0,0 @@ -Software License Agreement -========================== - -@ckeditor/jsdoc-plugins – Various JSDoc plugins developed by the CKEditor 5 team. -Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - -Licensed under the terms of the MIT License (see Appendix A): - - http://en.wikipedia.org/wiki/MIT_License - -Sources of Intellectual Property Included in CKEditor ------------------------------------------------------ - -Where not otherwise indicated, all @ckeditor/jsdoc-plugins content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, @ckeditor/jsdoc-plugins will incorporate work done by developers outside of CKSource with their express permission. - -Appendix A: The MIT License ---------------------------- - -The MIT License (MIT) - -Copyright (c) 2003-2024, CKSource Holding sp. z o.o. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/packages/jsdoc-plugins/README.md b/packages/jsdoc-plugins/README.md deleted file mode 100644 index ee2e2f224..000000000 --- a/packages/jsdoc-plugins/README.md +++ /dev/null @@ -1,217 +0,0 @@ -# JSDoc plugins overview - -[![npm version](https://badge.fury.io/js/%40ckeditor%2Fjsdoc-plugins.svg)](https://www.npmjs.com/package/@ckeditor/jsdoc-plugins) -[![CircleCI](https://circleci.com/gh/ckeditor/ckeditor5-dev.svg?style=shield)](https://app.circleci.com/pipelines/github/ckeditor/ckeditor5-dev?branch=master) - -## Overview - -This repository consists of few plugins which extend the capabilities of [JSDoc](https://github.com/jsdoc3/jsdoc). - -The list of generic plugins: - -* `lib/validator/validator.js` - validates if references to types used in params lists or property types are defined elsewhere, whether links point to existing properties/classes/modules, etc. -* `lib/export-fixer/export-fixer.js` - fixes an error with `export default` syntax -* `lib/custom-tags/error.js` - provides support for the custom `@error` tag -* `lib/relation-fixer.js` - fixes problem with inheritance (extends child classes with properties from parent classes) -* `lib/longname-fixer/longname-fixer.js` - enables short notation in links -* `lib/utils/doclet-logger.js` - enables logging output into the `/docs/api/output.json` - -CKEditor 5 specific plugins - -* `lib/event-extender/event-extender.js` - CKEditor 5 specific util that inserts parameter to all events. -* `lib/custom-tags/observable.js` - CKEditor 5 specific tag for observable properties -* `lib/observable-event-provider.js` - CKEditor 5 specific - -## Usage - -### JSDoc configuration - -To enable above plugins you need to list them in the `plugins` array of JSDoc config file. - -```json -{ - "plugins": [ - "node_modules/@ckeditor/jsdoc-plugins/lib/validator/validator", - "node_modules/@ckeditor/jsdoc-plugins/lib/longname-fixer/longname-fixer" - ], - // ... -} -``` - -Then, having the https://github.com/jsdoc3/jsdoc installed, the only thing to do is to call the command with the `-c` flag pointing to the configuration file. - -```bash -jsdoc -c path/to/config.json -``` - -## Types of references - -The reference system is improved by the `lib/longname-fixer/longname-fixer.js` plugin. - -### Overview - -There're 2 types of references available inside JSDoc comments. First of them are called `Full references`. They work everywhere but the con of using them are long names. The second ones are short references that can be used to point symbols that are present in the same file. - -### Full references - -Full references start with `module:`. The first part of that syntax needs to match the `@module` tag in the corresponding class. - -Here are a few examples: - -* `@param {module:command~Command}` -* `{@link module:core/editor/editor~Editor editor}` -* `@member {module:core/editor/editor~Editor}` - -### Short references - -There are two types of short references available. - -References starting with `#` are available for members methods and events, e.g. `{@link #create}`. These refs can be used to point members and methods inside the same class or interface. - -References starting with `~` are available to point classes and interfaces, e.g. `{@link ~Editor}`. **There's a known issue with pointing things that are declared later, the full ref should be used then instead.** - -```js -class Editor { - /** - * This property represents {@link ~Editor editor} name. - * - * @member {String} #name - */ - - /** - * This property represents editor version. - * See editor {@link #name name}. - * - * @member {String} #version - */ - - /** - * Get version of the editor - * Note - '@method getVersion' isn't needed here because the method is declared. - */ - getVersion() { - return this.version; - } -} -``` - - -## Events - -Events can be assigned to the classes. - -The `@fires` and `@event` tags work well with full references and with short references to the current `class` / `interface` / `mixin`. - -Events can be declared in class bodies and after them (short references are available in both cases). - -Full reference to the events must have the following syntax: `module:somemodule~SomeClass#event:eventName`. Note that `event:` part is required here. -Short reference can be either `event:eventName` or `eventName`. - -```js -class FocusTracker { - /** - * @private - * @fires blur - */ - _blur() { } - - /** - * @fires focus - * @fires module:focustracker~FocusTracker#event:focus // this will link to the same event as above - */ - - /** - * @event blur - */ -} - -// Note: the following event will be bound to the `FocusTracker` class. -/** - * @event focus - */ -``` - -## Validation - -### Overview - -The `lib/validator/validator.js` plugin is supposed to validate references and check types in JSDoc comments. - -Note that the `@module` tag is required on top of each file to make the validation possible. Without that tag, the validator will complain about it with the message: `Memberof property should start with 'module:'`. - -During the JSDoc compilation, the errors are thrown to the standard output for each invalid reference or type. - -### Validated tags - -References for the following tags are validated: - -* `@link` - matches *references* -* `@member` - matches *types* -* `@fires` – matches *events* -* `@param` - matches *types* -* `@implements` – matches *interfaces* -* `@returns` - matches *types* -* `@see` - matches *references* - -### Available types - -There're few kind of types available with following syntax: - -* Wildcard: `*`. -* Basic types: basic ES and DOM types, e.g. `String`, `Boolean`, `Error`, `Node`. -* String literal types: `'someString'`. -* Union types: `Type1|Type2`, `Type1|Type2|Type3`, etc. -* Generic types: `GenericType.`, `GenericType`, etc. -* References: declared interfaces, objects, events, etc. E.g. `module:somemodule~SomeInteface`. - -These types can be used together, e.g.: - -```js -/** - * @param {Map.<*>} map - * @param {'left'|'right'} direction - * @param {Object.} dictionary - * @returns {Array.} - */ -``` - -Basic types and generic types are listed in the `jsdoc/validator/types.js`. - -## TODO - -### Unsupported short references - -For now, there are still few unsupported tags, which require full references: - -* `@param` -* `@typedef` - -### Missing validation - -There're also tags which are not validated: - -* `@mixes` -* `@augments` / `@extends` - -## Inheritance of class members - -This feature is implemented by the `lib/relation-fixer/index.js` plugin. - -### Overview - -As of version 3.4.3 JSDoc [does not support inheritance of static members](https://github.com/jsdoc3/jsdoc/issues/1229). - -If class B extends class A and class A has a static property, JSDoc will not output documentation of that static property to documentation of class B. - -The `lib/relation-fixer` plugin checks for such cases and updates documentation of child classes with documentation of inherited, implemented or mixed static members. - -It also adds additional properties to doclets of classes, interfaces, and mixins to show related doclets. These properties are: - -* `augmentsNested` - an array of references to all parent classes, -* `implementsNested` - an array of references to implemented interfaces, -* `mixesNested` - an array of references to mixed mixins, -* `descendants` - an array of references to entities which implement, mix or extend the doclet. - -## Changelog - -See the [`CHANGELOG.md`](https://github.com/ckeditor/ckeditor5-dev/blob/master/packages/jsdoc-plugins/CHANGELOG.md) file. diff --git a/packages/jsdoc-plugins/lib/cleanup.js b/packages/jsdoc-plugins/lib/cleanup.js deleted file mode 100644 index a34a6cf99..000000000 --- a/packages/jsdoc-plugins/lib/cleanup.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -const { isEqual } = require( 'lodash' ); - -exports.handlers = { - processingComplete( e ) { - const knownDoclets = new Map(); - - for ( const doclet of e.doclets ) { - if ( doclet.name && doclet.name.startsWith( '#' ) ) { - doclet.name = doclet.name.slice( 1 ); - } - - if ( doclet.longname.includes( '#' ) ) { - doclet.scope = 'instance'; - } - - // Remove duplicates. - if ( knownDoclets.has( doclet.longname ) && isEqual( doclet, knownDoclets.get( doclet.longname ) ) ) { - doclet.ignore = true; - } - - knownDoclets.set( doclet.longname, doclet ); - - // Delete props that we don't use. - delete doclet.overrides; - } - - /** @type {Map.>} */ - const docletMap = new Map(); - - for ( const doclet of e.doclets ) { - const otherDocletsWithSameName = docletMap.get( doclet.longname ); - - if ( !otherDocletsWithSameName ) { - docletMap.set( doclet.longname, [ doclet ] ); - } else { - docletMap.set( doclet.longname, [ ...otherDocletsWithSameName, doclet ] ); - } - } - - // Delete doclets that are inherited and should be overwritten. - for ( const doclets of docletMap.values() ) { - const inheritedDoclets = doclets.filter( doclet => doclet.inherited ); - - if ( doclets.find( doclet => !doclet.inherited && !doclet.ignore ) ) { - for ( const d of inheritedDoclets ) { - d.ignore = true; - } - } - } - - e.doclets = e.doclets - // Filter out the package doclet. - .filter( doclet => doclet.kind !== 'package' ) - .filter( doclet => { - // Filter out doclet that should be ignored. - if ( doclet.ignore ) { - return false; - } - - // Filter out undocumented doclets. - if ( doclet.undocumented ) { - return ( - !!doclet.description || - !!doclet.comment || - !!doclet.classdesc - ); - } - - return true; - } ); - } -}; diff --git a/packages/jsdoc-plugins/lib/custom-tags/error.js b/packages/jsdoc-plugins/lib/custom-tags/error.js deleted file mode 100644 index 9f708ea0e..000000000 --- a/packages/jsdoc-plugins/lib/custom-tags/error.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -module.exports = { - // See http://usejsdoc.org/about-plugins.html#tag-definition. - defineTags( dictionary ) { - dictionary.defineTag( 'error', { - mustHaveValue: true, - mustNotHaveDescription: false, - canHaveType: true, - canHaveName: true, - onTagged( doclet, tag ) { - Object.assign( doclet, { - name: tag.value.name, - longname: `module:errors/${ tag.value.name }`, - kind: 'error', - memberof: 'module:errors', - scope: 'inner' - } ); - } - } ); - } -}; diff --git a/packages/jsdoc-plugins/lib/custom-tags/observable.js b/packages/jsdoc-plugins/lib/custom-tags/observable.js deleted file mode 100644 index 1de60f9ec..000000000 --- a/packages/jsdoc-plugins/lib/custom-tags/observable.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -module.exports = { - // See http://usejsdoc.org/about-plugins.html#tag-definitions. - defineTags( dictionary ) { - dictionary.defineTag( 'observable', { - onTagged( doclet ) { - doclet.observable = true; - } - } ); - } -}; diff --git a/packages/jsdoc-plugins/lib/doclet.jsdoc b/packages/jsdoc-plugins/lib/doclet.jsdoc deleted file mode 100644 index 0d94bce5a..000000000 --- a/packages/jsdoc-plugins/lib/doclet.jsdoc +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * Licensed under the terms of the MIT License (see LICENSE.md). - */ - -/** - * Doclets are atomic parts of the JSDoc output that describe each symbol of parsed input. - * - * @typedef {Object} Doclet - * - * @property {String} longname Long name of the doclet (including the `module:` part). - * - * @property {String} name Short name of the doclet (e.g. the name of the method). - * - * @property {Type} [type] A type of the member. - * - * @property {Array.} [returns] The metadata for the function or method return type and description. - * - * @property {String} memberof Where the doclet belongs to (parent of the symbol). - * - * @property {'class'|'interface'|'mixin'|'function'|'typedef'|'event'|'member'|'constant'|'module'|'error'} kind - * The kind of the doclet's symbol. - * - * @property {Boolean} [ignore] `true` for internal doclets which should not be published - * - * @property {Boolean} [undocumented] `true` when a doclet's symbol does not have API docs written above the declaration. - * - * @property {String} [inheritdoc] Specifies whether the `@inheritdoc` tag is present. Warning: When the `@inheritdoc` tag is - * present without no additional docs, then this property becomes an empty string! - * - * @property {Boolean} [overrides] - * - * @property {Array.} [properties] Typedef properties. - * - * @property {Boolean} [inherited] `true` for a property / method which is inherited from the parent class. - * - * @property {String} [inherits] The longname of the parent class / interface method. - * - * @property {String} [comment] Raw API comment. - * - * @property {String} [description] API Comment wrapped in HTML tags. - * - * @property {String} [classdesc] Description for the class. - * - * @property {Array.} [see] `@see {}` tag contents. - * - * @property {Array.} [params] Event and function params. - * - * @property {'instance'|'inner'|'static'|'global'} [scope] - * - * @property {Array.} [fires] An array of events that a method or a property can fire. - * - * @property {{ filename: String; lineno: Number; path: String }} meta Doclet's metadata - filename, line number, etc. - * - * @property {Array.} [augments] An array of classes that the doclet's symbol extends. - * Applies for `@class`, `@mixin`, `@interface`. - * - * @property {Array.} [mixes] An array of mixins that the doclet's symbol mixes. - * Applies for `@class` and `@mixin`. - * - * @property {Boolean} [mixed] `true` when a property or method comes from a mixin. - * - * @property {Array.} [implements] An array of interfaces that the doclet's symbol implements. - * Applies for `@class` and `@mixin`. - * - * @property {Array.} [augmentsNested] [A custom property used by the relation fixer] - - * an array of all classes in the inheritance chain augmenting the current doclet's symbol. - * - * @property {Array.} [mixesNested] [A custom property used by the relation fixer] - - * an array of all mixins in the inheritance chain augmenting the current doclet's symbol. - * - * @property {Array.} [implementsNested] [A custom property used by the relation fixer] - - * an array of all interfaces in the inheritance chain, which the current doclet's symbol implements. - * - * @property {Array.} [descendants] [A custom property used by the relation fixer] - - * an array of doclets which inherits / implements / mixes the doclet's symbol. - */ - -/** - * @typedef {Object} Property - * - * @property {String} name - * - * @property {Type} type - * - * @property {String} [description] - * - * @property {Boolean} [inherited] [A custom property used by the relation fixer] - */ - -/** - * @typedef {Object} Type - * - * @property {Array.} names -*/ - -/** - * @typedef {Object} ReturnData - * - * @property {Type} type Type of the return statement. I.e. what the function should return. - * It's gathered from the text after the `@returns` tag. - * - * @property {String} [description] Description for the return statement (after the `@returns` tag and type). - */ - -/** - * @typedef {Object} Parameter - * - * @property {Type} type Type of the parameter. - * - * @property {String} name Name of the paramter. - * - * @property {String} [description] Description of the parameter. - */ diff --git a/packages/jsdoc-plugins/lib/event-extender/event-extender.js b/packages/jsdoc-plugins/lib/event-extender/event-extender.js deleted file mode 100644 index 8d2768fe2..000000000 --- a/packages/jsdoc-plugins/lib/event-extender/event-extender.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -module.exports = { - handlers: { - /** - * @see http://usejsdoc.org/about-plugins.html#event-newdoclet - * @param evt - */ - newDoclet( evt ) { - const { doclet } = evt; - - if ( doclet.kind !== 'event' ) { - return; - } - - if ( !doclet.params ) { - doclet.params = []; - } - - doclet.params.unshift( { - type: { - names: [ - 'module:utils/eventinfo~EventInfo' - ] - }, - description: '

An object containing information about the fired event.

', - name: 'eventInfo' - } ); - } - } -}; diff --git a/packages/jsdoc-plugins/lib/export-fixer/export-fixer.js b/packages/jsdoc-plugins/lib/export-fixer/export-fixer.js deleted file mode 100644 index 374a35013..000000000 --- a/packages/jsdoc-plugins/lib/export-fixer/export-fixer.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -module.exports = { - handlers: { - /** - * @see http://usejsdoc.org/about-plugins.html#event-beforeparse - * @param evt - */ - beforeParse( evt ) { - // See https://github.com/ckeditor/ckeditor5-design/blob/jsdoc-module-test/jsdoc/plugins/export-fix.js - // and the contents of that branch for better understanding of wht these replacements do. - - evt.source = evt.source - .replace( /(\n\t*)export default class /, '$1class ' ) - .replace( /(\n\t*)export class /g, '$1class ' ) - .replace( /(\n\t*)export default function /, '$1export function ' ); - } - } -}; diff --git a/packages/jsdoc-plugins/lib/fix-code-snippets.js b/packages/jsdoc-plugins/lib/fix-code-snippets.js deleted file mode 100644 index fd8178936..000000000 --- a/packages/jsdoc-plugins/lib/fix-code-snippets.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -/** - * A fixer for doclet descriptions including code snippets. - * After upgrading JSDoc to v. 3.6.4 snippets started to contain leading tabs or spaces. - * This plugin removes that left padding. - */ -exports.handlers = { - parseComplete: e => { - /** @type {Array.} */ - const doclets = e.doclets; - - for ( const doclet of doclets ) { - if ( doclet.description ) { - doclet.description = fixDescription( doclet.description ); - } - - if ( doclet.classdesc ) { - doclet.classdesc = fixDescription( doclet.classdesc ); - } - - if ( doclet.params ) { - for ( const param of doclet.params ) { - if ( param.description ) { - param.description = fixDescription( param.description ); - } - } - } - - if ( doclet.returns ) { - for ( const returnObject of doclet.returns ) { - if ( returnObject.description ) { - returnObject.description = fixDescription( returnObject.description ); - } - } - } - - if ( doclet.properties ) { - for ( const property of doclet.properties ) { - if ( property.description ) { - property.description = fixDescription( property.description ); - } - } - } - } - } -}; - -function fixDescription( desc ) { - return desc.replace( /
(.*?)<\/code><\/pre>/gs, ( _match, codeSnippetContent ) => {
-		const codeRows = codeSnippetContent.split( '\n' );
-
-		let paddingSize = 0;
-
-		while ( true ) {
-			const paddingText = codeRows[ 0 ].slice( 0, paddingSize + 1 );
-
-			// When some row starts with a different text or
-			// padding contains some non-whitespace characters
-			// then it means that it is no loner a padding.
-			if (
-				( codeRows.some( row => /\S/.test( row ) && !row.startsWith( paddingText ) ) ) ||
-				/\S/.test( paddingText )
-			) {
-				break;
-			}
-
-			paddingSize++;
-		}
-
-		return (
-			'
' +
-			codeRows.map( row => row.slice( paddingSize ) ).join( '\n' ) +
-			'
' - ); - } ); -} diff --git a/packages/jsdoc-plugins/lib/longname-fixer/fixers/convert-short-refs-to-full-refs.js b/packages/jsdoc-plugins/lib/longname-fixer/fixers/convert-short-refs-to-full-refs.js deleted file mode 100644 index 8de5b6418..000000000 --- a/packages/jsdoc-plugins/lib/longname-fixer/fixers/convert-short-refs-to-full-refs.js +++ /dev/null @@ -1,227 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const assign = Object.assign; - -/** - * @param {Array.} doclets - */ -function convertShortRefsToFullRefs( doclets ) { - addMissingModulePart( doclets ); - convertShortRefsInLongnameAndMemberof( doclets ); - convertShortRefsInFireTag( doclets ); - convertShortRefsInSeeTag( doclets ); - convertShortRefsInLinks( doclets ); -} - -/** @param {Array.} doclets */ -function addMissingModulePart( doclets ) { - /** @type {Record} */ - const fileNameModuleDoclets = {}; - - for ( const doclet of doclets ) { - if ( doclet.kind === 'module' ) { - fileNameModuleDoclets[ doclet.meta.path + '/' + doclet.meta.filename ] = doclet; - } - } - - for ( const doclet of doclets ) { - if ( [ 'interface', 'class', 'mixin' ].includes( doclet.kind ) ) { - if ( - !doclet.longname.startsWith( 'module:' ) && - fileNameModuleDoclets[ doclet.meta.path + '/' + doclet.meta.filename ] - ) { - const module = fileNameModuleDoclets[ doclet.meta.path + '/' + doclet.meta.filename ]; - - assign( doclet, { - scope: 'inner', - memberof: module.longname, - longname: module.longname + '~' + doclet.longname - } ); - } - } - } -} - -/** @param {Array.} doclets */ -function convertShortRefsInLongnameAndMemberof( doclets ) { - const fileDoclets = groupDocletsByFiles( doclets ); - - for ( const doclet of doclets ) { - const parentDoclet = getCorrespondingParent( fileDoclets[ doclet.meta.path + '/' + doclet.meta.filename ], doclet ); - - const firstNameChar = doclet.longname[ 0 ]; - - if ( firstNameChar === '~' ) { - assign( doclet, { - memberof: parentDoclet.memberof + '~' + parentDoclet.name, - longname: parentDoclet.memberof + doclet.longname - } ); - } else if ( firstNameChar === '#' ) { - assign( doclet, { - memberof: parentDoclet.longname, - longname: parentDoclet.longname + doclet.longname - } ); - } - - // Fixes longname in events containing ':' in their names (e.g. change:attribute) - if ( doclet.kind === 'event' ) { - if ( doclet.longname.includes( '~' ) && doclet.longname.includes( '#' ) ) { - continue; - } - - doclet.memberof = parentDoclet.longname; - - if ( !doclet.name.includes( 'event' ) ) { - doclet.longname = parentDoclet.longname + '#event:' + doclet.name; - } else { - doclet.longname = parentDoclet.longname + '#' + doclet.name; - } - } - } -} - -/** @param {Array.} doclets */ -function convertShortRefsInFireTag( doclets ) { - for ( const doclet of doclets ) { - if ( !doclet.fires ) { - continue; - } - - doclet.fires = doclet.fires.map( event => { - if ( event.includes( 'module:' ) ) { - return event; - } - - if ( !event.includes( 'event:' ) ) { - event = 'event:' + event; - } - - if ( doclet.memberof.includes( '~' ) ) { - return doclet.memberof + '#' + event; - } - - return doclet.longname + '#' + event; - } ); - } -} - -/** @param {Array.} doclets */ -function convertShortRefsInSeeTag( doclets ) { - /** @type {Doclet} */ - let lastInterfaceOrClass; - - for ( const doclet of doclets ) { - if ( [ 'interface', 'class', 'mixin' ].includes( doclet.kind ) ) { - lastInterfaceOrClass = doclet; - } - - if ( !doclet.see ) { - continue; - } - - doclet.see = doclet.see.map( see => { - if ( see[ 0 ] === '#' ) { - return lastInterfaceOrClass.longname + see; - } - - if ( see[ 0 ] === '~' ) { - return lastInterfaceOrClass.memberof + see; - } - - return see; - } ); - } -} - -function convertShortRefsInLinks( doclets ) { - const fileDoclets = groupDocletsByFiles( doclets ); - - for ( const doclet of doclets ) { - const parentDoclet = getCorrespondingParent( fileDoclets[ doclet.meta.path + '/' + doclet.meta.filename ], doclet ); - - let memberof = doclet.memberof; - - // Errors have their own module 'module/errors'. - // Shortened links in error descriptions should link to the class items, not the error module. - if ( doclet.kind === 'error' && parentDoclet ) { - memberof = parentDoclet.longname; - } - - const linkRegExp = /{@link *([~#][^}]+)}/g; - const replacer = ( _fullLink, linkContent ) => { - const [ ref, ...linkDescription ] = linkContent.split( ' ' ); - const [ className, methodName ] = ref.split( '#' ); - - let result = '{@link ' + memberof; - - if ( !memberof.includes( className ) ) { - return result + linkContent + '}'; - } - - if ( methodName ) { - result += '#' + methodName; - } - - result += linkDescription.map( word => ' ' + word ).join( ' ' ); - - return result + '}'; - }; - - const comment = doclet.comment.replace( linkRegExp, replacer ); - - let description = doclet.description; - - if ( description ) { - description = doclet.description.replace( linkRegExp, replacer ); - } - - Object.assign( doclet, { comment, description } ); - } -} - -/** - * @param {Array.} doclets - */ -function groupDocletsByFiles( doclets ) { - /** @type {Record.>}*/ - const files = {}; - - for ( const doclet of doclets ) { - if ( !files[ doclet.meta.path + '/' + doclet.meta.filename ] ) { - files[ doclet.meta.path + '/' + doclet.meta.filename ] = []; - } - - files[ doclet.meta.path + '/' + doclet.meta.filename ].push( doclet ); - } - - return files; -} - -/** - * Finds within the same file the parent doclet (`class`, `interface` or `mixin`). - * - * @param {Array.} fileDoclets - * @param {Doclet} doclet -*/ -function getCorrespondingParent( fileDoclets, doclet ) { - let closestParent = null; - let closestLine = -1; - - for ( const fileDoclet of fileDoclets ) { - if ( [ 'interface', 'class', 'mixin' ].includes( fileDoclet.kind ) ) { - if ( fileDoclet.meta.lineno > closestLine && fileDoclet.meta.lineno <= doclet.meta.lineno ) { - closestParent = fileDoclet; - closestLine = fileDoclet.meta.lineno; - } - } - } - - return closestParent; -} - -module.exports = convertShortRefsToFullRefs; diff --git a/packages/jsdoc-plugins/lib/longname-fixer/fixers/fix-incorrect-class-constructor.js b/packages/jsdoc-plugins/lib/longname-fixer/fixers/fix-incorrect-class-constructor.js deleted file mode 100644 index 8b6dc7045..000000000 --- a/packages/jsdoc-plugins/lib/longname-fixer/fixers/fix-incorrect-class-constructor.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const { isEqual } = require( 'lodash' ); - -/** - * This function is supposed to fix both constructor and class doclets. - * - * JSDoc completely messes up doclets for constructors and classes. - * They are duplicated (where the only one contains valuable data), have invalid descriptions, etc. - * - * @param {Array.} doclets - */ -module.exports = function fixIncorrectClassConstructor( doclets ) { - const knownConstructorDoclets = new Set(); - const knownDoclets = new Map(); - - for ( const doclet of doclets ) { - // Constructor doclets have the same longname as class doclets. - if ( doclet.kind === 'class' && doclet.params ) { - Object.assign( doclet, { - longname: doclet.longname + '#constructor', - memberof: doclet.longname, - kind: 'function', - scope: 'instance', - name: 'constructor' - } ); - - if ( doclet.comment ) { - delete doclet.undocumented; - } - } - - if ( doclet.kind === 'function' && doclet.name === 'constructor' ) { - if ( knownConstructorDoclets.has( doclet.longname ) ) { - doclet.ignore = true; - } - - knownConstructorDoclets.add( doclet.longname ); - } - - if ( doclet.kind === 'class' && doclet.classdesc ) { - if ( doclet.description && doclet.description !== doclet.classdesc ) { - doclet.ignore = true; - } else { - if ( doclet.classdesc ) { - delete doclet.undocumented; - } - } - - if ( !doclet.comment || doclet.comment.includes( '@inheritDoc' ) ) { - doclet.ignore = true; - } - } - - // Remove duplicates (mostly they are created by the relation-fixer). - // The whole relation-fixer's logic should be rewritten. - if ( knownDoclets.has( doclet.longname ) && isEqual( doclet, knownDoclets.get( doclet.longname ) ) ) { - doclet.ignore = true; - } - - knownDoclets.set( doclet.longname, doclet ); - } -}; diff --git a/packages/jsdoc-plugins/lib/longname-fixer/longname-fixer.js b/packages/jsdoc-plugins/lib/longname-fixer/longname-fixer.js deleted file mode 100644 index 3c6b526aa..000000000 --- a/packages/jsdoc-plugins/lib/longname-fixer/longname-fixer.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -/** - * @see http://usejsdoc.org/about-plugins.html - */ - -'use strict'; - -const convertShortRefsToFullRefs = require( './fixers/convert-short-refs-to-full-refs' ); -const fixIncorrectClassConstructor = require( './fixers/fix-incorrect-class-constructor' ); - -const modulePattern = /module:[\w-]+(\/[\w-]+)*$/; - -exports.handlers = { - parseComplete: e => { - const doclets = e.doclets; - - fixIncorrectClassConstructor( doclets ); - convertShortRefsToFullRefs( doclets ); - - // Fix exported functions. - // All exported functions should be marked as module's `inner`. - for ( const doclet of doclets ) { - if ( doclet.kind === 'function' && doclet.scope === 'static' && modulePattern.test( doclet.memberof ) ) { - doclet.scope = 'inner'; - doclet.longname = doclet.longname.replace( /\./, '~' ); - } - - if ( doclet.kind === 'constant' && doclet.scope === 'static' && modulePattern.test( doclet.memberof ) ) { - doclet.scope = 'inner'; - doclet.longname = doclet.longname.replace( /\./, '~' ); - } - } - - // Filter out incorrect doclets. - e.doclets = doclets.filter( doclet => !doclet.ignore ); - } -}; diff --git a/packages/jsdoc-plugins/lib/observable-event-provider/addmissingeventdocletsforobservables.js b/packages/jsdoc-plugins/lib/observable-event-provider/addmissingeventdocletsforobservables.js deleted file mode 100644 index d898730b7..000000000 --- a/packages/jsdoc-plugins/lib/observable-event-provider/addmissingeventdocletsforobservables.js +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const { cloneDeep } = require( 'lodash' ); - -/** - * Creates event doclets for observable properties if they're missing. - * See #285. - * - * @param {Array.} doclets - * @returns {Array.} An array of enhanced doclets. - */ -module.exports = function addMissingEventDocletsForObservables( doclets ) { - doclets = markFiredEvents( doclets ); - - const newEventDoclets = createMissingEventDoclets( doclets ); - - return doclets.concat( newEventDoclets ); -}; - -// @param {Array.} doclets -// @returns {Array.} An array of doclets with fixed fires property. -function markFiredEvents( doclets ) { - return doclets.map( doclet => { - if ( !doclet.observable ) { - return doclet; - } - - const newDoclet = cloneDeep( doclet ); - const eventName = newDoclet.memberof + '#event:change:' + newDoclet.name; - - if ( !newDoclet.fires ) { - newDoclet.fires = []; - } - - if ( !newDoclet.fires.includes( eventName ) ) { - newDoclet.fires.push( eventName ); - } - - return newDoclet; - } ); -} - -// @param {Array.} doclets -// @returns {Array.} An array of new event doclets. -function createMissingEventDoclets( doclets ) { - const eventLongNames = doclets.filter( d => d.kind === 'event' ).map( d => d.longname ); - const observableEvents = getObservableEvents( doclets ); - - return observableEvents - // Skip for existing events. - .filter( observableEvent => !eventLongNames.includes( observableEvent.name ) ) - .map( observableEvent => { - const originalProperty = observableEvent.property; - - const typeNames = originalProperty.type ? - originalProperty.type.names : - [ '*' ]; - - const eventDoclet = { - comment: '', - meta: cloneDeep( originalProperty.meta ), - description: `

Fired when the ${ originalProperty.name } property changed value.

`, - kind: 'event', - name: 'change:' + originalProperty.name, - params: [ { - type: { - names: [ 'module:utils/eventinfo~EventInfo' ] - }, - description: '

An object containing information about the fired event.

', - name: 'eventInfo' - }, - { - type: { - names: [ 'String' ] - }, - description: `

Name of the changed property (${ originalProperty.name }).

`, - name: 'name' - }, - { - type: { - names: [ ...typeNames ] - }, - description: [ - `

New value of the ${ originalProperty.name } property with given key or null, `, - 'if operation should remove property.

' - ].join( '' ), - name: 'value' - }, - { - type: { - names: [ ...typeNames ] - }, - description: [ - `

Old value of the ${ originalProperty.name } property with given key or null, `, - 'if property was not set before.

' - ].join( '' ), - name: 'oldValue' - } ], - memberof: originalProperty.memberof, - longname: observableEvent.name, - scope: 'instance', - access: originalProperty.access ? originalProperty.access : 'public' - }; - - if ( originalProperty.inherited ) { - eventDoclet.inherited = true; - } - - if ( originalProperty.mixed ) { - eventDoclet.mixed = true; - } - - return eventDoclet; - } ); -} - -function getObservableEvents( doclets ) { - return doclets - .filter( doclet => doclet.observable ) - .map( observableDoclet => { - const eventName = observableDoclet.memberof + '#event:change:' + observableDoclet.name; - - return { - name: eventName, - property: observableDoclet - }; - } ); -} diff --git a/packages/jsdoc-plugins/lib/observable-event-provider/index.js b/packages/jsdoc-plugins/lib/observable-event-provider/index.js deleted file mode 100644 index 83285112a..000000000 --- a/packages/jsdoc-plugins/lib/observable-event-provider/index.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const addMissingEventDocletsForObservables = require( './addmissingeventdocletsforobservables' ); - -module.exports = { - handlers: { - processingComplete( e ) { - e.doclets = addMissingEventDocletsForObservables( e.doclets ); - } - } -}; diff --git a/packages/jsdoc-plugins/lib/purge-private-api-docs.js b/packages/jsdoc-plugins/lib/purge-private-api-docs.js deleted file mode 100644 index 79586ffad..000000000 --- a/packages/jsdoc-plugins/lib/purge-private-api-docs.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -// A plugin for JSDoc that should purge non-public API docs. -// Public API docs should contain the `@publicApi` tag below the `@module` tag. - -const path = require( 'path' ); -const fs = require( 'fs' ); - -module.exports = { - handlers: { - /** - * @see http://usejsdoc.org/about-plugins.html#event-beforeparse - * @param {any} evt - */ - beforeParse( evt ) { - // Skip public packages. - if ( !isPrivatePackageFile( evt.filename ) ) { - return; - } - - // Do not emit any JSDoc doclet if the `@publicApi` tag is missing in that file. - if ( !evt.source.includes( '@publicApi' ) ) { - evt.source = ''; - - return; - } - - // Do not emit any JSDoc doclet if the '@module' tag is missing and log a warning. - if ( !evt.source.includes( '@module' ) ) { - evt.source = ''; - - const filename = path.relative( process.cwd(), evt.filename ); - - console.warn( `File ${ filename } did not start with '@module' tag and hence it will be ignored while building docs.` ); - } - }, - - processingComplete( evt ) { - for ( const doclet of evt.doclets ) { - if ( doclet.meta && doclet.meta.path ) { - if ( isPrivatePackageFile( doclet.meta.path ) ) { - doclet.skipSource = true; - } - } - } - - // Filter out protected and private doclets. - // It's a simple and naive approach, this way private and protected - // doclets from inherited public resources are also filtered out. - evt.doclets = evt.doclets.filter( doclet => { - if ( !doclet.skipSource ) { - return true; - } - - if ( doclet.access === 'private' ) { - return false; - } - - if ( doclet.access === 'protected' ) { - return false; - } - - return true; - } ); - } - }, - - /** - * See http://usejsdoc.org/about-plugins.html#tag-definition. - * - * @param {any} dictionary - */ - defineTags( dictionary ) { - dictionary.defineTag( 'publicApi', { - mustHaveValue: false, - canHaveType: false, - canHaveName: false, - - /** - * @param {any} doclet - * @param {any} tag - */ - onTagged( doclet ) { - Object.assign( doclet, { - publicApi: true - } ); - } - } ); - } -}; - -function isPrivatePackageFile( fileName ) { - let dirName = path.dirname( fileName ); - - while ( true ) { - const pathToPackageJson = path.join( dirName, 'package.json' ); - - if ( fs.existsSync( pathToPackageJson ) ) { - return !!JSON.parse( fs.readFileSync( pathToPackageJson ).toString() ).private; - } - - dirName = path.dirname( dirName ); - - // Root's dirname is equal to the root, - // So if this check passes, then we should break this endless loop. - if ( dirName === path.dirname( dirName ) ) { - throw new Error( `${ fileName } is not placed inside the NPM project.` ); - } - } -} diff --git a/packages/jsdoc-plugins/lib/relation-fixer/addmissingdoclets.js b/packages/jsdoc-plugins/lib/relation-fixer/addmissingdoclets.js deleted file mode 100644 index 127beb890..000000000 --- a/packages/jsdoc-plugins/lib/relation-fixer/addmissingdoclets.js +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const getMissingDocletsData = require( './getmissingdocletsdata' ); -const DocletCollection = require( '../utils/doclet-collection' ); - -module.exports = addMissingDoclets; - -/** - * Adds missing doclets for members coming from implemented interfaces, extended classes, mixins and typedefs. - * It does also support inheriting static members and typedef inheritance, which both are not supported by the JSDoc. - * This function requires input to be preprocessed by the `buildRelations()` function. - * - * @param {Array.} doclets - * @returns {Array.} - */ -function addMissingDoclets( doclets ) { - const docletCollection = new DocletCollection(); - - for ( const doclet of doclets ) { - // Group doclets by memberof property. - docletCollection.add( `memberof:${ doclet.memberof }`, doclet ); - } - - const extensibleDoclets = doclets.filter( doclet => { - return ( - doclet.kind === 'class' || - doclet.kind === 'interface' || - doclet.kind === 'mixin' - ); - } ); - - /** @type {Array.} */ - const newDocletsToAdd = []; - - /** @type {Array.} */ - const docletsToIgnore = []; - - /** - * @type {Array.} - **/ - const options = [ - // Missing inherited items: - // - statics methods - // - methods - // - properties - // - events - { - relation: 'augmentsNested' - }, - - // Everything mixed, except existing mixed items. - { - relation: 'mixesNested', - onlyImplicitlyInherited: true - }, - - // Everything from implemented interfaces. - { - relation: 'implementsNested' - } - ]; - - const docletMap = createDocletMap( docletCollection ); - - for ( const extensibleDoclet of extensibleDoclets ) { - for ( const option of options ) { - const missingDocletsData = getMissingDocletsData( - docletMap, - docletCollection, - extensibleDoclet, - option - ); - - newDocletsToAdd.push( ...missingDocletsData.newDoclets ); - docletsToIgnore.push( ...missingDocletsData.docletsWhichShouldBeIgnored ); - } - } - - // Ignore doclets that shouldn't be used anymore. They will be removed afterward. - for ( const docletToIgnore of docletsToIgnore ) { - docletToIgnore.ignore = true; - } - - doclets = doclets.filter( doclet => !doclet.ignore ); - - const docletToAddMap = new Map( - newDocletsToAdd - .filter( d => !d.ignore ) - .map( d => [ d.longname, d ] ) - ); - - const existingDoclets = new Map( doclets.map( d => [ d.longname, d ] ) ); - - // The code here is hackish... - // We need to smartly determine which doclet should be get from the native JSDoc inheritance - // and which should be added from our custom inheritance mechanism. - return [ - ...doclets.filter( doclet => { - const willDocletBeAdded = docletToAddMap.has( doclet.longname ); - - // If the doclet has inherited property don't output it - // as it should be replaced by the parent's class/interface/mixin method doclet. - if ( willDocletBeAdded && doclet.inheritdoc === undefined ) { - return false; - } - - return true; - } ), - - // Do not output doclets that have its own documentation. - ...Array.from( docletToAddMap.values() ).filter( doclet => { - const existingDoclet = existingDoclets.get( doclet.longname ); - - if ( !existingDoclet ) { - return true; - } - - if ( existingDoclet.inheritdoc === undefined ) { - return true; - } - - return false; - } ) - ]; -} - -/** - * Creates a map. - * - * @param {DocletCollection} doclets - * @returns {Object} - */ -function createDocletMap( doclets ) { - const docletMap = {}; - - for ( const doclet of doclets.getAll() ) { - if ( !docletMap[ doclet.longname ] ) { - docletMap[ doclet.longname ] = doclet; - } - } - - return docletMap; -} diff --git a/packages/jsdoc-plugins/lib/relation-fixer/addtypedefproperties.js b/packages/jsdoc-plugins/lib/relation-fixer/addtypedefproperties.js deleted file mode 100644 index 08af430be..000000000 --- a/packages/jsdoc-plugins/lib/relation-fixer/addtypedefproperties.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const { cloneDeep } = require( 'lodash' ); - -module.exports = addTypedefProperties; - -/** - * It adds missing properties to doclet when in extends another doclets (with the `@extends` tag). - * Without modification on the original doclets it returns extended original doclets - * and new member doclets for each typedef property. - * - * @param {Array.} doclets - * @returns {Array.} - */ -function addTypedefProperties( doclets ) { - const typedefDoclets = doclets.filter( doclet => doclet.kind === 'typedef' ); - - // 1. Extend typedefs with missing properties. - doclets = doclets.map( doclet => { - if ( doclet.kind == 'typedef' ) { - return extendTypedef( doclet, typedefDoclets ); - } - - return doclet; - } ); - - // 2. Add doclets for typedef properties. - const typedefPropertyDoclets = createTypedefPropertyDoclets( typedefDoclets ); - - return [ - ...doclets, - ...typedefPropertyDoclets - ]; -} - -/** - * Copy properties from parent typedefs to typedefs which extend them. - * - * @param {Doclet} typedef - * @param {Array.} typedefDoclets - */ -function extendTypedef( typedef, typedefDoclets ) { - if ( !typedef.properties || !typedef.augmentsNested || !typedef.augmentsNested.length ) { - return typedef; - } - - // Prevent possible mutations. - typedef = cloneDeep( typedef ); - - for ( const parentLongname of typedef.augmentsNested ) { - const parentDoclet = typedefDoclets.find( doclet => doclet.longname === parentLongname ); - - if ( !parentDoclet ) { - console.error( `Base typedef (${ parentLongname }) for the ${ typedef.longname } typedef is missing.` ); - } - - if ( !parentDoclet.properties ) { - continue; - } - - for ( const parentProperty of parentDoclet.properties ) { - if ( !typedef.properties.find( p => p.name === parentProperty.name ) ) { - const inheritedProperty = cloneDeep( parentProperty ); - inheritedProperty.inherited = true; - typedef.properties.push( inheritedProperty ); - } - } - } - - return typedef; -} - -/** - * Creates and returns doclets for `@typedef` properties. - * - * @param {Array.} typedefDoclets - */ -function createTypedefPropertyDoclets( typedefDoclets ) { - const typedefPropertyDoclets = []; - - for ( const typedefDoclet of typedefDoclets ) { - for ( const property of typedefDoclet.properties || [] ) { - /** @type Doclet */ - const propertyDoclet = { - comment: property.description || '', - description: property.description, - - // Use the typedef's metadata. - meta: cloneDeep( typedefDoclet.meta ), - kind: 'member', - name: property.name, - type: property.type, - longname: typedefDoclet.longname + '#' + property.name, - scope: 'instance', - memberof: typedefDoclet.longname - }; - - typedefPropertyDoclets.push( propertyDoclet ); - } - } - - return typedefPropertyDoclets; -} diff --git a/packages/jsdoc-plugins/lib/relation-fixer/buildrelations.js b/packages/jsdoc-plugins/lib/relation-fixer/buildrelations.js deleted file mode 100644 index 91b20de74..000000000 --- a/packages/jsdoc-plugins/lib/relation-fixer/buildrelations.js +++ /dev/null @@ -1,163 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const { cloneDeep, uniq } = require( 'lodash' ); -const DocletCollection = require( '../utils/doclet-collection' ); -const RELATIONS = { - implements: 'implementsNested', - mixes: 'mixesNested', - augments: 'augmentsNested' -}; - -module.exports = buildRelations; - -/** - * Checks ascendants of every doclet and adds them to the relation array. - * Handles nested inheritance, mixins and implementation of interfaces. - * Also adds descendants to doclet. Descendants are entities that extend, implement or mix a doclet. - * For example: If ClassB extends ClassA and ClassA implements InterfaceC, - * ClassB and ClassA will have a property 'implementsNested': [ 'InterfaceC' ], - * also InterfaceC will have a property 'descendants': [ 'ClassA', 'ClassB' ] etc. - * - * @param {Array.} doclets - * @returns {Array.} - */ -function buildRelations( doclets ) { - // Preserve original doclets from modification for easier testing. - doclets = cloneDeep( doclets ); - - /** - * Doclets grouped by their longnames. - */ - const docletCollection = new DocletCollection(); - - for ( const doclet of doclets ) { - docletCollection.add( doclet.longname, doclet ); - } - - /** - * An array of doclets, for which we want to create relation arrays. - */ - const subjectDoclets = doclets.filter( item => { - return ( - item.kind === 'class' || - item.kind === 'interface' || - item.kind === 'mixin' || - item.kind === 'typedef' - ); - } ); - - for ( const doclet of subjectDoclets ) { - const related = getAncestors( docletCollection, doclet, { - relations: [ 'augments', 'implements', 'mixes' ] - } ); - - // Remove duplicates. - for ( const relation of Object.keys( related ) ) { - related[ relation ] = uniq( related[ relation ] ); - } - - Object.assign( doclet, related ); - } - - for ( const doclet of subjectDoclets ) { - doclet.descendants = uniq( getDescendants( subjectDoclets, doclet ) ); - } - - return doclets; -} - -/** - * Gets long names of the current doclet ancestors (classes it extends, interfaces it implements and so on). - * - * @param {DocletCollection} docletCollection Doclets grouped by their longnames - * @param {Doclet} currentDoclet - * @param {Object} options - * @param {Array.<'augments'|'implements'|'mixes'>} options.relations An array of relation names which should be used. - * @returns {Object} An object containing arrays of ancestors' longnames. - */ -function getAncestors( docletCollection, currentDoclet, options ) { - const { relations } = options; - - /** @type {Object} */ - const resultRelations = {}; - - // Initialize the returned object. - for ( const baseRelation of relations ) { - resultRelations[ RELATIONS[ baseRelation ] ] = []; - } - - // For every relation take doclets which are related to current doclet and run `getAncestors` function on them recursively. - for ( const baseRelation of relations ) { - const relation = RELATIONS[ baseRelation ]; - - if ( isEmpty( currentDoclet[ baseRelation ] ) ) { - continue; - } - - resultRelations[ relation ].push( ...currentDoclet[ baseRelation ] ); - - for ( const longname of currentDoclet[ baseRelation ] ) { - const ancestors = docletCollection.get( longname ); - - for ( const ancestor of ancestors ) { - const ancestorsResultRelations = getAncestors( docletCollection, ancestor, { - relations - } ); - - // Push relation arrays of doclet's ancestors to current doclet resultRelations. - for ( const key of Object.keys( resultRelations ) ) { - // Only items of same kind can be put in inheritance tree. See #361. - if ( key === 'augmentsNested' && ancestor.kind !== currentDoclet.kind ) { - continue; - } - - resultRelations[ key ].push( ...ancestorsResultRelations[ key ] ); - } - } - } - } - - return resultRelations; -} - -/** - * Returns `true` when the input in equal to `undefined` or is an empty array. - * - * @param {Array|undefined} arr - */ -function isEmpty( arr ) { - return !arr || arr.length === 0; -} - -/** - * Gets long names of descendants – i.e. entities which extend, implement or mix a doclet. - * - * @param {Array.} searchedDoclets - * @param {Doclet} currentDoclet - * @returns {Array.} An array of long names. - */ -function getDescendants( searchedDoclets, currentDoclet ) { - /** @type {Set.} */ - const descendants = new Set(); - - for ( const doclet of searchedDoclets ) { - for ( const baseRelation in RELATIONS ) { - const relation = RELATIONS[ baseRelation ]; - - if ( - !isEmpty( doclet[ relation ] ) && - doclet[ relation ].includes( currentDoclet.longname ) - ) { - descendants.add( doclet.longname ); - break; - } - } - } - - return Array.from( descendants ); -} diff --git a/packages/jsdoc-plugins/lib/relation-fixer/filteroutintenraldoclets.js b/packages/jsdoc-plugins/lib/relation-fixer/filteroutintenraldoclets.js deleted file mode 100644 index 2414572e1..000000000 --- a/packages/jsdoc-plugins/lib/relation-fixer/filteroutintenraldoclets.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -/** - * Filters out doclet that won't be displayed. - * - * @param {Array.} doclets - */ -module.exports = function filterOutInternalDoclets( doclets ) { - return doclets - .filter( doclet => !doclet.ignore ) - .filter( doclet => doclet.memberof != '' ); -}; diff --git a/packages/jsdoc-plugins/lib/relation-fixer/getmissingdocletsdata.js b/packages/jsdoc-plugins/lib/relation-fixer/getmissingdocletsdata.js deleted file mode 100644 index e695d6bb7..000000000 --- a/packages/jsdoc-plugins/lib/relation-fixer/getmissingdocletsdata.js +++ /dev/null @@ -1,211 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const { cloneDeep } = require( 'lodash' ); - -module.exports = getMissingDocletsData; - -/** - * Gets missing doclets of members coming from implemented interfaces, extended classes, mixins and typedefs. - * It returns also doclets which should be ignored as no longer necessary. - * This function requires input to be preprocessed by the `buildRelations()` function. - * - * @param {Map.} docletMap - * @param {DocletCollection} docletCollection - * @param {Doclet} interfaceClassOrMixinDoclet Doclet representing an entity which might have some inherited members missing. - * @param {Options} options - * @returns {{newDoclets: Array., docletsWhichShouldBeIgnored: Array.}} - */ -function getMissingDocletsData( docletMap, docletCollection, interfaceClassOrMixinDoclet, options ) { - const newDoclets = []; - const docletsWhichShouldBeIgnored = []; - - const docletsToAdd = getDocletsToAdd( docletCollection, interfaceClassOrMixinDoclet, options ); - - for ( const docletToAdd of docletsToAdd ) { - const clonedDoclet = cloneDeep( docletToAdd ); - - clonedDoclet.longname = getLongnameForNewDoclet( docletToAdd, interfaceClassOrMixinDoclet ); - clonedDoclet.memberof = interfaceClassOrMixinDoclet.longname; - - // Add property `inherited` or `mixed`. - const relationProperty = getRelationProperty( docletMap, interfaceClassOrMixinDoclet, docletToAdd, options.relation ); - - if ( relationProperty ) { - clonedDoclet[ relationProperty ] = true; - } - - const docletsOfSameMember = docletCollection.get( `memberof:${ clonedDoclet.memberof }` ).filter( d => { - // Different types, so avoid comparing their names. - if ( d.kind !== clonedDoclet.kind ) { - return false; - } - - // Static members are separated using the dot character. - const docletName = d.name.replace( /^[#.]/, '' ); - const clonedDocletName = clonedDoclet.name.replace( /^[#.]/, '' ); - - return docletName === clonedDocletName; - } ); - - if ( docletsOfSameMember.length === 0 ) { - // If there was no doclet for that member, simply add it to new doclets. - newDoclets.push( clonedDoclet ); - } else if ( doAllParentsExplicitlyInherit( docletsOfSameMember ) && !options.onlyImplicitlyInherited ) { - // If all doclets in the chain for that member already existed and used `inheritdoc` or `overrides`. - // Add `ignore` property to existing doclets. Unless 'onlyImplicitlyInherited' option is set. - docletsWhichShouldBeIgnored.push( ...docletsOfSameMember ); - - newDoclets.push( clonedDoclet ); - } else if ( docletsOfSameMember.length >= 2 ) { - const correctDoclet = cloneDeep( docletsOfSameMember[ 0 ] ); - - correctDoclet[ relationProperty ] = true; - - docletsWhichShouldBeIgnored.push( ...docletsOfSameMember ); - newDoclets.push( correctDoclet ); - } - } - - return { - newDoclets, - docletsWhichShouldBeIgnored - }; -} - -/** - * Gets doclets from entities related to current doclet (e.g. implemented by it) - * and matching criteria given via the `options.filter` query. - * - * @param {DocletCollection} docletCollection - * @param {Doclet} childDoclet - * @param {Options} options - * @returns {Array.} - */ -function getDocletsToAdd( docletCollection, childDoclet, options ) { - // Longnames of doclets which are related ( extended, mixed, implemented ) to childDoclet. - const ancestors = childDoclet[ options.relation ] || []; - - /** @type {Array.} */ - const docletsToAdd = []; - - for ( const ancestor of ancestors ) { - docletsToAdd.push( - ...docletCollection - .get( `memberof:${ ancestor }` ) - .filter( doclet => shouldDocletBeAdded( doclet, options ) ) - ); - } - - return docletsToAdd; -} - -/** - * @param {Doclet} doclet - * @param {Object} options - */ -function shouldDocletBeAdded( doclet, options ) { - // Filter out ignored, inherited, undocumented. - if ( - doclet.ignore || - doclet.undocumented || - typeof doclet.inheritdoc == 'string' - ) { - return false; - } - - for ( const key of Object.keys( options.filter || {} ) ) { - if ( doclet[ key ] !== options.filter[ key ] ) { - return false; - } - } - - return true; -} - -/** - * @param {Doclet} parentDoclet - * @param {Doclet} childDoclet - * @returns {String} - */ -function getLongnameForNewDoclet( parentDoclet, childDoclet ) { - const dotIndex = parentDoclet.longname.lastIndexOf( '.' ); - const hashIndex = parentDoclet.longname.lastIndexOf( '#' ); - const name = parentDoclet.longname.slice( Math.max( dotIndex, hashIndex ) ); - - return childDoclet.longname + name; -} - -/** - * Gets property which should be added to the new doclet (e.g. `inherited` or `mixed`). - * - * @param {Map.} docletMap - * @param {Doclet} childDoclet - * @param {Doclet} memberDoclet - * @param {'augmentsNested'|'mixesNested'|'implementsNested'} relation - * @returns {'inherited'|'mixed'|null} - */ -function getRelationProperty( docletMap, childDoclet, memberDoclet, relation ) { - if ( relation === 'augmentsNested' ) { - return 'inherited'; - } - - if ( relation === 'mixesNested' ) { - return 'mixed'; - } - - const memberDocletParent = docletMap[ memberDoclet.memberof ]; - - let isInherited = false; - let isMixed = false; - - // If doclet is a child of a mixin, it's 'mixed'. Else if it's a child of another class, it's 'inherited'. - for ( const longname of memberDocletParent.descendants || [] ) { - const doclet = docletMap[ longname ]; - - if ( !doclet || !doclet.descendants || !doclet.descendants.includes( childDoclet.longname ) ) { - continue; - } - - if ( doclet.kind === 'mixin' ) { - isMixed = true; - } else if ( doclet.kind === 'class' ) { - isInherited = true; - } - } - - if ( isMixed ) { - return 'mixed'; - } else if ( isInherited ) { - return 'inherited'; - } else { - return null; - } -} - -/** - * @param {Array.} doclets - * @returns {Boolean} - */ -function doAllParentsExplicitlyInherit( doclets ) { - for ( const doclet of doclets ) { - if ( doclet.inheritdoc === undefined && doclet.overrides === undefined ) { - return false; - } - } - - return true; -} - -/** - * @typedef {Object} Options - * - * @property {'augmentsNested'|'mixesNested'|'implementsNested'} relation Name of relation between child entity - * and its ancestors. - * @property {Partial} [filter] Object used to filter missing doclets (e.g. { scope: 'static' }). - * @property {Boolean} [onlyImplicitlyInherited] - */ diff --git a/packages/jsdoc-plugins/lib/relation-fixer/index.js b/packages/jsdoc-plugins/lib/relation-fixer/index.js deleted file mode 100644 index 7602c8b84..000000000 --- a/packages/jsdoc-plugins/lib/relation-fixer/index.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const buildRelations = require( './buildrelations' ); -const addMissingDoclets = require( './addmissingdoclets' ); -const filterOutInternalDoclets = require( './filteroutintenraldoclets' ); -const addTypedefProperties = require( './addtypedefproperties' ); - -exports.handlers = { - processingComplete( e ) { - e.doclets = precleanInheritance( e.doclets ); - e.doclets = buildRelations( e.doclets ); - e.doclets = addTypedefProperties( e.doclets ); - e.doclets = addMissingDoclets( e.doclets ); - e.doclets = filterOutInternalDoclets( e.doclets ); - } -}; - -/** - * Revert missing doclets that were marked as ignored. - * Remove ignored doclets. - * - * @param {Array.} doclets - */ -function precleanInheritance( doclets ) { - // Group doclet by longnames - /** @type {Map.>} */ - const docletMap = new Map(); - - for ( const doclet of doclets ) { - const docletsWithTheSameName = docletMap.get( doclet.longname ) || []; - - docletMap.set( doclet.longname, [ ...docletsWithTheSameName, doclet ] ); - } - - for ( const doclets of docletMap.values() ) { - if ( doclets.length === 1 ) { - continue; - } - - const ignoredOriginalDoclet = doclets.find( d => d.ignore && !d.mixed && !d.inherited ); - const restDoclets = doclets.filter( d => d !== ignoredOriginalDoclet ); - - if ( ignoredOriginalDoclet && restDoclets.every( d => d.inherited || d.mixed ) ) { - for ( const doclet of restDoclets ) { - doclet.ignore = true; - } - - delete ignoredOriginalDoclet.ignore; - } - - if ( doclets.some( d => !!d.comment ) ) { - for ( const doclet of doclets ) { - if ( !doclet.comment ) { - doclet.ignore = true; - } - } - } - } - - // Filter out member doclets that miss their comments. - for ( const doclet of doclets ) { - if ( ( doclet.kind === 'member' || doclet.kind === 'function' ) && ( doclet.inheritdoc === '' || !doclet.comment ) ) { - if ( doclet.name !== 'constructor' ) { - doclet.ignore = true; - } - } - } - - doclets = doclets.filter( d => !d.ignore ); - - return doclets; -} diff --git a/packages/jsdoc-plugins/lib/utils/doclet-collection.js b/packages/jsdoc-plugins/lib/utils/doclet-collection.js deleted file mode 100644 index 8a8dfb441..000000000 --- a/packages/jsdoc-plugins/lib/utils/doclet-collection.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -/** - * Collection of doclets as > pairs. Also stores all doclets and their longnames as arrays. - */ -module.exports = class DocletCollection { - /** - * Creates collection of doclets. - */ - constructor() { - this._data = {}; - this._allData = []; - this._allLongnames = []; - } - - /** - * Adds doclet to collection. - * - * @param {String} category - * @param {Doclet} doclet - */ - add( category, doclet ) { - if ( !this._data[ category ] ) { - this._data[ category ] = []; - } - - this._data[ category ].push( doclet ); - this._allData.push( doclet ); - - if ( doclet.longname ) { - this._allLongnames.push( doclet.longname ); - } - } - - /** - * Returns doclets filtered by category. - * - * @param {String} category - * @returns {Array.} - */ - get( category ) { - return this._data[ category ] || []; - } - - /** - * Returns all doclets. - * - * @returns {Array.} - */ - getAll() { - return this._allData; - } - - /** - * Returns all longnames. - * - * @returns {Array.} - */ - getAllLongnames() { - return this._allLongnames; - } -}; diff --git a/packages/jsdoc-plugins/lib/utils/doclet-logger.js b/packages/jsdoc-plugins/lib/utils/doclet-logger.js deleted file mode 100644 index ada4c59b4..000000000 --- a/packages/jsdoc-plugins/lib/utils/doclet-logger.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const fsExtra = require( 'fs-extra' ); -const path = require( 'path' ); - -/** - * Created for testing purpose. - * You can add / remove this plugin in src/tasks/build-api-docs.js - */ -exports.handlers = { - processingComplete( e ) { - const outputPath = process.env.JSDOC_OUTPUT_PATH; - - fsExtra.outputFileSync( path.resolve( outputPath ), JSON.stringify( e, null, 4 ) ); - } -}; diff --git a/packages/jsdoc-plugins/lib/validator/doclet-validator.js b/packages/jsdoc-plugins/lib/validator/doclet-validator.js deleted file mode 100644 index e3ee96b89..000000000 --- a/packages/jsdoc-plugins/lib/validator/doclet-validator.js +++ /dev/null @@ -1,487 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const DocletCollection = require( '../utils/doclet-collection' ); -const { ALL_TYPES, GENERIC_TYPES } = require( './types' ); - -const complexTypeRegExp = /^([\w]+)\.<\(?([^)^>]+)\)?>$/; - -/** - * Main validation class - */ -class DocletValidator { - /** - * Creates DocletLinter - */ - constructor( doclets ) { - /** - * Errors found during the validation. - * - * @type {Array.} - * @public - * @readonly - * */ - this.errors = []; - - /** - * Doclets grouped by doclet's `kind` property. - * - * @private - */ - this._collection = this._createDocletCollection( doclets ); - - /** - * The `longname` -> `doclet` map of doclets. - * - * @type {Record.} - */ - this._docletMap = createDocletMap( doclets ); - } - - /** - * Creates doclets grouped by doclet kind. - * - * @private - * @returns {DocletCollection} - */ - _createDocletCollection( doclets ) { - const collection = new DocletCollection(); - - for ( const doclet of doclets ) { - collection.add( doclet.kind, doclet ); - } - - return collection; - } - - /** - * Returns errors found during the validation. - * - * @public - * @returns {Array.} - */ - validate() { - this.errors.length = 0; - - this._validateMembers(); - this._validateMemberofProperty(); - this._validateLongnamePropertyInClasses(); - this._validateParameters(); - this._validateLinks(); - this._validateEvents(); - this._validateInterfaces(); - this._validateModuleDocumentedExports(); - this._validateReturnTypes(); - this._validateSeeReferences(); - this._validateTypedefs(); - this._validateExtensibility(); - this._checkDuplicatedDoclets(); - - return this.errors; - } - - /** - * Finds incorrectly documented members. - * - * @protected - */ - _validateMembers() { - this._collection.get( 'member' ) - .filter( member => member.name.startsWith( 'module:' ) ) - .filter( member => member.scope === 'inner' ) - .forEach( member => this._addError( member, `Incorrect member name: ${ member.name }` ) ); - } - - /** - * @protected - */ - _validateMemberofProperty() { - this._collection.getAll() - .filter( doclet => doclet.memberof && !doclet.memberof.startsWith( 'module:' ) ) - .forEach( doclet => { - this._addError( doclet, `Memberof property should start with 'module:'. Got '${ doclet.memberof }' instead.` ); - } ); - } - - /** - * @protected - */ - _validateLongnamePropertyInClasses() { - this._collection.getAll() - .filter( doclet => doclet.longname ) - .filter( doclet => { - const match = doclet.longname.match( /~([\w]+)\.([\w]+)$/ ); // e.g module:utils/ckeditorerror~CKEditorError.CKEditorError - - return match && match[ 1 ] === match[ 2 ]; - } ) - .forEach( doclet => { - this._addError( doclet, `Incorrect class reference name. No doclet exists with the following name: ${ doclet.longname }` ); - } ); - } - - /** - * @protected - */ - _validateLongnameProperty() { - this._collection.getAll() - .filter( doclet => doclet.longname && !doclet.longname.startsWith( 'module:' ) ) - .forEach( doclet => { - this._addError( doclet, `Longname property should start with the 'module:' part. Got ${ doclet.longname } instead.` ); - } ); - } - - /** - * Finds errors in parameter types. - * - * @protected - */ - _validateParameters() { - for ( const doclet of this._collection.getAll() ) { - for ( const param of doclet.params || [] ) { - this._validateParameter( doclet, param ); - } - } - } - - /** - * @private - * - * @param {Doclet} doclet - * @param {Object} param - */ - _validateParameter( doclet, param ) { - if ( !param.type ) { - // Skip not typed parameters. - return; - } - - for ( const paramFullName of param.type.names || [] ) { - if ( !this._isCorrectType( paramFullName ) ) { - this._addError( doclet, `Incorrect param type: ${ paramFullName }` ); - } - } - } - - /** - * Finds errors in links. - * - * @protected - */ - _validateLinks() { - const allLinkRegExp = /\{@link\s+[^}]+\}/g; - const pathRegExp = /^\{@link\s+([^}\s]+)[^}]*\}$/; - - const optionalTagWithBracedContentRegExp = /(@[a-z]+ )?\{[^}]+\}/g; - - for ( const doclet of this._collection.getAll() ) { - if ( !doclet.comment ) { - continue; - } - - // Find all missing `@link` parts inside comments. - for ( const commentPart of doclet.comment.match( optionalTagWithBracedContentRegExp ) || [] ) { - if ( commentPart.startsWith( '{module:' ) ) { - // If the comment part starts with the '{module:' it means that: - // * it's not a normal tag (tags starts with `@` and the tagName). - // * it's not a link (the part misses the `@link` part), but it supposed to be (it contains the `module:` part). - this._addError( doclet, `Link misses the '@link' part: ${ commentPart }` ); - } - } - - const refs = ( doclet.comment.match( allLinkRegExp ) || [] ) - .map( link => link.match( pathRegExp )[ 1 ] ); - - for ( const ref of refs ) { - if ( !this._isCorrectReference( ref ) ) { - this._addError( doclet, `Incorrect link: ${ ref }` ); - } - } - } - } - - /** - * Finds errors in the 'fires' tag. - * - * @protected - */ - _validateEvents() { - const eventNames = this._collection.get( 'event' ).map( event => event.longname ); - - for ( const doclet of this._collection.getAll() ) { - for ( const event of doclet.fires || [] ) { - if ( !eventNames.includes( event ) ) { - this._addError( doclet, `Incorrect event name: ${ event } in @fires tag` ); - } - } - } - } - - /** - * Finds errors in the 'implements' tag. - * - * @protected - */ - _validateInterfaces() { - const classesAndMixins = [ ...this._collection.get( 'class' ), ...this._collection.get( 'mixin' ) ]; - const interfaceLongNames = this._collection.get( 'interface' ) - .map( i => i.longname ); - - for ( const someClassOrMixin of classesAndMixins ) { - for ( const someInterface of someClassOrMixin.implements || [] ) { - if ( !interfaceLongNames.includes( someInterface ) ) { - this._addError( someClassOrMixin, `Incorrect interface name: ${ someInterface }` ); - } - } - } - } - - /** - * @protected - */ - _validateModuleDocumentedExports() { - const memberDoclets = this._collection.get( 'member' ) - .filter( member => member.scope === 'inner' ) - .filter( member => !member.undocumented ); - - for ( const member of memberDoclets ) { - if ( this._docletMap[ member.memberof ] && this._docletMap[ member.memberof ].kind === 'module' ) { - this._addError( member, `Module ${ member.memberof } exports member: ${ member.name }` ); - } - } - } - - /** - * @protected - */ - _validateReturnTypes() { - const doclets = this._collection.getAll() - .filter( doclet => !!doclet.returns ); - - for ( const doclet of doclets ) { - if ( !doclet.returns[ 0 ].type ) { - this._addError( doclet, 'Invalid return type.' ); - continue; - } - - for ( const typeName of doclet.returns[ 0 ].type.names ) { - if ( !this._isCorrectType( typeName ) ) { - this._addError( doclet, `Invalid return type: ${ typeName }.` ); - } - } - } - } - - /** - * @protected - */ - _validateSeeReferences() { - for ( const doclet of this._collection.getAll() ) { - for ( const seeReference of doclet.see || [] ) { - if ( !this._isCorrectReference( seeReference ) ) { - this._addError( doclet, `Invalid @see reference: ${ seeReference }.` ); - } - } - } - } - - /** - * @protected - */ - _validateTypedefs() { - for ( const doclet of this._collection.getAll() ) { - for ( const prop of doclet.properties || [] ) { - for ( const typeName of prop.type.names ) { - if ( !this._isCorrectType( typeName ) ) { - this._addError( doclet, `Invalid @property type: ${ typeName }.` ); - } - } - } - } - } - - /** - * Checks whether the reference in the `@extends` tag is correct. - * - * @protected - */ - _validateExtensibility() { - for ( const doclet of this._collection.getAll() ) { - for ( const base of doclet.augments || [] ) { - if ( !this._isCorrectReference( base ) && !this._isValidBuiltInType( base ) ) { - this._addError( - doclet, - `Invalid @extends reference: ${ base }.` - ); - } - } - } - - for ( const doclet of this._collection.getAll() ) { - for ( const base of doclet.implements || [] ) { - const baseDoclet = this._docletMap[ base ]; - - // TODO: We should only allow interfaces here. - if ( !baseDoclet || ![ 'interface', 'function' ].includes( baseDoclet.kind ) ) { - this._addError( - doclet, - `Invalid @implements reference: ${ base } - no found doclet or doclet is not an interface.` - ); - } - } - } - } - - _checkDuplicatedDoclets() { - const docletLongNames = new Set(); - - for ( const doclet of this._collection.getAll() ) { - // Skip modules. - // Module descriptions are mergeable. - if ( doclet.kind === 'module' ) { - continue; - } - - if ( docletLongNames.has( doclet.longname ) ) { - this._addError( doclet, 'Duplicated doclets with longname: ' + doclet.longname ); - } - - docletLongNames.add( doclet.longname ); - } - } - - /** - * @private - * @param {Doclet} doclet - * @param {string} errorMessage - */ - _addError( doclet, errorMessage ) { - this.errors.push( Object.assign( { - message: errorMessage - }, this._getErrorData( doclet ) ) ); - } - - /** - * @private - * @param {Doclet} doclet - */ - _getErrorData( doclet ) { - return { - parent: doclet.memberof, - line: doclet.meta.lineno, - file: doclet.meta.path + '/' + doclet.meta.filename - }; - } - - /** - * Naive implementation of simple parser. - * - * @protected - * @param {String} type to assert - * - * @returns {Boolean} - */ - _isCorrectType( type ) { - // JSDoc converts `Type.` to `Type.` for some reason... - type = type.replace( 'function()', 'function' ); - - if ( complexTypeRegExp.test( type ) ) { - const [ , genericType, innerType ] = type.match( complexTypeRegExp ); - - return GENERIC_TYPES.includes( genericType ) && this._isCorrectType( innerType ); - } - - if ( type.includes( '|' ) ) { - return type.split( '|' ).every( unionType => this._isCorrectType( unionType ) ); - } - - if ( type.includes( ',' ) ) { - return type.split( ',' ).every( type => this._isCorrectType( type ) ); - } - - if ( type.includes( 'module:' ) ) { - return this._isCorrectReferenceType( type ); - } - - type = type.trim(); - - return this._isValidBuiltInType( type ) || - this._isStringLiteralType( type ); - } - - /** @private */ - _isValidBuiltInType( type ) { - return ALL_TYPES.includes( type ); - } - - /** - * A string literal type - e.g. 'forward' or 'backward'; - * - * @private - */ - _isStringLiteralType( type ) { - return /^'[^']+'$/.test( type ); - } - - /** - * @private - * @param {String} type - */ - _isCorrectReference( type ) { - type = type.trim(); - - if ( !type.includes( 'module:' ) ) { - return false; - } - - return !!this._docletMap[ type ]; - } - - /** - * Returns `true` when the reference points to the symbol which is one of: - * * `class` - * * `interface` - * * `typedef` - * * `function` - * - * @private - * @param {String} type - */ - _isCorrectReferenceType( type ) { - type = type.trim(); - - if ( !type.includes( 'module:' ) ) { - return false; - } - - const doclet = this._docletMap[ type ]; - - if ( !doclet ) { - return false; - } - - return doclet.kind === 'class' || - doclet.kind === 'interface' || - doclet.kind === 'typedef' || - doclet.kind === 'function'; - } -} - -/** - * @param {Array.} doclets - */ -function createDocletMap( doclets ) { - /** @type {Record.} */ - const docletMap = {}; - - for ( const doclet of doclets ) { - docletMap[ doclet.longname ] = doclet; - } - - return docletMap; -} - -module.exports = DocletValidator; diff --git a/packages/jsdoc-plugins/lib/validator/types.js b/packages/jsdoc-plugins/lib/validator/types.js deleted file mode 100644 index 7ffb53ab5..000000000 --- a/packages/jsdoc-plugins/lib/validator/types.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const BASIC_TYPES = [ - // Wildcard - '*', - - // ES types - 'null', - 'undefined', - 'String', - 'Number', - 'Boolean', - 'Object', - 'Error', - 'Function', - 'function', // JSDoc renames Function into function. - 'RegExp', - 'Symbol', - 'Date', - - // DOM API - 'Node', - 'NodeList', - 'HTMLElement', - 'Document', - 'Element', - 'DocumentFragment', - 'Text', - 'Range', - 'Selection', - 'Event', - 'FocusEvent', - 'ClientRect', - 'DOMRect', - 'Window', - 'ErrorEvent', - 'PromiseRejectionEvent', - 'Blob', - - // Web APIs - 'File', - 'DataTransfer', - 'FormData', - 'URL' -]; - -const GENERIC_TYPES = [ - 'Array', - 'Set', - 'Map', - 'WeakMap', - 'WeakSet', - 'Promise', - 'Uint8Array', - 'Uint16Array', - 'Uint32Array', - 'Int8Array', - 'Int16Array', - 'Int32Array', - - // Object treated as a dictionary, e.g. Object.. - 'Object', - - // Object that contains a [Symbol.iterator]() method. - 'Iterable', - - // Object that contains next() method and satisfies the Iterator protocol. - // https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Iteration_protocols - 'Iterator' -]; - -module.exports = { - BASIC_TYPES, - GENERIC_TYPES, - ALL_TYPES: [ ...BASIC_TYPES, ...GENERIC_TYPES ] -}; diff --git a/packages/jsdoc-plugins/lib/validator/validator.js b/packages/jsdoc-plugins/lib/validator/validator.js deleted file mode 100644 index 4b7109a04..000000000 --- a/packages/jsdoc-plugins/lib/validator/validator.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -/** - * @see http://usejsdoc.org/about-plugins.html - */ - -const DocletValidator = require( './doclet-validator' ); -const logger = require( 'jsdoc/util/logger' ); - -exports.handlers = { - processingComplete( e ) { - const isValidateOnly = Boolean( process.env.JSDOC_VALIDATE_ONLY ); - const isStrictCheck = Boolean( process.env.JSDOC_STRICT_CHECK ); - - const validator = new DocletValidator( e.doclets ); - const errors = validator.validate(); - - // Prints only first 50 errors to stdout. - printErrors( errors, 50 ); - - // Mark the process as ended with error. - if ( errors.length ) { - process.exitCode = 1; - - if ( isValidateOnly || isStrictCheck ) { - return logger.fatal( 'Since the process is being executed in strict or checking mode, aborting due to errors.' ); - } - } - - if ( isValidateOnly ) { - process.exit(); - } - } -}; - -function printErrors( errors, maxSize ) { - const errorMessages = []; - - if ( errors.length === 0 ) { - process.stdout.write( 'No errors found during the validation.' ); - - return; - } - - for ( const error of errors.slice( 0, maxSize ) ) { - errorMessages.push( error.message ); - errorMessages.push( `\tat ${ error.file }:${ error.line }\n` ); - } - - errorMessages.push( '\nValidation Summary:' ); - errorMessages.push( `* Validator found ${ errors.length } errors.\n` ); - - if ( errors.length > maxSize ) { - errorMessages.push( `* ${ errors.length - maxSize } errors not shown in the console.` ); - } - - process.stderr.write( errorMessages.join( '\n' ) ); -} diff --git a/packages/jsdoc-plugins/package.json b/packages/jsdoc-plugins/package.json deleted file mode 100644 index 3b5d6846e..000000000 --- a/packages/jsdoc-plugins/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@ckeditor/jsdoc-plugins", - "version": "43.0.0", - "description": "Various JSDoc plugins developed by the CKEditor 5 team.", - "keywords": [ - "jsdoc", - "jsdoc3", - "plugins", - "ckeditor", - "validator", - "validation", - "short references", - "inheritance" - ], - "author": "CKSource (http://cksource.com/)", - "license": "MIT", - "homepage": "https://github.com/ckeditor/ckeditor5-dev/tree/master/packages/jsdoc-plugins", - "bugs": "https://github.com/ckeditor/ckeditor5/issues", - "repository": { - "type": "git", - "url": "https://github.com/ckeditor/ckeditor5-dev.git", - "directory": "packages/jsdoc-plugins" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=5.7.1" - }, - "files": [ - "lib" - ], - "dependencies": { - "fs-extra": "^11.2.0", - "lodash": "^4.17.15", - "jsdoc": "ckeditor/jsdoc#fixed-trailing-comment-doclets" - }, - "devDependencies": { - "chai": "^4.2.0", - "glob": "^10.2.5", - "mocha": "^7.1.2", - "tmp": "^0.2.1", - "upath": "^2.0.1" - }, - "scripts": { - "test": "mocha './tests/**/*.js' --timeout 10000", - "coverage": "nyc --reporter=lcov --reporter=text-summary yarn run test" - } -} diff --git a/packages/jsdoc-plugins/tests/comment-fixer.js b/packages/jsdoc-plugins/tests/comment-fixer.js deleted file mode 100644 index 01c297b73..000000000 --- a/packages/jsdoc-plugins/tests/comment-fixer.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; diff --git a/packages/jsdoc-plugins/tests/convert-short-refs-to-full-refs.js b/packages/jsdoc-plugins/tests/convert-short-refs-to-full-refs.js deleted file mode 100644 index c72fb85de..000000000 --- a/packages/jsdoc-plugins/tests/convert-short-refs-to-full-refs.js +++ /dev/null @@ -1,529 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const chai = require( 'chai' ); -const expect = chai.expect; -const convertShortRefsToFullRefs = require( '../lib/longname-fixer/fixers/convert-short-refs-to-full-refs' ); - -describe( 'jsdoc-plugins/longname-fixers/convert-short-refs-to-full-refs', () => { - it( 'should convert interface method short refs to full refs', () => { - /** @type {Array.} */ - const doclets = [ { - kind: 'interface', - memberof: 'module:editor/editorinterface', - longname: 'module:editor/editorinterface~EditorInterface', - name: 'EditorInterface', - meta: { - path: 'editor/', - filename: 'interface.js', - lineno: 20 - }, - comment: '', - description: '' - }, { - kind: 'function', - meta: { - path: 'editor/', - filename: 'interface.js', - lineno: 30 - }, - longname: '#destroy', - memberof: 'module:editor/editorinterface~EditorInterface', - name: 'destroy', - comment: '', - description: '' - } ]; - - convertShortRefsToFullRefs( doclets ); - - expect( doclets[ 1 ].memberof ).to.be.equal( 'module:editor/editorinterface~EditorInterface' ); - expect( doclets[ 1 ].longname ).to.be.equal( 'module:editor/editorinterface~EditorInterface#destroy' ); - } ); - - it( 'should convert mixin method short refs to full refs', () => { - /** @type {Array.} */ - const doclets = [ { - kind: 'mixin', - memberof: 'module:editor/editormixin', - longname: 'module:editor/editormixin~EditorMixin', - name: 'EditorMixin', - meta: { - path: 'editor/', - filename: 'editormixin.js', - lineno: 20 - }, - comment: '', - description: '' - }, - { - kind: 'function', - meta: { - path: 'editor/', - filename: 'editormixin.js', - lineno: 30 - }, - longname: '#destroy', - memberof: 'module:editor/editormixin~EditorMixin', - name: 'destroy', - comment: '', - description: '' - } ]; - - convertShortRefsToFullRefs( doclets ); - - expect( doclets[ 1 ].memberof ).to.be.equal( 'module:editor/editormixin~EditorMixin' ); - expect( doclets[ 1 ].longname ).to.be.equal( 'module:editor/editormixin~EditorMixin#destroy' ); - } ); - - it( 'should not convert short refs if the memberof differs', () => { - /** @type {Array.} */ - const doclets = [ { - kind: 'interface', - memberof: 'module:editor/editorinterface', - longname: 'module:editor/editorinterface~EditorInterface', - name: 'EditorInterface', - meta: { - path: '/', - filename: 'interface.js', - lineno: 20 - }, - comment: '', - description: '' - }, - { - kind: 'function', - meta: { - path: '/', - filename: 'interface.js', - lineno: 30 - }, - longname: 'module:someModule~SomeOtherClass#destroy', - memberof: 'module:someModule~SomeOtherClass', - name: 'destroy', - comment: '', - description: '' - } ]; - - convertShortRefsToFullRefs( doclets ); - - expect( doclets[ 1 ].memberof ).to.be.equal( 'module:someModule~SomeOtherClass' ); - expect( doclets[ 1 ].longname ).to.be.equal( 'module:someModule~SomeOtherClass#destroy' ); - } ); - - it( 'should fix class members starting with the `~` character', () => { - /** @type {Array.} */ - const doclets = [ { - kind: 'class', - memberof: 'module:editor', - longname: 'module:editor~Editor', - name: 'Editor', - meta: { - path: '/', - filename: 'editor.js', - lineno: 20 - }, - comment: '', - description: '' - }, - { - kind: 'member', - meta: { - path: '/', - filename: 'editor.js', - lineno: 30 - }, - longname: '~Editor#name', - memberof: 'module:editor~Editor', - name: 'name', - comment: '', - description: '' - } ]; - - convertShortRefsToFullRefs( doclets ); - - expect( doclets[ 1 ].longname ).to.be.equal( 'module:editor~Editor#name' ); - expect( doclets[ 1 ].memberof ).to.be.equal( 'module:editor~Editor' ); - } ); - - it( 'should convert short event names to full names if the event is declared after the class/mixin/interface', () => { - /** @type {Array.} */ - const doclets = [ { - kind: 'class', - memberof: 'module:editor', - longname: 'module:editor~Editor', - name: 'Editor', - meta: { - path: '/', - filename: 'editor.js', - lineno: 20 - }, - comment: '', - description: '' - }, - { - kind: 'event', - meta: { - path: '/', - filename: 'editor.js', - lineno: 30 - }, - name: 'blur', - longname: 'event:blur', - memberof: 'module:editor~Editor', - comment: '', - description: '' - } ]; - - convertShortRefsToFullRefs( doclets ); - - expect( doclets[ 1 ].longname ).to.be.equal( - 'module:editor~Editor#event:blur' - ); - } ); - - it( 'should not convert event name if there is no class/mixin/interface defined above the event', () => { - /** @type {Array.} */ - const doclets = [ { - kind: 'class', - memberof: 'module:editor', - longname: 'module:editor~Editor', - name: 'Editor', - meta: { - path: '/', - filename: 'editor.js', - lineno: 20 - }, - comment: '', - description: '' - }, - { - kind: 'event', - meta: { - path: '/', - filename: 'editor.js', - lineno: 30 - }, - name: 'event:blur', - longname: 'module:editor2~Editor#event:blur', - memberof: 'module:editor2~Editor', - comment: '', - description: '' - } ]; - - convertShortRefsToFullRefs( doclets ); - - expect( doclets[ 1 ].longname ).to.be.equal( - 'module:editor2~Editor#event:blur' - ); - } ); - - it( 'should convert short refs in fires tag to full refs if a class/mixin/interface is declared above', () => { - /** @type {Array.} */ - const doclets = [ { - kind: 'class', - memberof: 'module:editor', - longname: 'module:editor~Editor', - name: 'Editor', - meta: { - path: '/', - filename: 'editor.js', - lineno: 20 - }, - comment: '', - description: '' - }, - { - kind: 'function', - meta: { - path: '/', - filename: 'editor.js', - lineno: 30 - }, - name: 'execute', - fires: [ 'event:execute' ], - longname: 'module:editor~Editor#execute', - memberof: 'module:editor~Editor', - comment: '', - description: '' - } ]; - - convertShortRefsToFullRefs( doclets ); - - expect( doclets[ 1 ].fires[ 0 ] ).to.be.equal( - 'module:editor~Editor#event:execute' - ); - } ); - - it( 'should convert short refs in fires tag to full refs if a class/mixin/interface is declared above #2', () => { - /** @type {Array.} */ - const doclets = [ { - kind: 'class', - memberof: 'module:editor', - longname: 'module:editor~Editor', - name: 'Editor', - meta: { - path: '/', - filename: 'editor.js', - lineno: 20 - }, - comment: '', - description: '' - }, - { - kind: 'function', - meta: { - path: '/', - filename: 'editor.js', - lineno: 30 - }, - name: 'attr', - fires: [ 'change:attribute' ], - longname: 'module:editor~Editor#attr', - memberof: 'module:editor~Editor', - comment: '', - description: '' - } ]; - - convertShortRefsToFullRefs( doclets ); - - expect( doclets[ 1 ].fires[ 0 ] ).to.be.equal( - 'module:editor~Editor#event:change:attribute' - ); - } ); - - it( 'should convert short refs in see tags to full refs', () => { - /** @type {Array.} */ - const doclets = [ { - kind: 'class', - memberof: 'module:editor', - longname: 'module:editor~Editor', - name: 'Editor', - meta: { - path: '/', - filename: 'editor.js', - lineno: 20 - }, - comment: '', - description: '' - }, - { - kind: 'function', - meta: { - path: '/', - filename: 'editor.js', - lineno: 30 - }, - name: 'attr', - see: [ '#create' ], - longname: 'module:editor~Editor#attr', - memberof: 'module:editor~Editor', - comment: '', - description: '' - } ]; - - convertShortRefsToFullRefs( doclets ); - - expect( doclets[ 1 ].see[ 0 ] ).to.be.equal( - 'module:editor~Editor#create' - ); - } ); -} ); - -describe( 'jsdoc-plugins/longname-fixer/fix-links', () => { - it( 'formatLinks()', () => { - /** @type {Doclet} */ - const doclet = { - name: 'EditorInterface', - comment: 'Creates {@link ~EditorInterface} instance', - description: '

Creates {@link ~EditorInterface} instance

', - memberof: 'module:ckeditor5/editor/editorinterface', - longname: 'module:ckeditor5/editor/editorinterface~EditorInterface', - kind: 'interface', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 0 } - }; - - convertShortRefsToFullRefs( [ doclet ] ); - - expect( doclet.comment ).to.be.equal( - 'Creates {@link module:ckeditor5/editor/editorinterface~EditorInterface} instance' - ); - expect( doclet.description ).to.be.equal( - '

Creates {@link module:ckeditor5/editor/editorinterface~EditorInterface} instance

' - ); - } ); - - it( 'formatLinks() hash', () => { - /** @type {Doclet} */ - const doclet = { - name: '#create', - comment: 'Method {@link #create} creates instance', - memberof: 'module:ckeditor5/editor/editorinterface~EditorInterface', - longname: 'module:ckeditor5/editor/editorinterface~EditorInterface#create', - kind: 'function', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 0 } - }; - - convertShortRefsToFullRefs( [ doclet ] ); - - expect( doclet.comment ).to.be.equal( - 'Method {@link module:ckeditor5/editor/editorinterface~EditorInterface#create} creates instance' - ); - } ); - - it( 'formatLinks() with link description', () => { - /** @type {Doclet} */ - const doclet = { - name: 'EditorInterface', - comment: 'Creates {@link ~EditorInterface editor} instance with a given name.', - memberof: 'module:ckeditor5/editor/editorinterface', - longname: 'module:ckeditor5/editor/editorinterface~EditorInterface', - kind: 'interface', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 0 } - }; - - convertShortRefsToFullRefs( [ doclet ] ); - - expect( doclet.comment ).to.be.equal( - 'Creates {@link module:ckeditor5/editor/editorinterface~EditorInterface editor} instance with a given name.' - ); - } ); - - it( 'formatLinks() with more complicated path', () => { - /** @type {Doclet} */ - const doclet = { - name: 'EditorInterface', - comment: 'Method {@link ~EditorInterface#create create} creates Editor', - memberof: 'module:ckeditor5/editor/editorinterface', - longname: 'module:ckeditor5/editor/editorinterface~EditorInterface', - kind: 'interface', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 0 } - }; - - convertShortRefsToFullRefs( [ doclet ] ); - - expect( doclet.comment ).to.be.equal( - 'Method {@link module:ckeditor5/editor/editorinterface~EditorInterface#create create} creates Editor' - ); - } ); - - it( 'formatLinks() in description', () => { - /** @type {Doclet} */ - const doclet = { - name: 'EditorInterface', - comment: '', - description: 'You can later destroy it with {@link ~EditorInterface#destroy}', - memberof: 'module:ckeditor5/editor/editorinterface', - longname: 'module:ckeditor5/editor/editorinterface~EditorInterface', - kind: 'interface', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 0 } - }; - - convertShortRefsToFullRefs( [ doclet ] ); - - expect( doclet.description ).to.be.equal( - 'You can later destroy it with {@link module:ckeditor5/editor/editorinterface~EditorInterface#destroy}' - ); - } ); - - it( 'formatLinks() multiple links', () => { - /** @type {Doclet} */ - const doclet = { - name: 'EditorInterface', - comment: '{@link #destroy} {@link #destroy}', - memberof: 'module:editor/editorinterface', - longname: 'module:ckeditor5/editor/editorinterface~EditorInterface', - kind: 'interface', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 0 } - }; - - convertShortRefsToFullRefs( [ doclet ] ); - - expect( doclet.comment ).to.be.equal( - '{@link module:editor/editorinterface#destroy} {@link module:editor/editorinterface#destroy}' - ); - } ); - - it( 'formatLinks() link to parent: class / interface', () => { - /** @type {Doclet} */ - const doclet = { - name: 'EditorInterface', - comment: '{@link ~EditorInterface}', - memberof: 'module:editor/editorinterface~EditorInterface', - longname: 'module:ckeditor5/editor/editorinterface~EditorInterface', - kind: 'interface', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 0 } - }; - - convertShortRefsToFullRefs( [ doclet ] ); - - expect( doclet.comment ).to.be.equal( - '{@link module:editor/editorinterface~EditorInterface}' - ); - } ); - - it( 'formatLinks() with multi-word link', () => { - /** @type {Doclet} */ - const doclet = { - name: 'EditorInterface', - comment: 'Creates {@link ~EditorInterface some editor} instance with a given name.', - memberof: 'module:ckeditor5/editor/editorinterface', - longname: 'module:ckeditor5/editor/editorinterface~EditorInterface', - kind: 'interface', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 0 } - }; - - convertShortRefsToFullRefs( [ doclet ] ); - - expect( doclet.comment ).to.be.equal( - 'Creates {@link module:ckeditor5/editor/editorinterface~EditorInterface some editor} ' + - 'instance with a given name.' - ); - } ); - - it( 'should fix links in error doclets', () => { - /** @type {Array.} */ - const doclets = [ { - name: 'some-error', - longname: 'module:errors~some-error', - memberof: 'module:errors', - kind: 'error', - comment: 'The {@link #constructor source} of a rect in an HTML element', - description: '

The {@link #constructor source} of a rect in an HTML element

', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 40 } - }, { - name: 'Rect', - memberof: 'module:ckeditor5-utils/dom/rect', - longname: 'module:ckeditor5-utils/dom/rect~Rect', - kind: 'class', - comment: '', - description: '', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 30 } - }, { - name: 'constructor', - longname: 'module:ckeditor5-utils/dom/rect~Rect#constructor', - memberof: 'module:ckeditor5-utils/dom/rect~Rect', - kind: 'function', - comment: '', - description: '', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 32 } - } ]; - - convertShortRefsToFullRefs( doclets ); - - const errorDoclet = doclets.find( d => d.longname === 'module:errors~some-error' ); - - expect( errorDoclet ).to.deep.equal( { - name: 'some-error', - longname: 'module:errors~some-error', - memberof: 'module:errors', - kind: 'error', - comment: 'The {@link module:ckeditor5-utils/dom/rect~Rect#constructor source} of a rect in an HTML element', - description: '

The {@link module:ckeditor5-utils/dom/rect~Rect#constructor source} of a rect in an HTML element

', - meta: { filename: 'foo.js', path: 'foo/bar', lineno: 40 } - } ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/doclet-collection.js b/packages/jsdoc-plugins/tests/doclet-collection.js deleted file mode 100644 index e570b79c0..000000000 --- a/packages/jsdoc-plugins/tests/doclet-collection.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const chai = require( 'chai' ); -const expect = chai.expect; -const DocletCollection = require( '../lib/utils/doclet-collection' ); - -describe( 'collection', () => { - let collection; - - beforeEach( () => { - const docletA = { - name: 'ClassA', - longname: 'module:M~ClassA', - kind: 'class' - }; - const docletB = { - name: 'methodB', - longname: 'module:M~ClassA#methodB', - kind: 'method' - }; - collection = new DocletCollection(); - collection.add( docletA.kind, docletA ); - collection.add( docletB.kind, docletB ); - } ); - - it( 'should return doclets filtered by category', () => { - expect( collection.get( 'class' ) ).to.deep.equal( - [ - { - name: 'ClassA', - longname: 'module:M~ClassA', - kind: 'class' - } - ] - ); - } ); - - it( 'should return all doclets', () => { - expect( collection.getAll() ).to.deep.equal( - [ - { - name: 'ClassA', - longname: 'module:M~ClassA', - kind: 'class' - }, - { - name: 'methodB', - longname: 'module:M~ClassA#methodB', - kind: 'method' - } - ] - ); - } ); - - it( 'should return all longnames of stored doclets', () => { - expect( collection.getAllLongnames() ).to.deep.equal( - [ - 'module:M~ClassA', - 'module:M~ClassA#methodB' - ] - ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/doclet-validator.js b/packages/jsdoc-plugins/tests/doclet-validator.js deleted file mode 100644 index 07962c989..000000000 --- a/packages/jsdoc-plugins/tests/doclet-validator.js +++ /dev/null @@ -1,600 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const chai = require( 'chai' ); -const expect = chai.expect; -const DocletValidator = require( '../lib/validator/doclet-validator.js' ); - -// TODO - These tests should be rewritten to use doclets created from the API docs extraction. -describe( 'jsdoc-plugins/Validator', () => { - it( '_validateMembers()', () => { - const validator = new DocletValidator( [ { - kind: 'member', - name: 'module:ckeditor5/wrong_path', - scope: 'inner', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateMembers(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - - describe( '_validateMemberofProperty()', () => { - it( 'should emit error if the doclet comes from inner variable', () => { - const validator = new DocletValidator( [ { - kind: 'member', - name: 'module:ckeditor5/path', - memberof: '', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateMemberofProperty(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - - it( 'should emit error if the doclet contains invalid `memberof` property', () => { - const validator = new DocletValidator( [ { - kind: 'member', - name: 'module:ckeditor5/wrong_path', - memberof: 'wrongMemberof', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateMemberofProperty(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - - it( 'should not emit error when the doclets\' `memberof` starts with `module:`', () => { - const validator = new DocletValidator( [ { - kind: 'member', - name: 'module:ckeditor5/editor', - memberof: 'module:ckeditor5/editor', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateMemberofProperty(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'should emit error if the doclet comes from undocumented code', () => { - const validator = new DocletValidator( [ { - kind: 'member', - undocumented: 'true', - name: '⌘', - memberof: 'macGlyphsToModifiers', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateMemberofProperty(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - } ); - - describe( 'linting function parameters', () => { - it( 'should handle not existing types', () => { - const validator = new DocletValidator( [ { - kind: 'function', - params: [ { - type: { - names: [ 'module:engine/ckeditor5/editor' ] - } - } ], - longname: 'abc', - scope: 'inner', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateParameters(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - - it( 'should log an error if a module is passed as parameter type', () => { - const validator = new DocletValidator( [ { - kind: 'class', - params: [ { - type: { - names: [ 'module:engine/ckeditor5/editor' ] - } - } ], - meta: { fileName: '', path: '' } - }, { - kind: 'module', - longname: 'module:engine/ckeditor5/editor', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateParameters(); - - expect( validator.errors.length ).to.be.equal( 1 ); - expect( validator.errors[ 0 ].message ).to.equal( 'Incorrect param type: module:engine/ckeditor5/editor' ); - } ); - - it( 'should not log an error if an allowed member is passed as parameter type', () => { - const validator = new DocletValidator( [ { - kind: 'class', - params: [ { - type: { - names: [ 'module:engine/foo~ClassFoo' ] - } - }, { - type: { - names: [ 'module:engine/foo~InterfaceBar' ] - } - }, { - type: { - names: [ 'module:engine/foo~TypedefBaz' ] - } - }, { - type: { - names: [ 'module:engine/foo~FunctionAbc' ] - } - } ], - meta: { fileName: '', path: '' } - }, { - kind: 'class', - longname: 'module:engine/foo~ClassFoo', - meta: { fileName: '', path: '' } - }, { - kind: 'interface', - longname: 'module:engine/foo~InterfaceBar', - meta: { fileName: '', path: '' } - }, { - kind: 'typedef', - longname: 'module:engine/foo~TypedefBaz', - meta: { fileName: '', path: '' } - }, { - kind: 'function', - longname: 'module:engine/foo~FunctionAbc', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateParameters(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'should handle built-in types', () => { - const validator = new DocletValidator( [ { - kind: 'class', - params: [ { - type: { - names: [ - 'String', - 'Array', - 'Number' - ] - } - } ], - meta: { fileName: '', path: '' } - } ] ); - - validator._validateParameters(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'should log an error if an incorrect type is passed', () => { - const validator = new DocletValidator( [ { - kind: 'class', - params: [ { - type: { - names: [ - 'String', - 'Array', - 'Wrong' - ] - } - } ], - meta: { fileName: '', path: '' } - } ] ); - - validator._validateParameters(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - } ); - - describe( 'linting links', () => { - it( 'should validate links and adds errors if they are incorrect', () => { - const validator = new DocletValidator( [ { - comment: - `* {@link module:utils/a~A#method1} - * {@link module:utils/b~Some1} `, - meta: { fileName: '', path: '' } - } ] ); - - validator._validateLinks(); - - expect( validator.errors.length ).to.be.equal( 2 ); - } ); - - it( 'should not produce errors if links are correct', () => { - const validator = new DocletValidator( [ { - comment: - `/** Linking test:\n *\n * * a:\n * - * {@link module:ckeditor5/a~A} `, - meta: { fileName: '', path: '' } - }, { - comment: '', - longname: 'module:ckeditor5/a~A', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateLinks(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'should validate links with name', () => { - const validator = new DocletValidator( [ { - comment: ' {@link module:ckeditor5/a~A classA} ', - meta: { fileName: '', path: '' } - }, { - comment: '', - longname: 'module:ckeditor5/a~A', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateLinks(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'should validate links with white spaces', () => { - const validator = new DocletValidator( [ { - comment: ' {@link \n module:ckeditor5/a~A \n\t classA} ', - meta: { fileName: '', path: '' } - }, { - comment: '', - longname: 'module:ckeditor5/a~A', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateLinks(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'should validate links with multi-word link', () => { - const validator = new DocletValidator( [ { - comment: ' {@link module:ckeditor5/a~A with multi word link} ', - meta: { fileName: '', path: '' } - }, { - comment: '', - longname: 'module:ckeditor5/a~A', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateLinks(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'should validate links that contain double link keyword', () => { - const validator = new DocletValidator( [ { - comment: '{@link @link module:ckeditor5/a~A with multi word link} ', - meta: { fileName: '', path: '' } - }, { - comment: '', - longname: 'module:ckeditor5/a~A', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateLinks(); - - expect( validator.errors.length ).to.be.equal( 1 ); - expect( validator.errors[ 0 ].message ).to.match( /Incorrect link:/ ); - } ); - - it( 'should validate links that does not contain the @link part', () => { - const validator = new DocletValidator( [ { - comment: ` - @param {module:ckeditor5/a~A} - @returns {module:ckeditor5/a~A} - Correct link: {@link module:ckeditor5/a~A} - Random comment: {priority: 'high'} - Invalid link: {module:ckeditor5/a~B} - `, - meta: { fileName: '', path: '' } - }, { - comment: '', - longname: 'module:ckeditor5/a~A', - meta: { fileName: '', path: '' } - }, { - comment: '', - longname: 'module:ckeditor5/a~B', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateLinks(); - - expect( validator.errors.length ).to.be.equal( 1 ); - expect( validator.errors[ 0 ].message ).to.match( /Link misses the '@link' part: \{module:ckeditor5\/a~B\}/ ); - } ); - - it( 'should validate comment without any link', () => { - const validator = new DocletValidator( [ { - comment: 'Some comment without any valid nor invalid link', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateLinks(); - - expect( validator.errors.length ).to.equal( 0 ); - } ); - } ); - - describe( 'linting extensibility', () => { - it( 'should assert that the type in the `@extends` tag exsits (positive)', () => { - const validator = new DocletValidator( [ { - kind: 'class', - longname: 'module:abc/SomeClass', - augments: [ 'module:abc/SomeOtherClass' ], - meta: { fileName: '', path: '' } - }, { - kind: 'class', - longname: 'module:abc/SomeOtherClass', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateExtensibility(); - - expect( validator.errors.length ).to.equal( 0 ); - } ); - - it( 'should assert that the type in the `@extends` tag exsits (negative)', () => { - const validator = new DocletValidator( [ { - kind: 'class', - longname: 'module:abc/SomeClass', - augments: [ 'module:abc/SomeOtherClass' ], - meta: { fileName: '', path: '' } - } ] ); - - validator._validateExtensibility(); - - expect( validator.errors.length ).to.equal( 1 ); - expect( validator.errors[ 0 ].message ).to.equal( 'Invalid @extends reference: module:abc/SomeOtherClass.' ); - } ); - } ); - - describe( 'linting events', () => { - it( 'should assert that references in `fires` exist (positive)', () => { - const validator = new DocletValidator( [ { - kind: 'class', - longname: 'module:abc/SomeClass', - meta: { fileName: '', path: '' }, - fires: [ 'someEvent' ] - } ] ); - - validator._validateEvents(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - - it( 'should assert that references in `fires` exist (negative)', () => { - const validator = new DocletValidator( [ { - kind: 'class', - longname: 'module:abc/SomeClass', - meta: { fileName: '', path: '' }, - fires: [ 'module:abc/SomeClass#event:someEvent' ] - }, { - kind: 'event', - longname: 'module:abc/SomeClass#event:someEvent' - } ] ); - - validator._validateEvents(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'should assert that references in `fires` are only events', () => { - const validator = new DocletValidator( [ { - kind: 'class', - longname: 'module:abc/SomeClass', - meta: { fileName: '', path: '' }, - fires: [ 'module:abc/SomeClass#event:someEvent' ] - }, { - kind: 'not-event', - longname: 'module:abc/SomeClass#event:someEvent' - } ] ); - - validator._validateEvents(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - } ); - - it( '_validateModuleDocumentedExports() - show errors', () => { - const validator = new DocletValidator( [ { - kind: 'member', - scope: 'inner', - memberof: 'module:utils/emittermixin', - meta: { fileName: '', path: '' } - }, { - kind: 'module', - longname: 'module:utils/emittermixin', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateModuleDocumentedExports(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - - it( '_validateModuleDocumentedExports()', () => { - const validator = new DocletValidator( [ { - kind: 'member', - scope: 'inner', - memberof: 'module:utils/emittermixin~EmitterMixin', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateModuleDocumentedExports(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'lintSeeReferences()', () => { - const validator = new DocletValidator( [ { - kind: 'class', - longname: 'module:utils/emittermixin~EmitterMixin', - see: [ - 'module:utils/emittermixin~EmitterMixin#constructor' - ], - meta: { fileName: '', path: '' } - }, { - kind: 'member', - longname: 'module:utils/emittermixin~EmitterMixin#constructor', - meta: { fileName: '', path: '' } - } ] ); - - validator._validateSeeReferences(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( 'lintSeeReferences() - invalid', () => { - const validator = new DocletValidator( [ { - kind: 'class', - see: [ - 'module:utils/emittermixin~EmitterMixin' - ], - meta: { fileName: '', path: '' } - } ] ); - - validator._validateSeeReferences(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - - it( '_validateTypedefs()', () => { - const validator = new DocletValidator( [ { - type: 'typedef', - properties: [ { - type: { - names: [ - 'String', - 'Map.' - ] - } - } ], - meta: { fileName: '', path: '' } - } ] ); - - validator._validateTypedefs(); - - expect( validator.errors.length ).to.be.equal( 0 ); - } ); - - it( '_validateTypedefs() - invalid', () => { - const validator = new DocletValidator( [ { - type: 'typedef', - properties: [ { - type: { - names: [ - 'Abc' - ] - } - } ], - meta: { fileName: '', path: '' } - } ] ); - - validator._validateTypedefs(); - - expect( validator.errors.length ).to.be.equal( 1 ); - } ); - - describe( '_isCorrectType', () => { - it( 'Should validate union type', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( 'String|Array' ); - - expect( result ).to.be.equal( true ); - } ); - - it( 'Should validate generic type (Array.)', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( 'Array.' ); - - expect( result ).to.be.equal( true ); - } ); - - it( 'Should validate generic union type', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( 'Array.' ); - - expect( result ).to.be.equal( true ); - } ); - - it( 'Should validate union type with parenthesis', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( 'Array.<(Object|String)>' ); - - expect( result ).to.be.equal( true ); - } ); - - it( 'Should validate incorrect union type', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( 'Array.<(Object|IncorrectType)>' ); - - expect( result ).to.be.equal( false ); - } ); - - it( 'Should validate full path to class', () => { - const validator = new DocletValidator( [ { - longname: 'module:core/editor~Editor', - kind: 'function', - meta: { fileName: '', path: '' } - } ] ); - - const result = validator._isCorrectType( 'Array.' ); - - expect( result ).to.be.equal( true ); - } ); - - it( 'Should validate generic type (Array)', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( 'Array.<*>' ); - - expect( result ).to.be.equal( true ); - } ); - - it( 'Should validate invalid generic type', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( 'String.' ); - - expect( result ).to.be.equal( false ); - } ); - - it( 'Should validate string literal type', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( '\'forward\'' ); - - expect( result ).to.be.equal( true ); - } ); - - it( 'Should validate generic type with more than one template type', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( 'Object.' ); - - expect( result ).to.be.equal( true ); - } ); - - it( 'Should accept spaces', () => { - const validator = new DocletValidator( [] ); - const result = validator._isCorrectType( ' String | Number | Boolean ' ); - - expect( result ).to.be.equal( true ); - } ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/fix-code-snippets.js b/packages/jsdoc-plugins/tests/fix-code-snippets.js deleted file mode 100644 index eaf88c364..000000000 --- a/packages/jsdoc-plugins/tests/fix-code-snippets.js +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const { expect } = require( 'chai' ); -const fixCodeSnippets = require( '../lib/fix-code-snippets' ); - -describe( 'jsdoc-plugins/fix-code-snippets', () => { - it( 'should remove leading tabs ina multi-line code snippets', () => { - const doclet = { - description: '
\tfoo\n\tbar
' - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.description ).to.equal( - '
foo\nbar
' - ); - } ); - - it( 'should remove leading tabs in a single-line code snippet', () => { - const doclet = { - description: '
\tfoo
' - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.description ).to.equal( - '
foo
' - ); - } ); - - it( 'should remove leading tabs in a description containing multiple code snippets', () => { - const doclet = { - description: - '
\tfoo
' + - 'foo' + - '
\tbar
' + - 'bar' - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.description ).to.equal( - '
foo
' + - 'foo' + - '
bar
' + - 'bar' - ); - } ); - - it( 'should remove multiple leading tabs', () => { - const doclet = { - description: - '
\t\tfoo\n\t\tbar
' - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.description ).to.equal( - '
foo\nbar
' - ); - } ); - - it( 'should remove leading spaces', () => { - const doclet = { - description: - '
   foo\n   bar
' - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.description ).to.equal( - '
foo\nbar
' - ); - } ); - - it( 'should remove leading tabs in code snippet containing empty lines', () => { - const doclet = { - description: - '
\t\tfoo\n\n\t\tbar
' - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.description ).to.equal( - '
foo\n\nbar
' - ); - } ); - - it( 'should not remove correct code snippet tabs', () => { - const doclet = { - description: - '
\tfoo\n\t\tbar\n\t\t\tbaz
' - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.description ).to.equal( - '
foo\n\tbar\n\t\tbaz
' - ); - } ); - - it( 'should fix classdesc in classes', () => { - const doclet = { - classdesc: - '
\tfoo\n\tbar
' - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.classdesc ).to.equal( - '
foo\nbar
' - ); - } ); - - it( 'should fix property descriptions', () => { - const doclet = { - properties: [ { - name: 'foo', - description: '
\tfoo\n\tbar
' - }, { - name: 'bar', - description: '
\tfoo\n\tbar
' - }, { - name: 'baz' - // The `baz` property has no description. - } ] - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.properties[ 0 ].description ).to.equal( - '
foo\nbar
' - ); - - expect( doclet.properties[ 1 ].description ).to.equal( - '
foo\nbar
' - ); - } ); - - it( 'should fix descriptions of the return tags', () => { - const doclet = { - returns: [ { - type: 'String', - description: '
\tfoo\n\tbar
' - }, { - type: 'Array', - description: '
\tfoo\n\tbar
' - }, { - type: 'Boolean' - // Third return overload has no description. - } ] - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.returns[ 0 ].description ).to.equal( - '
foo\nbar
' - ); - - expect( doclet.returns[ 1 ].description ).to.equal( - '
foo\nbar
' - ); - } ); - - it( 'should fix descriptions of parameters', () => { - const doclet = { - params: [ { - name: 'foo', - description: '
\tfoo\n\tbar
' - }, { - name: 'bar', - description: '
\tfoo\n\tbar
' - }, { - name: 'baz' - // The `baz` parameter has no description. - } ] - }; - - fixCodeSnippets.handlers.parseComplete( { doclets: [ doclet ] } ); - - expect( doclet.params[ 0 ].description ).to.equal( - '
foo\nbar
' - ); - - expect( doclet.params[ 1 ].description ).to.equal( - '
foo\nbar
' - ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/integration-tests/_utils/extract-api-docs.js b/packages/jsdoc-plugins/tests/integration-tests/_utils/extract-api-docs.js deleted file mode 100644 index 1ec5133dc..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/_utils/extract-api-docs.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -const tmp = require( 'tmp' ); -const fs = require( 'fs' ); -const { execSync } = require( 'child_process' ); -const { globSync } = require( 'glob' ); -const upath = require( 'upath' ); - -module.exports = async function extractApiDocs( dirname ) { - const filePattern1 = upath.join( dirname, '/input/**/*.jsdoc' ); - const filePattern2 = upath.join( dirname, '/input.jsdoc' ); - - const files = [ - ...globSync( filePattern1 ), - ...globSync( filePattern2 ) - ]; - - if ( files.length === 0 ) { - throw new Error( - `No file matching the '${ filePattern1 }' pattern was found by the 'extractApiDocs' test utility.` - ); - } - - const jsDocConfig = { - plugins: [ - require.resolve( '../../../lib/export-fixer/export-fixer' ), - require.resolve( '../../../lib/custom-tags/error' ), - require.resolve( '../../../lib/custom-tags/observable' ), - require.resolve( '../../../lib/observable-event-provider' ), - require.resolve( '../../../lib/relation-fixer' ), - require.resolve( '../../../lib/longname-fixer/longname-fixer' ), - require.resolve( '../../../lib/event-extender/event-extender' ), - require.resolve( '../../../lib/cleanup' ), - - // The logger prints the JSON to stdout. - // This way the generated structure can be fetched by integration tests. - require.resolve( './logger' ) - ], - source: { - include: files - }, - opts: { - encoding: 'utf8', - recurse: true, - access: 'all', - template: 'templates/silent' - } - }; - - const tmpConfig = tmp.fileSync(); - - fs.writeFileSync( tmpConfig.name, JSON.stringify( jsDocConfig ) ); - - const cmd = require.resolve( 'jsdoc/jsdoc.js' ); - - const rawOutput = execSync( `node ${ cmd } -c ${ tmpConfig.name }` ).toString(); - - const doclets = JSON.parse( rawOutput ).doclets; - - // Preserve only filename for doclet identification metadata. - for ( const doclet of doclets ) { - if ( doclet.meta ) { - doclet.meta = { - filename: doclet.meta.filename - }; - } - } - - return doclets; -}; diff --git a/packages/jsdoc-plugins/tests/integration-tests/_utils/logger.js b/packages/jsdoc-plugins/tests/integration-tests/_utils/logger.js deleted file mode 100644 index 8a852b3bb..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/_utils/logger.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -exports.handlers = { - processingComplete( e ) { - console.log( JSON.stringify( e, null, 4 ) ); - } -}; diff --git a/packages/jsdoc-plugins/tests/integration-tests/class-inheriting-from-mixins/class-inheriting-from-mixins.js b/packages/jsdoc-plugins/tests/integration-tests/class-inheriting-from-mixins/class-inheriting-from-mixins.js deleted file mode 100644 index 476113be2..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/class-inheriting-from-mixins/class-inheriting-from-mixins.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const extractApiDocs = require( '../_utils/extract-api-docs' ); -const { cloneDeep } = require( 'lodash' ); -const { expect } = require( 'chai' ); - -describe( 'integration test/class inheriting from mixins', () => { - /** @type {Array.} */ - let originalApiDocs; - - /** @type {Array.} */ - let apiDocs; - - before( async () => { - originalApiDocs = await extractApiDocs( __dirname ); - } ); - - beforeEach( () => { - apiDocs = cloneDeep( originalApiDocs ); - } ); - - describe( 'interfaces and mixins', () => { - it( 'EmitterMixin doclet should contain correct longname', () => { - const emitterMixinDoclet = apiDocs.find( d => d.name === 'EmitterMixin' ); - - expect( emitterMixinDoclet.longname ).to.equal( 'module:utils/emittermixin~EmitterMixin' ); - expect( emitterMixinDoclet.memberof ).to.equal( 'module:utils/emittermixin' ); - } ); - - it( 'EmitterMixin doclet should be generated only once', () => { - const emitterMixinDoclets = apiDocs.filter( d => d.name === 'EmitterMixin' ); - - expect( emitterMixinDoclets.length ).to.equal( 1 ); - } ); - - it( 'Emitter#on doclet should be generated for the `on` method', () => { - const emitterOnDoclet = apiDocs.find( d => d.longname == 'module:utils/emittermixin~Emitter#on' ); - - expect( emitterOnDoclet ).to.be.an( 'object' ); - expect( emitterOnDoclet.description ).to.equal( - 'Registers a callback function to be executed when an event is fired.' - ); - - expect( emitterOnDoclet.scope ).to.equal( 'instance' ); - expect( emitterOnDoclet.memberof ).to.equal( 'module:utils/emittermixin~Emitter' ); - } ); - - it( 'EmitterMixin#on doclet should be generated for the `on` method and should inherit docs ', () => { - const emitterMixinOnDoclet = apiDocs.find( d => d.longname == 'module:utils/emittermixin~EmitterMixin#on' ); - - expect( emitterMixinOnDoclet ).to.be.an( 'object' ); - - expect( emitterMixinOnDoclet.description ).to.equal( - 'Registers a callback function to be executed when an event is fired.' - ); - - expect( emitterMixinOnDoclet.scope ).to.equal( 'instance' ); - expect( emitterMixinOnDoclet.memberof ).to.equal( 'module:utils/emittermixin~EmitterMixin' ); - } ); - } ); - - describe( 'class extending mixins that implements interfaces', () => { - it( 'doclet for the Emitter class should be generated', () => { - const emitterDoclet = apiDocs.find( d => d.longname == 'module:engine/emitter~Emitter' ); - - expect( emitterDoclet ).to.be.an( 'object' ); - - expect( emitterDoclet.implementsNested ).to.deep.equal( [ - 'module:utils/emittermixin~Emitter' - ] ); - - expect( emitterDoclet.mixesNested ).to.deep.equal( [ - 'module:utils/emittermixin~EmitterMixin' - ] ); - } ); - - it( 'doclet for the `on` method should be generated', () => { - const emitterOnDoclet = apiDocs.find( d => d.longname == 'module:engine/emitter~Emitter#on' ); - - expect( emitterOnDoclet ).to.be.an( 'object' ); - - expect( emitterOnDoclet.scope ).to.equal( 'instance' ); - expect( emitterOnDoclet.memberof ).to.equal( 'module:engine/emitter~Emitter' ); - - expect( emitterOnDoclet.mixed ).to.equal( true ); - } ); - } ); -} ); - diff --git a/packages/jsdoc-plugins/tests/integration-tests/class-inheriting-from-mixins/input/class.jsdoc b/packages/jsdoc-plugins/tests/integration-tests/class-inheriting-from-mixins/input/class.jsdoc deleted file mode 100644 index c99f10436..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/class-inheriting-from-mixins/input/class.jsdoc +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @module engine/emitter - */ - -/** - * A class mixing EmitterMixin - * - * @mixes module:utils/emittermixin~EmitterMixin - */ -export default class Emitter { - /** - * @inheritDoc - */ - on() {} -} diff --git a/packages/jsdoc-plugins/tests/integration-tests/class-inheriting-from-mixins/input/mixin.jsdoc b/packages/jsdoc-plugins/tests/integration-tests/class-inheriting-from-mixins/input/mixin.jsdoc deleted file mode 100644 index 6e8a30a4e..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/class-inheriting-from-mixins/input/mixin.jsdoc +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @module utils/emittermixin - */ - -/** - * Mixin that injects the {@link ~Emitter events API} into its host. - * - * @mixin EmitterMixin - * @implements module:utils/emittermixin~Emitter - */ -const EmitterMixin = { - /** - * @inheritDoc - */ - on( event, callback, options = {} ) { - this.listenTo( this, event, callback, options ); - } -}; - -export default EmitterMixin; - -/** - * Emitter/listener interface. - * - * @interface Emitter - */ - -/** - * Registers a callback function to be executed when an event is fired. - * - * @method #on - * @param {String} event The name of the event. - * @param {Function} callback The function to be called on event. - * @param {Object} [options={}] Additional options. - */ diff --git a/packages/jsdoc-plugins/tests/integration-tests/class-static-methods/class-static-methods.js b/packages/jsdoc-plugins/tests/integration-tests/class-static-methods/class-static-methods.js deleted file mode 100644 index a7976e107..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/class-static-methods/class-static-methods.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const extractApiDocs = require( '../_utils/extract-api-docs' ); -const { cloneDeep } = require( 'lodash' ); -const { expect } = require( 'chai' ); - -describe( 'integration test/class-static-methods', () => { - /** @type {Array.} */ - let originalApiDocs; - - /** @type {Array.} */ - let apiDocs; - - before( async () => { - originalApiDocs = await extractApiDocs( __dirname ); - } ); - - beforeEach( () => { - apiDocs = cloneDeep( originalApiDocs ); - } ); - - describe( 'class static methods', () => { - it( 'doclets should be generated', () => { - expect( apiDocs.length ).to.equal( 3 ); - } ); - - it( 'doclet for static property (getter + setter) should be generated', () => { - const doclet = apiDocs.find( doclet => doclet.longname === 'module:foo/bar~Foo.foo' ); - - expect( doclet ).to.deep.equal( { - comment: '/**\n\t * Static foo property.\n\t */', - meta: { filename: 'input.jsdoc' }, - description: 'Static foo property.', - name: 'foo', - longname: 'module:foo/bar~Foo.foo', - kind: 'member', - memberof: 'module:foo/bar~Foo', - scope: 'static', - params: [] - } ); - } ); - - it( 'doclet for static method should be generated', () => { - const doclet = apiDocs.find( doclet => doclet.longname === 'module:foo/bar~Foo.get' ); - - expect( doclet ).to.deep.equal( { - comment: '/**\n\t * Gets some value.\n\t */', - meta: { filename: 'input.jsdoc' }, - description: 'Gets some value.', - name: 'get', - longname: 'module:foo/bar~Foo.get', - kind: 'function', - memberof: 'module:foo/bar~Foo', - scope: 'static', - params: [] - } ); - } ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/integration-tests/class-static-methods/input.jsdoc b/packages/jsdoc-plugins/tests/integration-tests/class-static-methods/input.jsdoc deleted file mode 100644 index f0eed5aa1..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/class-static-methods/input.jsdoc +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @module foo/bar - */ - -export default class Foo { - /** - * Gets some value. - */ - static get() { - - } - - /** - * Static foo property. - */ - static get foo() { - return []; - } - - static set foo( value ) { - - } -} diff --git a/packages/jsdoc-plugins/tests/integration-tests/class/class-basics.js b/packages/jsdoc-plugins/tests/integration-tests/class/class-basics.js deleted file mode 100644 index 07f86dd8d..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/class/class-basics.js +++ /dev/null @@ -1,157 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const extractApiDocs = require( '../_utils/extract-api-docs' ); -const { cloneDeep } = require( 'lodash' ); -const { expect } = require( 'chai' ); - -describe( 'integration test/exported-class', () => { - /** @type {Array.} */ - let originalApiDocs; - - /** @type {Array.} */ - let apiDocs; - - before( async () => { - originalApiDocs = await extractApiDocs( __dirname ); - } ); - - beforeEach( () => { - apiDocs = cloneDeep( originalApiDocs ); - } ); - - it( 'should generate a doclet for class', () => { - const classDoclets = apiDocs.filter( doclet => doclet.longname === 'module:foo/bar/baz~Foo' ); - - expect( classDoclets.length ).to.equal( 1 ); - - expect( classDoclets[ 0 ] ).to.deep.equal( { - comment: '/**\n * Docs for class `Foo`.\n */', - meta: { filename: 'input.jsdoc' }, - classdesc: 'Docs for class `Foo`.', - name: 'Foo', - longname: 'module:foo/bar/baz~Foo', - kind: 'class', - scope: 'inner', - memberof: 'module:foo/bar/baz', - augmentsNested: [], - implementsNested: [], - mixesNested: [], - descendants: [ - 'module:foo/bar/baz~Bar', - 'module:foo/bar/baz~Baz' - ] - } ); - } ); - - it( 'should generate a doclet for a class constructor', () => { - const constructorDoclets = apiDocs.filter( doclet => doclet.longname === 'module:foo/bar/baz~Foo#constructor' ); - - expect( constructorDoclets.length ).to.equal( 1 ); - - expect( constructorDoclets[ 0 ] ).to.deep.equal( { - comment: '/**\n\t * Docs for the constructor.\n\t */', - meta: { filename: 'input.jsdoc' }, - description: 'Docs for the constructor.', - name: 'constructor', - longname: 'module:foo/bar/baz~Foo#constructor', - kind: 'function', - memberof: 'module:foo/bar/baz~Foo', - scope: 'instance', - params: [] - } ); - } ); - - it( 'should generate a doclet for an inherited class', () => { - const classDoclets = apiDocs.filter( doclet => doclet.longname === 'module:foo/bar/baz~Bar' ); - - expect( classDoclets.length ).to.equal( 1 ); - - expect( classDoclets[ 0 ] ).to.deep.equal( { - comment: '/**\n * Docs for the `Bar` class.\n *\n * @extends module:foo/bar/baz~Foo\n */', - meta: { filename: 'input.jsdoc' }, - classdesc: 'Docs for the `Bar` class.', - name: 'Bar', - longname: 'module:foo/bar/baz~Bar', - kind: 'class', - scope: 'inner', - memberof: 'module:foo/bar/baz', - augments: [ - 'module:foo/bar/baz~Foo' - ], - augmentsNested: [ - 'module:foo/bar/baz~Foo' - ], - implementsNested: [], - mixesNested: [], - descendants: [] - } ); - } ); - - it( 'should generate a doclet for an inherited class constructor', () => { - const constructorDoclets = apiDocs.filter( doclet => doclet.longname === 'module:foo/bar/baz~Bar#constructor' ); - - expect( constructorDoclets.length ).to.equal( 1 ); - - expect( constructorDoclets[ 0 ] ).to.deep.equal( { - comment: '/**\n\t * Docs for the constructor.\n\t */', - description: 'Docs for the constructor.', - meta: { filename: 'input.jsdoc' }, - inherited: true, - name: 'constructor', - longname: 'module:foo/bar/baz~Bar#constructor', - kind: 'function', - memberof: 'module:foo/bar/baz~Bar', - scope: 'instance', - params: [] - } ); - } ); - - it( 'should generate a doclet for an inherited class with its own docs', () => { - const classDoclets = apiDocs.filter( doclet => doclet.longname === 'module:foo/bar/baz~Baz' ); - - expect( classDoclets.length ).to.equal( 1 ); - - expect( classDoclets[ 0 ] ).to.deep.equal( { - comment: '/**\n * Docs for the `Baz` class.\n *\n * @extends module:foo/bar/baz~Foo\n */', - meta: { filename: 'input.jsdoc' }, - classdesc: 'Docs for the `Baz` class.', - name: 'Baz', - longname: 'module:foo/bar/baz~Baz', - kind: 'class', - scope: 'inner', - memberof: 'module:foo/bar/baz', - augments: [ - 'module:foo/bar/baz~Foo' - ], - augmentsNested: [ - 'module:foo/bar/baz~Foo' - ], - implementsNested: [], - mixesNested: [], - descendants: [] - } ); - } ); - - it( 'should generate a doclet for an inherited class constructor with its own docs', () => { - const constructorDoclets = apiDocs.filter( doclet => doclet.longname === 'module:foo/bar/baz~Baz#constructor' ); - - expect( constructorDoclets.length ).to.equal( 1 ); - - expect( constructorDoclets[ 0 ] ).to.deep.equal( { - comment: '/**\n\t * Docs for the `Baz` class constructor.\n\t */', - description: 'Docs for the `Baz` class constructor.', - meta: { filename: 'input.jsdoc' }, - name: 'constructor', - longname: 'module:foo/bar/baz~Baz#constructor', - kind: 'function', - memberof: 'module:foo/bar/baz~Baz', - scope: 'instance', - params: [] - } ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/integration-tests/class/input.jsdoc b/packages/jsdoc-plugins/tests/integration-tests/class/input.jsdoc deleted file mode 100644 index b27992e17..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/class/input.jsdoc +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @module foo/bar/baz - */ - -/** - * Docs for class `Foo`. - */ -export class Foo { - /** - * Docs for the constructor. - */ - constructor() { - this.undocumentedVariable = true; - } -} - -/** - * Docs for the `Bar` class. - * - * @extends module:foo/bar/baz~Foo - */ -export class Bar extends Foo { - /** - * @inheritDoc - */ - constructor() { - super(); - - this.undocumentedVariable = false; - } -} - -/** - * Docs for the `Baz` class. - * - * @extends module:foo/bar/baz~Foo - */ -export class Baz extends Foo { - /** - * Docs for the `Baz` class constructor. - */ - constructor() { - super(); - - this.undocumentedVariable = false; - } -} - diff --git a/packages/jsdoc-plugins/tests/integration-tests/events-basics/event-basics.js b/packages/jsdoc-plugins/tests/integration-tests/events-basics/event-basics.js deleted file mode 100644 index 0ce95e5ff..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/events-basics/event-basics.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const extractApiDocs = require( '../_utils/extract-api-docs' ); -const { cloneDeep } = require( 'lodash' ); -const { expect } = require( 'chai' ); - -describe( 'integration test/event basics', () => { - /** @type {Array.} */ - let originalApiDocs; - - /** @type {Array.} */ - let apiDocs; - - before( async () => { - originalApiDocs = await extractApiDocs( __dirname ); - } ); - - beforeEach( () => { - apiDocs = cloneDeep( originalApiDocs ); - } ); - - describe( 'integration/events basics', () => { - it( 'should contain 5 doclets', () => { - expect( apiDocs.length ).to.equal( 5 ); - } ); - - it( 'should contain the module doclet', () => { - const doclet = apiDocs.find( d => d.longname === 'module:foo' ); - - expect( doclet ).to.deep.equal( { - 'comment': '/**\n * @module foo\n */', - 'meta': { - 'filename': 'input.jsdoc' - }, - 'kind': 'module', - 'name': 'foo', - 'longname': 'module:foo' - } ); - } ); - - it( 'should include the class doclet', () => { - const doclet = apiDocs.find( d => d.longname === 'module:foo~Foo' ); - - expect( doclet ).to.deep.equal( { - 'comment': '/**\n * The `Foo` class documentation.\n */', - 'meta': { - 'filename': 'input.jsdoc' - }, - 'classdesc': 'The `Foo` class documentation.', - 'name': 'Foo', - 'longname': 'module:foo~Foo', - 'kind': 'class', - 'memberof': 'module:foo', - 'scope': 'inner', - 'descendants': [], - 'augmentsNested': [], - 'mixesNested': [], - 'implementsNested': [] - } ); - } ); - - it( 'should include a doclet for event declared outside the class', () => { - const doclet = apiDocs.find( d => d.longname === 'module:foo~Foo#event:outside' ); - - expect( doclet ).to.deep.equal( { - 'comment': '/**\n * An event documented outside the class.\n *\n * @event outside\n */', - 'meta': { - 'filename': 'input.jsdoc' - }, - 'description': 'An event documented outside the class.', - 'kind': 'event', - 'name': 'outside', - 'longname': 'module:foo~Foo#event:outside', - 'scope': 'instance', - 'memberof': 'module:foo~Foo', - 'params': [ - { - 'type': { - 'names': [ - 'module:utils/eventinfo~EventInfo' - ] - }, - 'description': '

An object containing information about the fired event.

', - 'name': 'eventInfo' - } - ] - } ); - } ); - - it( 'should include a doclet for event declared at the bottom of the class body', () => { - const doclet = apiDocs.find( d => d.longname === 'module:foo~Foo#event:inside' ); - - expect( doclet ).to.deep.equal( { - 'comment': '/**\n\t * An event documented inside the class.\n\t *\n\t * @event inside\n\t */', - 'meta': { - 'filename': 'input.jsdoc' - }, - 'description': 'An event documented inside the class.', - 'kind': 'event', - 'name': 'inside', - 'longname': 'module:foo~Foo#event:inside', - 'scope': 'instance', - 'memberof': 'module:foo~Foo', - 'params': [ - { - 'type': { - 'names': [ - 'module:utils/eventinfo~EventInfo' - ] - }, - 'description': '

An object containing information about the fired event.

', - 'name': 'eventInfo' - } - ] - } ); - } ); - - it( 'should include the Foo#bar function firing two events', () => { - const doclet = apiDocs.find( d => d.longname === 'module:foo~Foo#bar' ); - - expect( doclet ).to.deep.equal( { - 'comment': '/**\n\t * Fires two events.\n\t *\n\t * @fires inside\n\t * @fires outside\n\t */', - 'meta': { - 'filename': 'input.jsdoc' - }, - 'description': 'Fires two events.', - 'fires': [ - 'module:foo~Foo#event:inside', - 'module:foo~Foo#event:outside' - ], - 'name': 'bar', - 'longname': 'module:foo~Foo#bar', - 'kind': 'function', - 'scope': 'instance', - 'memberof': 'module:foo~Foo', - 'params': [] - } ); - } ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/integration-tests/events-basics/input.jsdoc b/packages/jsdoc-plugins/tests/integration-tests/events-basics/input.jsdoc deleted file mode 100644 index 238947774..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/events-basics/input.jsdoc +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @module foo - */ - -/** - * The `Foo` class documentation. - */ -export default class Foo { - /** - * Fires two events. - * - * @fires inside - * @fires outside - */ - bar() { - - } - - /** - * An event documented inside the class. - * - * @event inside - */ -} - -/** - * An event documented outside the class. - * - * @event outside - */ diff --git a/packages/jsdoc-plugins/tests/integration-tests/exported-variables/exported-variables.js b/packages/jsdoc-plugins/tests/integration-tests/exported-variables/exported-variables.js deleted file mode 100644 index 9f1160fd1..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/exported-variables/exported-variables.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const extractApiDocs = require( '../_utils/extract-api-docs' ); -const { cloneDeep } = require( 'lodash' ); -const { expect } = require( 'chai' ); - -describe( 'integration test/exported-variables', () => { - /** @type {Array.} */ - let originalApiDocs; - - /** @type {Array.} */ - let apiDocs; - - before( async () => { - originalApiDocs = await extractApiDocs( __dirname ); - } ); - - beforeEach( () => { - apiDocs = cloneDeep( originalApiDocs ); - } ); - - describe( 'exported constants and variables', () => { - it( 'doclet for MAGIC_CONSTANT should be generated', () => { - const magicConstantDoclet = apiDocs.find( d => d.longname == 'module:engine/magic~MAGIC_CONSTANT' ); - - expect( magicConstantDoclet ).to.deep.equal( { - comment: '/**\n * Magic constant\n */', - description: 'Magic constant', - kind: 'constant', - longname: 'module:engine/magic~MAGIC_CONSTANT', - memberof: 'module:engine/magic', - meta: { - filename: 'input.jsdoc' - }, - name: 'MAGIC_CONSTANT', - scope: 'inner' - } ); - } ); - - it( 'doclet for magicVariable should be generated', () => { - const magicVariableDoclet = apiDocs.find( d => d.longname == 'module:engine/magic.magicVariable' ); - - expect( magicVariableDoclet ).to.deep.equal( { - comment: '/**\n * Magic variable\n */', - description: 'Magic variable', - kind: 'member', - longname: 'module:engine/magic.magicVariable', - memberof: 'module:engine/magic', - meta: { - filename: 'input.jsdoc' - }, - name: 'magicVariable', - scope: 'static' - } ); - } ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/integration-tests/exported-variables/input.jsdoc b/packages/jsdoc-plugins/tests/integration-tests/exported-variables/input.jsdoc deleted file mode 100644 index 7b0c5de2d..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/exported-variables/input.jsdoc +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -/** - * @module engine/magic - */ - -/** - * Magic constant - */ -export const MAGIC_CONSTANT = 7; - -/** - * Magic variable - */ -export let magicVariable = 3; - -magicVariable++; diff --git a/packages/jsdoc-plugins/tests/integration-tests/functions/functions.js b/packages/jsdoc-plugins/tests/integration-tests/functions/functions.js deleted file mode 100644 index a454d7b14..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/functions/functions.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const extractApiDocs = require( '../_utils/extract-api-docs' ); -const { cloneDeep } = require( 'lodash' ); -const { expect } = require( 'chai' ); - -describe( 'integration test/exported-functions', () => { - /** @type {Array.} */ - let originalApiDocs; - - /** @type {Array.} */ - let apiDocs; - - before( async () => { - originalApiDocs = await extractApiDocs( __dirname ); - } ); - - beforeEach( () => { - apiDocs = cloneDeep( originalApiDocs ); - } ); - - describe( 'exported functions', () => { - it( '3 doclets should be generated', () => { - expect( apiDocs.length ).to.equal( 3 ); - } ); - - it( 'doclet for the default export function should be generated', () => { - const fooDoclet = apiDocs.find( d => d.longname === 'module:foo~foo' ); - - expect( fooDoclet ).to.be.an( 'object' ); - - expect( fooDoclet ).to.deep.equal( { - comment: '/**\n * Function `foo`.\n */', - meta: { - filename: 'input.jsdoc' - }, - description: 'Function `foo`.', - name: 'foo', - longname: 'module:foo~foo', - kind: 'function', - memberof: 'module:foo', - scope: 'inner' - } ); - } ); - - it( 'doclet for the exported function should be generated', () => { - const barDoclet = apiDocs.find( d => d.longname === 'module:foo~bar' ); - - expect( barDoclet ).to.be.an( 'object' ); - - expect( barDoclet ).to.deep.equal( { - comment: '/**\n * Helper function `bar`.\n */', - meta: { - filename: 'input.jsdoc' - }, - description: 'Helper function `bar`.', - name: 'bar', - longname: 'module:foo~bar', - kind: 'function', - memberof: 'module:foo', - scope: 'inner' - } ); - } ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/integration-tests/functions/input.jsdoc b/packages/jsdoc-plugins/tests/integration-tests/functions/input.jsdoc deleted file mode 100644 index c7971139a..000000000 --- a/packages/jsdoc-plugins/tests/integration-tests/functions/input.jsdoc +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @module foo - */ - -/** - * Function `foo`. - */ -export default function foo() { - bar(); -} - -/** - * Helper function `bar`. - */ -export function bar() { - -} diff --git a/packages/jsdoc-plugins/tests/observable-event-provider/addmissingeventdocletsforobservables.js b/packages/jsdoc-plugins/tests/observable-event-provider/addmissingeventdocletsforobservables.js deleted file mode 100644 index 6c2c9a569..000000000 --- a/packages/jsdoc-plugins/tests/observable-event-provider/addmissingeventdocletsforobservables.js +++ /dev/null @@ -1,287 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const { expect } = require( 'chai' ); -const addMissingEventDocletsForObservables = require( '../../lib/observable-event-provider/addmissingeventdocletsforobservables' ); - -describe( 'jsdoc-plugins/observable-event-provider', () => { - describe( 'addMissingEventDocletsForObservables()', () => { - it( 'should provide new event doclet for the observable property', () => { - const inputDoclets = [ { - comment: '...', - meta: { - range: [ - 1861, - 2061 - ], - filename: 'command.js', - lineno: 56, - path: '/workspace/ckeditor5/packages/ckeditor5-core/src', - code: {} - }, - description: '

Flag indicating whether a command is enabled or disabled.

', - observable: true, - readonly: true, - kind: 'member', - name: 'isEnabled', - type: { - names: [ - 'Boolean' - ] - }, - longname: 'module:core/command~Command#isEnabled', - scope: 'instance', - memberof: 'module:core/command~Command', - access: 'protected' - } ]; - - const outputDoclets = addMissingEventDocletsForObservables( inputDoclets ); - - expect( outputDoclets.length ).to.equal( 2 ); - expect( outputDoclets[ 1 ] ).to.deep.equal( { - comment: '', - meta: { - range: [ - 1861, - 2061 - ], - filename: 'command.js', - lineno: 56, - path: '/workspace/ckeditor5/packages/ckeditor5-core/src', - code: {} - }, - description: '

Fired when the isEnabled property changed value.

', - kind: 'event', - name: 'change:isEnabled', - longname: 'module:core/command~Command#event:change:isEnabled', - params: [ { - type: { - names: [ 'module:utils/eventinfo~EventInfo' ] - }, - description: '

An object containing information about the fired event.

', - name: 'eventInfo' - }, - { - type: { - names: [ 'String' ] - }, - description: '

Name of the changed property (isEnabled).

', - name: 'name' - }, - { - type: { - names: [ 'Boolean' ] - }, - description: [ - '

New value of the isEnabled property with given key or null, ', - 'if operation should remove property.

' - ].join( '' ), - name: 'value' - }, - { - type: { - names: [ 'Boolean' ] - }, - description: [ - '

Old value of the isEnabled property with given key or null, ', - 'if property was not set before.

' - ].join( '' ), - name: 'oldValue' - } ], - scope: 'instance', - memberof: 'module:core/command~Command', - access: 'protected' - } ); - } ); - - it( 'should not provide event doclet for an observable property if the doclet already exists', () => { - const inputDoclets = [ { - comment: '...', - meta: { - range: [ - 1861, - 2061 - ], - filename: 'command.js', - lineno: 56, - path: '/workspace/ckeditor5/packages/ckeditor5-core/src', - code: {} - }, - description: '

Flag indicating whether a command is enabled or disabled.

', - observable: true, - readonly: true, - kind: 'member', - name: 'isEnabled', - type: { - names: [ - 'Boolean' - ] - }, - longname: 'module:core/command~Command#isEnabled', - scope: 'instance', - memberof: 'module:core/command~Command' - }, { - kind: 'event', - longname: 'module:core/command~Command#event:change:isEnabled' - } ]; - - const outputDoclets = addMissingEventDocletsForObservables( inputDoclets ); - - expect( outputDoclets.length ).to.equal( 2 ); - } ); - - it( 'should add a proper event name to the fires property', () => { - const inputDoclets = [ { - comment: '/**\n\t\t * Flag indicating whether a command is enabled or disabled.', - meta: { - range: [ - 1861, - 2061 - ], - filename: 'command.js', - lineno: 56, - path: '/workspace/ckeditor5/packages/ckeditor5-core/src', - code: {} - }, - description: '

Flag indicating whether a command is enabled or disabled.

', - observable: true, - readonly: true, - kind: 'member', - name: 'isEnabled', - type: { - names: [ - 'Boolean' - ] - }, - longname: 'module:core/command~Command#isEnabled', - scope: 'instance', - memberof: 'module:core/command~Command', - access: 'public' - } ]; - - const outputDoclets = addMissingEventDocletsForObservables( inputDoclets ); - - expect( outputDoclets[ 0 ].fires ).to.deep.equal( [ - 'module:core/command~Command#event:change:isEnabled' - ] ); - } ); - - it( 'should provide new event doclet with `*` type for the observable property that does not specify type', () => { - const inputDoclets = [ { - comment: '...', - meta: { - range: [ - 1861, - 2061 - ], - filename: 'command.js', - lineno: 56, - path: '/workspace/ckeditor5/packages/ckeditor5-core/src', - code: {} - }, - description: '

Flag indicating whether a command is enabled or disabled.

', - observable: true, - readonly: true, - kind: 'member', - name: 'isEnabled', - longname: 'module:core/command~Command#isEnabled', - scope: 'instance', - memberof: 'module:core/command~Command' - } ]; - - const outputDoclets = addMissingEventDocletsForObservables( inputDoclets ); - - expect( outputDoclets.length ).to.equal( 2 ); - expect( outputDoclets[ 1 ] ).to.deep.equal( { - comment: '', - meta: { - range: [ - 1861, - 2061 - ], - filename: 'command.js', - lineno: 56, - path: '/workspace/ckeditor5/packages/ckeditor5-core/src', - code: {} - }, - description: '

Fired when the isEnabled property changed value.

', - kind: 'event', - name: 'change:isEnabled', - longname: 'module:core/command~Command#event:change:isEnabled', - params: [ { - type: { - names: [ 'module:utils/eventinfo~EventInfo' ] - }, - description: '

An object containing information about the fired event.

', - name: 'eventInfo' - }, - { - type: { - names: [ 'String' ] - }, - description: '

Name of the changed property (isEnabled).

', - name: 'name' - }, - { - type: { - names: [ '*' ] - }, - description: [ - '

New value of the isEnabled property with given key or null, ', - 'if operation should remove property.

' - ].join( '' ), - name: 'value' - }, - { - type: { - names: [ '*' ] - }, - description: [ - '

Old value of the isEnabled property with given key or null, ', - 'if property was not set before.

' - ].join( '' ), - name: 'oldValue' - } ], - scope: 'instance', - memberof: 'module:core/command~Command', - access: 'public' - } ); - } ); - - it( 'should mark new event doclet as inherited if the observable property inherited from other class', () => { - const inputDoclets = [ { - comment: '...', - meta: { - range: [ - 1861, - 2061 - ], - filename: 'command.js', - lineno: 56, - path: '/workspace/ckeditor5/packages/ckeditor5-core/src', - code: {} - }, - description: '

Flag indicating whether a command is enabled or disabled.

', - observable: true, - readonly: true, - kind: 'member', - name: 'isEnabled', - longname: 'module:core/command~Command#isEnabled', - scope: 'instance', - memberof: 'module:core/command~Command', - inherited: true, - mixed: true - } ]; - - const outputDoclets = addMissingEventDocletsForObservables( inputDoclets ); - - expect( outputDoclets.length ).to.equal( 2 ); - expect( outputDoclets[ 1 ].inherited ).to.be.true; - expect( outputDoclets[ 1 ].mixed ).to.be.true; - } ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/relation-fixer/addmissingdoclets.js b/packages/jsdoc-plugins/tests/relation-fixer/addmissingdoclets.js deleted file mode 100644 index 3cddc95a2..000000000 --- a/packages/jsdoc-plugins/tests/relation-fixer/addmissingdoclets.js +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const chai = require( 'chai' ); -const expect = chai.expect; -const addMissingDoclets = require( '../../lib/relation-fixer/addmissingdoclets' ); -const interfaceTestDoclets = require( './test-data/interface' ); -const inheritanceImplicitTestDoclets = require( './test-data/inheritance-implicit' ); -const inheritanceInheritdocTestDoclets = require( './test-data/inheritance-inheritdoc' ); -const unwantedTestDoclets = require( './test-data/unwanted-doclets' ); -const mixinTestDoclets = require( './test-data/mixins' ); - -describe( 'jsdoc-plugins/relation-fixer/addMissingDoclets()', () => { - it( 'should add missing doclets coming from interfaces', () => { - const expectedDoclet = { - name: 'intAProperty', - longname: 'classB.intAProperty', - kind: 'member', - memberof: 'classB', - description: 'intAProp description', - inherited: true - }; - - const newDoclets = addMissingDoclets( interfaceTestDoclets ); - expect( newDoclets ).to.deep.include( expectedDoclet ); - } ); - - it( 'should add missing doclets coming from extended classes implicitly', () => { - const expectedDoclet = { - name: 'classAProp', - longname: 'classB.prop', - kind: 'member', - scope: 'static', - memberof: 'classB', - inherited: true - }; - - const newDoclets = addMissingDoclets( inheritanceImplicitTestDoclets ); - expect( newDoclets ).to.deep.include( expectedDoclet ); - } ); - - it( 'should add missing doclets coming from extended classes with use of `inheritdoc`', () => { - const expectedDoclet = { - name: 'classAProp', - longname: 'classB.prop', - kind: 'member', - scope: 'static', - memberof: 'classB', - description: 'Class A prop description', - inherited: true - }; - - const newDoclets = addMissingDoclets( inheritanceInheritdocTestDoclets ); - expect( newDoclets ).to.deep.include( expectedDoclet ); - } ); - - it( 'should ignore existing doclets when `inheritdoc` was used', () => { - const newDoclets = addMissingDoclets( inheritanceInheritdocTestDoclets ); - const classBPropDoclets = newDoclets.filter( d => d.longname === 'classB.prop' ); - - expect( classBPropDoclets.length ).to.equal( 1 ); - expect( classBPropDoclets[ 0 ].inheritdoc ).to.equal( undefined ); - } ); - - it( 'should add missing doclets of mixed stuff', () => { - const expectedDoclet = { - name: 'mixedProp', - longname: 'classB.mixedProp', - kind: 'event', - memberof: 'classB', - description: 'mixedProp description', - mixed: true - }; - - const newDoclets = addMissingDoclets( mixinTestDoclets ); - expect( newDoclets ).to.deep.include( expectedDoclet ); - } ); - - it( 'should not add doclets of mixed stuff which already have own doclets', () => { - const expectedDoclet = { - name: 'mixedProp', - longname: 'classA.mixedProp', - kind: 'event', - memberof: 'classA', - description: 'mixedProp description', - mixed: true - }; - - const newDoclets = addMissingDoclets( mixinTestDoclets ); - expect( newDoclets ).to.not.deep.include( expectedDoclet ); - } ); - - it( 'should not add doclets which were already inherited (they have inheritdoc property)', () => { - const newDoclets = addMissingDoclets( unwantedTestDoclets ); - const expectedDoclet = newDoclets.find( d => d.longname === 'classB.propA' ); - - expect( expectedDoclet ).to.not.exist; - } ); - - it( 'should not add doclets which have `ignore: true` property', () => { - const newDoclets = addMissingDoclets( unwantedTestDoclets ); - const expectedDoclet = newDoclets.find( d => d.longname === 'classB.propB' ); - - expect( expectedDoclet ).to.not.exist; - } ); - - it( 'should not add doclets which have `undocumented: true` property', () => { - const newDoclets = addMissingDoclets( unwantedTestDoclets ); - const expectedDoclet = newDoclets.find( d => d.longname === 'classB.propC' ); - - expect( expectedDoclet ).to.not.exist; - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/relation-fixer/buildrelations.js b/packages/jsdoc-plugins/tests/relation-fixer/buildrelations.js deleted file mode 100644 index 60a9ea898..000000000 --- a/packages/jsdoc-plugins/tests/relation-fixer/buildrelations.js +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const chai = require( 'chai' ); -const expect = chai.expect; -const buildRelations = require( '../../lib/relation-fixer/buildrelations' ); - -describe( 'JSDoc relation-fixer buildrelations module', () => { - let testDoclets; - let testDoclets2; - - beforeEach( () => { - testDoclets = [ - { - name: 'interfaceA', - longname: 'interfaceA', - kind: 'interface' - }, - { - name: 'interfaceB', - longname: 'interfaceB', - kind: 'interface' - }, - { - name: 'mixinA', - longname: 'mixinA', - kind: 'mixin', - implements: [ - 'interfaceB', - 'interfaceB' - ] - }, - { - name: 'classA', - longname: 'classA', - kind: 'class', - implements: [ - 'interfaceA' - ], - mixes: [ - 'mixinA', - 'mixinA' - ] - }, - { - name: 'classB', - longname: 'classB', - kind: 'class', - augments: [ - 'classA', - 'classA' - ] - }, - { - name: 'classB', - longname: 'classB', - kind: 'class', - augments: [ - 'classA', - 'classA' - ] - } - ]; - - testDoclets2 = [ - { - name: 'interfaceA', - longname: 'interfaceA', - kind: 'interface' - }, - { - name: 'interfaceB', - longname: 'interfaceB', - kind: 'interface', - augments: [ 'interfaceA' ] - }, - { - name: 'classA', - longname: 'classA', - kind: 'class', - implements: [ - 'interfaceB' - ] - }, - { - name: 'classB', - longname: 'classB', - kind: 'class', - augments: [ 'classA' ] - } - ]; - } ); - - it( 'should add implementation chain array to doclets', () => { - const newDoclets = buildRelations( testDoclets ); - const testedDoclet = newDoclets.find( d => d.longname === 'classB' ); - const expectedProp = [ - 'interfaceA', - 'interfaceB' - ]; - - expectedProp.forEach( prop => { - expect( testedDoclet ).to.have.property( 'implementsNested' ).and.to.include( prop ); - } ); - } ); - - it( 'should add mixing chain array to doclets', () => { - const newDoclets = buildRelations( testDoclets ); - const testedDoclet = newDoclets.find( d => d.longname === 'classB' ); - const expectedProp = [ - 'mixinA' - ]; - - expectedProp.forEach( prop => { - expect( testedDoclet ).to.have.property( 'mixesNested' ).and.to.include( prop ); - } ); - } ); - - it( 'should add inheritance chain array to doclets', () => { - const newDoclets = buildRelations( testDoclets ); - const testedDoclet = newDoclets.find( d => d.longname === 'classB' ); - const expectedProp = [ - 'classA' - ]; - - expectedProp.forEach( prop => { - expect( testedDoclet ).to.have.property( 'augmentsNested' ).and.to.include( prop ); - } ); - } ); - - it( 'should add descendants chain array to doclets', () => { - const newDoclets = buildRelations( testDoclets ); - const testedDoclet = newDoclets.find( d => d.longname === 'interfaceB' ); - const expectedProp = [ - 'mixinA', - 'classA', - 'classB' - ]; - - expectedProp.forEach( prop => { - expect( testedDoclet ).to.have.property( 'descendants' ).and.to.include( prop ); - } ); - } ); - - it( 'should not allow duplicates in relation arrays', () => { - const newDoclets = buildRelations( testDoclets ); - const testedClass = newDoclets.find( d => d.longname === 'classB' ); - const testedInterface = newDoclets.find( d => d.longname === 'interfaceB' ); - - // Removing duplicates. - const expectedImplementsNested = Array.from( new Set( testedClass.implementsNested ) ); - const expectedMixesNested = Array.from( new Set( testedClass.mixesNested ) ); - const expectedAugmentsNested = Array.from( new Set( testedClass.augmentsNested ) ); - const expectedDescendants = Array.from( new Set( testedInterface.descendants ) ); - - expect( testedClass ).to.have.property( 'implementsNested' ).and.to.deep.equal( expectedImplementsNested ); - expect( testedClass ).to.have.property( 'mixesNested' ).and.to.deep.equal( expectedMixesNested ); - expect( testedClass ).to.have.property( 'augmentsNested' ).and.to.deep.equal( expectedAugmentsNested ); - expect( testedInterface ).to.have.property( 'descendants' ).and.to.deep.equal( expectedDescendants ); - } ); - - it( 'should not put non-classes to inheritance hierarchy', () => { - const newDoclets = buildRelations( testDoclets2 ); - const testedDoclet = newDoclets.find( d => d.longname === 'classB' ); - - expect( testedDoclet ).to.have.property( 'augmentsNested' ).and.to.deep.equal( [ 'classA' ] ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/relation-fixer/relationfixerintegration.js b/packages/jsdoc-plugins/tests/relation-fixer/relationfixerintegration.js deleted file mode 100644 index c2995cd58..000000000 --- a/packages/jsdoc-plugins/tests/relation-fixer/relationfixerintegration.js +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -const chai = require( 'chai' ); -const expect = chai.expect; -const buildRelations = require( '../../lib/relation-fixer/buildrelations' ); -const addMissingDoclets = require( '../../lib/relation-fixer/addmissingdoclets' ); -const addTypedefProperties = require( '../../lib/relation-fixer/addtypedefproperties' ); - -describe( 'JSDoc relation-fixer plugin', () => { - let testDoclets; - - beforeEach( () => { - testDoclets = [ - { - name: 'interfaceB', - longname: 'interfaceB', - kind: 'interface' - }, - { - name: 'interfaceBProp', - longname: 'interfaceB.prop', - kind: 'member', - scope: 'static', - memberof: 'interfaceB', - description: 'Interface B prop description' - }, - { - name: 'mixinA', - longname: 'mixinA', - kind: 'mixin', - implements: [ - 'interfaceB' - ] - }, - { - name: 'classA', - longname: 'classA', - kind: 'class', - mixes: [ 'mixinA' ] - }, - { - name: 'interfaceBProp', - longname: 'classA.prop', - kind: 'member', - scope: 'static', - memberof: 'classA', - inheritdoc: '' - }, - { - name: 'eventD', - longname: 'classA.eventD', - kind: 'event', - memberof: 'classA' - }, - { - name: 'classB', - longname: 'classB', - kind: 'class', - augments: [ - 'classA' - ], - augmentsNested: [ - 'classA' - ] - }, - { - name: 'interfaceBProp', - longname: 'classB.prop', - kind: 'member', - scope: 'static', - memberof: 'classB', - inheritdoc: '' - }, - { - name: 'typedefA', - longname: 'typedefA', - kind: 'typedef', - properties: [ - { - type: { - names: [ - 'String' - ] - }, - description: 'Some description', - name: 'modelElement' - }, - { - type: { - names: [ - 'String' - ] - }, - description: 'Another description', - name: 'viewElement' - } - ] - }, - { - name: 'typedefB', - longname: 'typedefB', - kind: 'typedef', - augments: [ - 'typedefA' - ], - properties: [ - { - type: { - names: [ - 'String' - ] - }, - description: 'Some other description', - name: 'modelElement' - } - ] - } - ]; - } ); - - it( 'should add missing doclet through relation chain', () => { - const newDoclets = addMissingDoclets( buildRelations( testDoclets ) ); - const expectedDoclet = { - name: 'interfaceBProp', - longname: 'classB.prop', - kind: 'member', - scope: 'static', - memberof: 'classB', - description: 'Interface B prop description', - mixed: true - }; - - expect( newDoclets ).to.deep.include( expectedDoclet ); - } ); - - it( 'should add missing doclet to other links of relation chain', () => { - const newDoclets = addMissingDoclets( buildRelations( testDoclets ) ); - const expectedDoclet = { - name: 'interfaceBProp', - longname: 'classA.prop', - kind: 'member', - scope: 'static', - memberof: 'classA', - description: 'Interface B prop description', - mixed: true - }; - - expect( newDoclets ).to.deep.include( expectedDoclet ); - } ); - - it( 'should add missing events', () => { - const newDoclets = addMissingDoclets( buildRelations( testDoclets ) ); - const expectedDoclet = { - name: 'eventD', - longname: 'classB.eventD', - kind: 'event', - memberof: 'classB', - inherited: true - }; - - expect( newDoclets ).to.deep.include( expectedDoclet ); - } ); - - it( 'should extend typedefs', () => { - const newDoclets = addMissingDoclets( addTypedefProperties( buildRelations( testDoclets ) ) ); - const expectedDoclet = { - name: 'typedefB', - longname: 'typedefB', - kind: 'typedef', - augments: [ - 'typedefA' - ], - augmentsNested: [ - 'typedefA' - ], - implementsNested: [], - mixesNested: [], - descendants: [], - properties: [ - { - type: { - names: [ - 'String' - ] - }, - description: 'Some other description', - name: 'modelElement' - }, - { - type: { - names: [ - 'String' - ] - }, - description: 'Another description', - name: 'viewElement', - inherited: true - } - ] - }; - - expect( newDoclets ).to.deep.include( expectedDoclet ); - } ); -} ); diff --git a/packages/jsdoc-plugins/tests/relation-fixer/test-data/inheritance-implicit.js b/packages/jsdoc-plugins/tests/relation-fixer/test-data/inheritance-implicit.js deleted file mode 100644 index c6a0651b1..000000000 --- a/packages/jsdoc-plugins/tests/relation-fixer/test-data/inheritance-implicit.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -/** @type {Array.} */ -module.exports = [ - { - name: 'classA', - longname: 'classA', - kind: 'class' - }, - { - name: 'classAProp', - longname: 'classA.prop', - kind: 'member', - scope: 'static', - memberof: 'classA' - }, - { - name: 'classB', - longname: 'classB', - kind: 'class', - augments: [ - 'classA' - ], - augmentsNested: [ - 'classA' - ] - } -]; diff --git a/packages/jsdoc-plugins/tests/relation-fixer/test-data/inheritance-inheritdoc.js b/packages/jsdoc-plugins/tests/relation-fixer/test-data/inheritance-inheritdoc.js deleted file mode 100644 index 88b8bdd43..000000000 --- a/packages/jsdoc-plugins/tests/relation-fixer/test-data/inheritance-inheritdoc.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -/** @type {Array.} */ -module.exports = [ - { - name: 'classA', - longname: 'classA', - kind: 'class' - }, - { - name: 'classAProp', - longname: 'classA.prop', - kind: 'member', - scope: 'static', - memberof: 'classA', - description: 'Class A prop description' - }, - { - name: 'classB', - longname: 'classB', - kind: 'class', - augments: [ - 'classA' - ], - augmentsNested: [ - 'classA' - ] - }, - { - name: 'classAProp', - longname: 'classB.prop', - kind: 'member', - scope: 'static', - memberof: 'classB', - inheritdoc: '' - } -]; diff --git a/packages/jsdoc-plugins/tests/relation-fixer/test-data/interface.js b/packages/jsdoc-plugins/tests/relation-fixer/test-data/interface.js deleted file mode 100644 index 885b724fe..000000000 --- a/packages/jsdoc-plugins/tests/relation-fixer/test-data/interface.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -/** @type {Array.} */ -module.exports = [ - { - name: 'interfaceA', - longname: 'interfaceA', - kind: 'interface', - descendants: [ - 'classA', - 'classB' - ] - }, - { - name: 'intAProperty', - longname: 'interfaceA.intAProperty', - kind: 'member', - memberof: 'interfaceA', - description: 'intAProp description' - }, - { - name: 'classA', - longname: 'classA', - kind: 'class', - implements: [ - 'interfaceA' - ], - implementsNested: [ 'interfaceA' ], - descendants: [ 'classB' ] - }, - { - name: 'classB', - longname: 'classB', - kind: 'class', - augments: [ - 'classA' - ], - implementsNested: [ 'interfaceA' ], - augmentsNested: [ 'classA' ] - }, - { - name: 'intAProperty', - longname: 'classB.intAProperty', - kind: 'member', - memberof: 'classB', - inheritdoc: '' - } -]; diff --git a/packages/jsdoc-plugins/tests/relation-fixer/test-data/mixins.js b/packages/jsdoc-plugins/tests/relation-fixer/test-data/mixins.js deleted file mode 100644 index 6f43ce018..000000000 --- a/packages/jsdoc-plugins/tests/relation-fixer/test-data/mixins.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -/** @type {Array.} */ -module.exports = [ - { - name: 'mixinA', - longname: 'mixinA', - kind: 'mixin' - }, - { - name: 'mixedProp', - longname: 'mixinA.mixedProp', - kind: 'event', - memberof: 'mixinA', - description: 'mixedProp description' - }, - { - name: 'classA', - longname: 'classA', - kind: 'class', - mixesNested: [ 'mixinA' ] - }, - { - name: 'classAProp', - longname: 'classA.prop', - kind: 'member', - scope: 'static', - memberof: 'classA' - }, - { - name: 'mixedProp', - longname: 'classA.mixedProp', - kind: 'event', - memberof: 'classA', - inheritdoc: '' - }, - { - name: 'classB', - longname: 'classB', - kind: 'class', - augments: [ - 'classA' - ], - augmentsNested: [ - 'classA' - ], - mixesNested: [ 'mixinA' ] - } -]; diff --git a/packages/jsdoc-plugins/tests/relation-fixer/test-data/unwanted-doclets.js b/packages/jsdoc-plugins/tests/relation-fixer/test-data/unwanted-doclets.js deleted file mode 100644 index 7e603eb34..000000000 --- a/packages/jsdoc-plugins/tests/relation-fixer/test-data/unwanted-doclets.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md. - */ - -'use strict'; - -/** @type {Array.} */ -module.exports = [ - { - name: 'classA', - longname: 'classA', - kind: 'class' - }, - { - name: 'classAPropA', - longname: 'classA.propA', - kind: 'member', - scope: 'static', - memberof: 'classA', - inheritdoc: '' - }, - { - name: 'classAPropB', - longname: 'classA.propB', - kind: 'member', - scope: 'static', - memberof: 'classA', - ignore: true - }, - { - name: 'classAPropC', - longname: 'classA.propC', - kind: 'member', - scope: 'static', - memberof: 'classA', - undocumented: true - }, - { - name: 'classB', - longname: 'classB', - kind: 'class', - augments: [ - 'classA' - ], - augmentsNested: [ - 'classA' - ] - } -]; diff --git a/scripts/changelog.js b/scripts/changelog.js index 8ff5952be..6051ec3f8 100755 --- a/scripts/changelog.js +++ b/scripts/changelog.js @@ -15,10 +15,6 @@ const changelogOptions = { packages: 'packages', releaseBranch: cliArguments.branch, transformScope: name => { - if ( name === 'jsdoc-plugins' ) { - return 'https://www.npmjs.com/package/@ckeditor/jsdoc-plugins'; - } - if ( name === 'typedoc-plugins' ) { return 'https://www.npmjs.com/package/@ckeditor/typedoc-plugins'; }