import { expect } from 'chai'; import prepareMarkdown from './prepareMarkdown.mjs'; describe('prepareMarkdown', () => { const defaultParams = { fileRelativeContext: 'test/bar', options: { env: {}, }, }; it('returns the table of contents with html and emojis preserved and tags stripped', () => { const markdown = ` # Support

Foo.

## Community help (free) ### GitHub GitHub logo ### Unofficial 👍 ### Warning ⚠️ ### Header with Pro plan
### Header with \`code\` `; const { docs: { en: { toc }, }, } = prepareMarkdown({ ...defaultParams, translations: [{ filename: 'index.md', markdown, userLanguage: 'en' }], }); expect(toc).to.have.deep.ordered.members([ { children: [ { hash: 'github', level: 3, text: 'GitHub GitHub logo', }, { hash: 'unofficial', level: 3, text: 'Unofficial 👍' }, { hash: 'warning', level: 3, text: 'Warning ⚠️' }, { hash: 'header-with-pro-plan', level: 3, text: 'Header with Pro plan ', }, { hash: 'header-with-code', level: 3, text: 'Header with code', }, ], hash: 'community-help-free', level: 2, text: 'Community help (free)', }, ]); }); it('enables word-break for function signatures', () => { const markdown = ` # Theming

Foo.

## API ### responsiveFontSizes(theme, options) => theme ### createTheme(options, ...args) => theme `; const { docs: { en: { toc }, }, } = prepareMarkdown({ ...defaultParams, translations: [{ filename: 'index.md', markdown, userLanguage: 'en' }], }); expect(toc).to.have.deep.ordered.members([ { children: [ { hash: 'responsivefontsizes-theme-options-theme', level: 3, text: 'responsiveFontSizes(​theme, options) => theme', }, { hash: 'createtheme-options-args-theme', level: 3, text: 'createTheme(​options, ...args) => theme', }, ], hash: 'api', level: 2, text: 'API', }, ]); }); it('use english hash for different locales', () => { const markdownEn = ` # Localization

Foo.

## Locales ### Example ### Use same hash `; const markdownPt = ` # Localização

Foo.

## Idiomas ### Exemplo ### Usar o mesmo hash `; const markdownZh = ` # 所在位置

Foo.

## 语言环境 ### 例 ### 使用相同的哈希 `; const { docs: { en: { toc: tocEn }, pt: { toc: tocPt }, zh: { toc: tocZh }, }, } = prepareMarkdown({ pageFilename: '/same-hash-test', translations: [ { filename: 'localization.md', markdown: markdownEn, userLanguage: 'en' }, { filename: 'localization-pt.md', markdown: markdownPt, userLanguage: 'pt' }, { filename: 'localization-zh.md', markdown: markdownZh, userLanguage: 'zh' }, ], }); expect(tocZh).to.have.deep.ordered.members([ { children: [ { hash: 'example', level: 3, text: '例', }, { hash: 'use-same-hash', level: 3, text: '使用相同的哈希', }, ], hash: 'locales', level: 2, text: '语言环境', }, ]); expect(tocPt).to.have.deep.ordered.members([ { children: [ { hash: 'example', level: 3, text: 'Exemplo', }, { hash: 'use-same-hash', level: 3, text: 'Usar o mesmo hash', }, ], hash: 'locales', level: 2, text: 'Idiomas', }, ]); expect(tocEn).to.have.deep.ordered.members([ { children: [ { hash: 'example', level: 3, text: 'Example', }, { hash: 'use-same-hash', level: 3, text: 'Use same hash', }, ], hash: 'locales', level: 2, text: 'Locales', }, ]); }); it('use translated hash for translations are not synced', () => { const markdownEn = ` # Localization

Foo.

## Locales ### Example ### Use same hash `; const markdownPt = ` # Localização

Foo.

## Idiomas ### Exemplo ### Usar o mesmo hash ### Usar traduzido `; const { docs: { en: { toc: tocEn }, pt: { toc: tocPt }, }, } = prepareMarkdown({ pageFilename: '/same-hash-test', translations: [ { filename: 'localization.md', markdown: markdownEn, userLanguage: 'en' }, { filename: 'localization-pt.md', markdown: markdownPt, userLanguage: 'pt' }, ], }); expect(tocPt).to.have.deep.ordered.members([ { children: [ { hash: 'example', level: 3, text: 'Exemplo', }, { hash: 'use-same-hash', level: 3, text: 'Usar o mesmo hash', }, { hash: 'usar-traduzido', level: 3, text: 'Usar traduzido', }, ], hash: 'locales', level: 2, text: 'Idiomas', }, ]); expect(tocEn).to.have.deep.ordered.members([ { children: [ { hash: 'example', level: 3, text: 'Example', }, { hash: 'use-same-hash', level: 3, text: 'Use same hash', }, ], hash: 'locales', level: 2, text: 'Locales', }, ]); }); it('should report missing trailing splashes', () => { const markdown = ` # Localization

Foo.

[bar](/bar/) [foo](/foo) `; expect(() => { prepareMarkdown({ ...defaultParams, translations: [{ filename: 'index.md', markdown, userLanguage: 'en' }], }); }).to.throw(`docs-infra: Missing trailing slash. The following link: [foo](/foo) in /test/bar/index.md is missing a trailing slash, please add it. See https://ahrefs.com/blog/trailing-slash/ for more details. `); }); it('should report missing leading splashes', () => { const markdown = ` # Localization

Foo.

[bar](/bar/) [foo](foo/) `; expect(() => { prepareMarkdown({ ...defaultParams, translations: [{ filename: 'index.md', markdown, userLanguage: 'en' }], }); }).to.throw(`docs-infra: Missing leading slash. The following link: [foo](foo/) in /test/bar/index.md is missing a leading slash, please add it. `); }); it('should report title too long', () => { const markdown = ` # Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo

Foo.

`; expect(() => { prepareMarkdown({ ...defaultParams, translations: [{ filename: 'index.md', markdown, userLanguage: 'en' }], }); }).to .throw(`docs-infra: The title "Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" is too long (117 characters). It needs to have fewer than 70 characters—ideally less than 60. For more details, see: https://developers.google.com/search/docs/advanced/appearance/title-link `); }); it('should report description too long', () => { const markdown = ` # Foo

Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.

`; expect(() => { prepareMarkdown({ ...defaultParams, translations: [{ filename: 'index.md', markdown, userLanguage: 'en' }], }); }).to .throw(`docs-infra: The description "Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo." is too long (188 characters). It needs to have fewer than 170 characters—ideally less than 160. For more details, see: https://ahrefs.com/blog/meta-description/#4-be-concise `); }); it('should not accept sh', () => { const markdown = ` # Foo

Fo.

\`\`\`sh npm install @mui/material \`\`\` `; expect(() => { prepareMarkdown({ ...defaultParams, translations: [{ filename: 'index.md', markdown, userLanguage: 'en' }], }); }).to.throw(`docs-infra: Unsupported language: "sh" in: \`\`\`sh npm install @mui/material \`\`\` Use "bash" instead. `); }); it('should report duplicated trailing splashes', () => { const markdown = ` # Localization

Foo.

[foo](/foo/) [bar](/bar//#foo) `; expect(() => { prepareMarkdown({ ...defaultParams, translations: [{ filename: 'index.md', markdown, userLanguage: 'en' }], }); }).to.throw(`docs-infra: Duplicated trailing slashes.`); }); });