forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpages.js
155 lines (134 loc) · 5.19 KB
/
pages.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { jest } from '@jest/globals'
import path from 'path'
import { loadPages } from '../../lib/page-data.js'
import libLanguages from '../../lib/languages.js'
import { liquid } from '../../lib/render-content/index.js'
import patterns from '../../lib/patterns.js'
import GithubSlugger from 'github-slugger'
import { decode } from 'html-entities'
import { chain, pick } from 'lodash-es'
import checkIfNextVersionOnly from '../../lib/check-if-next-version-only.js'
import removeFPTFromPath from '../../lib/remove-fpt-from-path.js'
const languageCodes = Object.keys(libLanguages)
const slugger = new GithubSlugger()
describe('pages module', () => {
jest.setTimeout(60 * 1000)
let pages
beforeAll(async () => {
pages = await loadPages()
})
describe('loadPages', () => {
test('yields a non-empty array of Page objects', async () => {
expect(Array.isArray(pages)).toBe(true)
expect(pages.length).toBeGreaterThan(100)
})
test('every page has a `languageCode`', async () => {
expect(pages.every((page) => languageCodes.includes(page.languageCode))).toBe(true)
})
test('every page has a non-empty `permalinks` array', async () => {
const brokenPages = pages
.filter((page) => !Array.isArray(page.permalinks) || page.permalinks.length === 0)
// Ignore pages that only have "next" versions specified and therefore no permalinks;
// These pages are not broken, they just won't render in the currently supported versions.
.filter(
(page) =>
!Object.values(page.versions).every((pageVersion) =>
checkIfNextVersionOnly(pageVersion)
)
)
const expectation = JSON.stringify(
brokenPages.map((page) => page.fullPath),
null,
2
)
expect(brokenPages.length, expectation).toBe(0)
})
test('redirect_from routes are unique across English pages', () => {
const englishPages = chain(pages)
.filter(['languageCode', 'en'])
.filter('redirect_from')
.map((pages) => pick(pages, ['redirect_from', 'applicableVersions']))
.value()
const versionedRedirects = []
englishPages.forEach((page) => {
page.redirect_from.forEach((redirect) => {
page.applicableVersions.forEach((version) => {
versionedRedirects.push(removeFPTFromPath(path.posix.join('/', version, redirect)))
})
})
})
const duplicates = versionedRedirects.reduce((acc, el, i, arr) => {
if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el)
return acc
}, [])
const message = `Found ${duplicates.length} duplicate redirect_from ${
duplicates.length === 1 ? 'path' : 'paths'
}.
Ensure that you don't define the same path more than once in the redirect_from property in a single file and across all English files.
You may also receive this error if you have defined the same children property more than once.\n
${duplicates.join('\n')}`
expect(duplicates.length, message).toBe(0)
})
test('every English page has a filename that matches its slugified title', async () => {
const nonMatches = pages
.filter((page) => {
slugger.reset()
return (
page.languageCode === 'en' && // only check English
!page.relativePath.includes('index.md') && // ignore TOCs
!page.allowTitleToDifferFromFilename && // ignore docs with override
slugger.slug(decode(page.title)) !== path.basename(page.relativePath, '.md')
)
})
// make the output easier to read
.map((page) => {
return JSON.stringify(
{
file: path.basename(page.relativePath),
title: page.title,
path: page.fullPath,
},
null,
2
)
})
const message = `
Found ${nonMatches.length} ${
nonMatches.length === 1 ? 'file' : 'files'
} that do not match their slugified titles.\n
${nonMatches.join('\n')}\n
To fix, run script/reconcile-filenames-with-ids.js\n\n`
expect(nonMatches.length, message).toBe(0)
})
test('every page has valid frontmatter', async () => {
const frontmatterErrors = chain(pages)
// .filter(page => page.languageCode === 'en')
.map((page) => page.frontmatterErrors)
.filter(Boolean)
.flatten()
.value()
const failureMessage =
JSON.stringify(frontmatterErrors, null, 2) +
'\n\n' +
chain(frontmatterErrors).map('filepath').join('\n').value()
expect(frontmatterErrors.length, failureMessage).toBe(0)
})
test('every page has valid Liquid templating', async () => {
const liquidErrors = []
for (const page of pages) {
const markdown = page.raw
if (!patterns.hasLiquid.test(markdown)) continue
try {
await liquid.parse(markdown)
} catch (error) {
liquidErrors.push({
filename: page.fullPath,
error: error.message,
})
}
}
const failureMessage = JSON.stringify(liquidErrors, null, 2)
expect(liquidErrors.length, failureMessage).toBe(0)
})
})
})