'use strict'; const common = require('../common'); // The doctool currently uses js-yaml from the tool/node_modules/eslint/ tree. try { require('../../tools/node_modules/eslint/node_modules/js-yaml'); } catch { common.skip('missing js-yaml (eslint not present)'); } const assert = require('assert'); const { readFile } = require('fs'); const fixtures = require('../common/fixtures'); const { replaceLinks } = require('../../tools/doc/markdown.js'); const html = require('../../tools/doc/html.js'); const path = require('path'); module.paths.unshift( path.join(__dirname, '..', '..', 'tools', 'doc', 'node_modules')); const unified = require('unified'); const markdown = require('remark-parse'); const remark2rehype = require('remark-rehype'); const raw = require('rehype-raw'); const htmlStringify = require('rehype-stringify'); // Test links mapper is an object of the following structure: // { // [filename]: { // [link definition identifier]: [url to the linked resource] // } // } const testLinksMapper = { 'foo': { 'command line options': 'cli.html#cli-options', 'web server': 'example.html' } }; async function toHTML({ input, filename, nodeVersion }) { const content = unified() .use(replaceLinks, { filename, linksMapper: testLinksMapper }) .use(markdown) .use(html.firstHeader) .use(html.preprocessText) .use(html.preprocessElements, { filename }) .use(html.buildToc, { filename, apilinks: {} }) .use(remark2rehype, { allowDangerousHTML: true }) .use(raw) .use(htmlStringify) .processSync(input); return html.toHTML({ input, content, filename, nodeVersion }); } // Test data is a list of objects with two properties. // The file property is the file path. // The html property is some HTML which will be generated by the doctool. // This HTML will be stripped of all whitespace because we don't currently // have an HTML parser. const testData = [ { file: fixtures.path('sample_document.md'), html: '
  1. fish
  2. fish
' + '' }, { file: fixtures.path('order_of_end_tags_5873.md'), html: '

ClassMethod: Buffer.from(array) ' + '#

' + '' }, { file: fixtures.path('doc_with_yaml.md'), html: '

Sample Markdown with YAML info' + '#

' + '

Foobar#

' + '
Added in: v1.0.0
' + '

Describe Foobar in more detail here.

' + '

Foobar II#

' + '
History' + '' + '' + '' + '
VersionChanges
v5.3.0, v4.2.0

Added in: v5.3.0, v4.2.0

v4.2.0

The error parameter can now be' + 'an arrow function.

' + '

Describe Foobar II in more detail here.' + 'fg(1)' + '

Deprecated thingy#' + '

Added in: v1.0.0' + 'Deprecated since: v2.0.0

Describe ' + 'Deprecated thingy in more detail here.' + 'fg(1p)' + '

Something#

' + ' ' + '

Describe Something in more detail here.

' }, { file: fixtures.path('sample_document.md'), html: '
  1. fish
  2. fish
' + '', }, { file: fixtures.path('altdocs.md'), html: '
  • 8.x', }, { file: fixtures.path('document_with_links.md'), html: '

    Usage and Example#' + '

    Usage#

    node \\[options\\] index.js' + '

    Please see the' + 'Command Line Optionsdocument for more information.

    ' + 'Example' + '#

    An example of a' + 'webserverwritten with Node.js which responds with' + '\'Hello, World!\':

    See also#

    Check' + 'out alsothis guide

    ' }, ]; const spaces = /\s/g; testData.forEach(({ file, html }) => { // Normalize expected data by stripping whitespace. const expected = html.replace(spaces, ''); readFile(file, 'utf8', common.mustCall(async (err, input) => { assert.ifError(err); const output = await toHTML({ input: input, filename: 'foo', nodeVersion: process.version }); const actual = output.replace(spaces, ''); // Assert that the input stripped of all whitespace contains the // expected markup. assert(actual.includes(expected), `ACTUAL: ${actual}\nEXPECTED: ${expected}`); })); });