@diplodoc/cli-tests 5.27.4 → 5.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/e2e/__snapshots__/crawler-manifest.spec.ts.snap +26 -0
- package/e2e/crawler-manifest.spec.ts +58 -0
- package/e2e/openapi-include-size.spec.ts +55 -0
- package/mocks/crawler-manifest/config/input/.yfm +1 -0
- package/mocks/crawler-manifest/config/input/index.md +3 -0
- package/mocks/crawler-manifest/config/input/toc.yaml +4 -0
- package/mocks/crawler-manifest/no-links/input/index.md +5 -0
- package/mocks/crawler-manifest/no-links/input/toc.yaml +4 -0
- package/mocks/crawler-manifest/with-links/input/redirects.yaml +5 -0
- package/mocks/crawler-manifest/with-links/input/ru/_includes/snippet.md +1 -0
- package/mocks/crawler-manifest/with-links/input/ru/index.md +35 -0
- package/mocks/crawler-manifest/with-links/input/ru/leading.yaml +5 -0
- package/mocks/crawler-manifest/with-links/input/ru/no-links.md +3 -0
- package/mocks/crawler-manifest/with-links/input/ru/references.md +5 -0
- package/mocks/crawler-manifest/with-links/input/toc.yaml +12 -0
- package/mocks/openapi-include-size-exceeds/input/openapi-spec.yaml +190 -0
- package/mocks/openapi-include-size-exceeds/input/toc.yaml +9 -0
- package/mocks/openapi-include-size-within/input/openapi-spec.yaml +16 -0
- package/mocks/openapi-include-size-within/input/toc.yaml +9 -0
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`Crawler manifest > generates crawler-manifest.json 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"ru/index.md": [
|
|
6
|
+
"https://example.com",
|
|
7
|
+
"http://http.example.com",
|
|
8
|
+
"https://autolink.example.com",
|
|
9
|
+
"https://plain.example.com",
|
|
10
|
+
"https://image.example.com/logo.png",
|
|
11
|
+
"https://included.example.com",
|
|
12
|
+
],
|
|
13
|
+
"ru/leading.yaml": [
|
|
14
|
+
"https://yaml.example.com",
|
|
15
|
+
],
|
|
16
|
+
"ru/old-page": [
|
|
17
|
+
"https://external-redirect.example.com",
|
|
18
|
+
],
|
|
19
|
+
"ru/references.md": [
|
|
20
|
+
"https://reference.example.com",
|
|
21
|
+
],
|
|
22
|
+
"toc.yaml": [
|
|
23
|
+
"https://toc.example.com",
|
|
24
|
+
],
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {describe, expect, test} from 'vitest';
|
|
2
|
+
import {join} from 'node:path';
|
|
3
|
+
import {access, readFile} from 'node:fs/promises';
|
|
4
|
+
|
|
5
|
+
import {TestAdapter, getTestPaths} from '../fixtures';
|
|
6
|
+
|
|
7
|
+
describe('Crawler manifest', () => {
|
|
8
|
+
test('generates crawler-manifest.json', async () => {
|
|
9
|
+
const {inputPath, outputPath} = getTestPaths('mocks/crawler-manifest/with-links');
|
|
10
|
+
|
|
11
|
+
await TestAdapter.testBuildPass(inputPath, outputPath, {
|
|
12
|
+
md2md: true,
|
|
13
|
+
md2html: false,
|
|
14
|
+
args: '--crawler-manifest',
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const manifestContent = await readFile(join(outputPath, 'crawler-manifest.json'), 'utf-8');
|
|
18
|
+
|
|
19
|
+
expect(JSON.parse(manifestContent)).toMatchSnapshot();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('does not generate manifest when --crawler-manifest flag is absent', async () => {
|
|
23
|
+
const {inputPath, outputPath} = getTestPaths('mocks/crawler-manifest/with-links');
|
|
24
|
+
|
|
25
|
+
await TestAdapter.testBuildPass(inputPath, outputPath, {
|
|
26
|
+
md2md: true,
|
|
27
|
+
md2html: false,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
await expect(access(join(outputPath, 'crawler-manifest.json'))).rejects.toThrow();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('does not generate manifest when there are no external links', async () => {
|
|
34
|
+
const {inputPath, outputPath} = getTestPaths('mocks/crawler-manifest/no-links');
|
|
35
|
+
|
|
36
|
+
await TestAdapter.testBuildPass(inputPath, outputPath, {
|
|
37
|
+
md2md: true,
|
|
38
|
+
md2html: false,
|
|
39
|
+
args: '--crawler-manifest',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
await expect(access(join(outputPath, 'crawler-manifest.json'))).rejects.toThrow();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('reads crawlerManifest setting from .yfm config file', async () => {
|
|
46
|
+
const {inputPath, outputPath} = getTestPaths('mocks/crawler-manifest/config');
|
|
47
|
+
|
|
48
|
+
await TestAdapter.testBuildPass(inputPath, outputPath, {
|
|
49
|
+
md2md: true,
|
|
50
|
+
md2html: false,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const manifestContent = await readFile(join(outputPath, 'crawler-manifest.json'), 'utf-8');
|
|
54
|
+
const manifest = JSON.parse(manifestContent);
|
|
55
|
+
|
|
56
|
+
expect(manifest['index.md']).toContain('https://config.example.com');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {readFileSync} from 'node:fs';
|
|
2
|
+
import {resolve} from 'node:path';
|
|
3
|
+
import {glob} from 'glob';
|
|
4
|
+
import {describe, expect, it} from 'vitest';
|
|
5
|
+
|
|
6
|
+
import {TestAdapter, getTestPaths} from '../fixtures';
|
|
7
|
+
|
|
8
|
+
const STUB_MARKER = 'This page exceeds the maximum allowed size and cannot be displayed.';
|
|
9
|
+
|
|
10
|
+
describe('OpenAPI max include size', () => {
|
|
11
|
+
it('should replace oversized pages with stub when limit is exceeded', async () => {
|
|
12
|
+
const {inputPath, outputPath} = getTestPaths('mocks/openapi-include-size-exceeds');
|
|
13
|
+
|
|
14
|
+
await TestAdapter.testBuildPass(inputPath, outputPath, {
|
|
15
|
+
md2md: true,
|
|
16
|
+
md2html: false,
|
|
17
|
+
args: '--max-openapi-include-size 1K',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const files = await glob('**/*.md', {cwd: outputPath, nodir: true});
|
|
21
|
+
expect(files.length).toBeGreaterThan(0);
|
|
22
|
+
|
|
23
|
+
const stubbed = [];
|
|
24
|
+
const preserved = [];
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
const content = readFileSync(resolve(outputPath, file), 'utf-8');
|
|
27
|
+
if (content.includes(STUB_MARKER)) {
|
|
28
|
+
stubbed.push(file);
|
|
29
|
+
} else {
|
|
30
|
+
preserved.push(file);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Endpoint pages and main index exceed 1K and should be stubbed
|
|
35
|
+
expect(stubbed.length).toBeGreaterThan(0);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should preserve all content when pages are within limit', async () => {
|
|
39
|
+
const {inputPath, outputPath} = getTestPaths('mocks/openapi-include-size-within');
|
|
40
|
+
|
|
41
|
+
await TestAdapter.testBuildPass(inputPath, outputPath, {
|
|
42
|
+
md2md: true,
|
|
43
|
+
md2html: false,
|
|
44
|
+
args: '--max-openapi-include-size 1K',
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const files = await glob('**/*.md', {cwd: outputPath, nodir: true});
|
|
48
|
+
expect(files.length).toBeGreaterThan(0);
|
|
49
|
+
|
|
50
|
+
for (const file of files) {
|
|
51
|
+
const content = readFileSync(resolve(outputPath, file), 'utf-8');
|
|
52
|
+
expect(content).not.toContain(STUB_MARKER);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
crawlerManifest: true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This snippet contains an [included link](https://included.example.com).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Index
|
|
2
|
+
|
|
3
|
+
Inline link: [example](https://example.com).
|
|
4
|
+
|
|
5
|
+
Http link: [example](http://http.example.com).
|
|
6
|
+
|
|
7
|
+
Autolink: <https://autolink.example.com>.
|
|
8
|
+
|
|
9
|
+
Plain URL: https://plain.example.com.
|
|
10
|
+
|
|
11
|
+
Local link: [relative](./no-links.md).
|
|
12
|
+
|
|
13
|
+
`[inline code link](https://inline-code.example.com)`
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
[block code link](https://block-code.example.com)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
~~~
|
|
20
|
+
[tilde code link](https://tilde-code.example.com)
|
|
21
|
+
~~~
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
url: https://fenced-lang.example.com
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
<!-- [hidden link](https://comment.example.com) -->
|
|
30
|
+
|
|
31
|
+
<!--
|
|
32
|
+
https://multiline-comment.example.com
|
|
33
|
+
-->
|
|
34
|
+
|
|
35
|
+
{% include [snippet](./_includes/snippet.md) %}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
title: Crawler manifest test
|
|
2
|
+
items:
|
|
3
|
+
- name: Index
|
|
4
|
+
href: ru/index.md
|
|
5
|
+
- name: No links
|
|
6
|
+
href: ru/no-links.md
|
|
7
|
+
- name: References
|
|
8
|
+
href: ru/references.md
|
|
9
|
+
- name: Leading
|
|
10
|
+
href: ru/leading.yaml
|
|
11
|
+
- name: External
|
|
12
|
+
href: https://toc.example.com
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
openapi: 3.0.1
|
|
2
|
+
info:
|
|
3
|
+
title: Large Test API
|
|
4
|
+
version: v1
|
|
5
|
+
description: This is a large API specification used for testing the max openapi include size limit.
|
|
6
|
+
servers:
|
|
7
|
+
- url: http://localhost:8080
|
|
8
|
+
description: Generated server url
|
|
9
|
+
paths:
|
|
10
|
+
/users:
|
|
11
|
+
get:
|
|
12
|
+
tags:
|
|
13
|
+
- user-controller
|
|
14
|
+
summary: Get all users
|
|
15
|
+
description: Returns a list of all users in the system with their details.
|
|
16
|
+
operationId: getAllUsers
|
|
17
|
+
parameters:
|
|
18
|
+
- name: page
|
|
19
|
+
in: query
|
|
20
|
+
required: false
|
|
21
|
+
description: Page number for pagination
|
|
22
|
+
schema:
|
|
23
|
+
type: integer
|
|
24
|
+
- name: limit
|
|
25
|
+
in: query
|
|
26
|
+
required: false
|
|
27
|
+
description: Number of items per page
|
|
28
|
+
schema:
|
|
29
|
+
type: integer
|
|
30
|
+
- name: sort
|
|
31
|
+
in: query
|
|
32
|
+
required: false
|
|
33
|
+
description: Sort field
|
|
34
|
+
schema:
|
|
35
|
+
type: string
|
|
36
|
+
responses:
|
|
37
|
+
"200":
|
|
38
|
+
description: Successful operation
|
|
39
|
+
content:
|
|
40
|
+
application/json:
|
|
41
|
+
schema:
|
|
42
|
+
type: array
|
|
43
|
+
items:
|
|
44
|
+
$ref: '#/components/schemas/User'
|
|
45
|
+
"400":
|
|
46
|
+
description: Bad request
|
|
47
|
+
content:
|
|
48
|
+
application/json:
|
|
49
|
+
schema:
|
|
50
|
+
$ref: '#/components/schemas/Error'
|
|
51
|
+
post:
|
|
52
|
+
tags:
|
|
53
|
+
- user-controller
|
|
54
|
+
summary: Create a new user
|
|
55
|
+
description: Creates a new user in the system.
|
|
56
|
+
operationId: createUser
|
|
57
|
+
requestBody:
|
|
58
|
+
required: true
|
|
59
|
+
content:
|
|
60
|
+
application/json:
|
|
61
|
+
schema:
|
|
62
|
+
$ref: '#/components/schemas/UserCreate'
|
|
63
|
+
responses:
|
|
64
|
+
"201":
|
|
65
|
+
description: User created
|
|
66
|
+
content:
|
|
67
|
+
application/json:
|
|
68
|
+
schema:
|
|
69
|
+
$ref: '#/components/schemas/User'
|
|
70
|
+
"400":
|
|
71
|
+
description: Bad request
|
|
72
|
+
content:
|
|
73
|
+
application/json:
|
|
74
|
+
schema:
|
|
75
|
+
$ref: '#/components/schemas/Error'
|
|
76
|
+
/users/{id}:
|
|
77
|
+
get:
|
|
78
|
+
tags:
|
|
79
|
+
- user-controller
|
|
80
|
+
summary: Get user by ID
|
|
81
|
+
description: Returns a single user by their unique identifier.
|
|
82
|
+
operationId: getUserById
|
|
83
|
+
parameters:
|
|
84
|
+
- name: id
|
|
85
|
+
in: path
|
|
86
|
+
required: true
|
|
87
|
+
description: The unique identifier of the user
|
|
88
|
+
schema:
|
|
89
|
+
type: string
|
|
90
|
+
responses:
|
|
91
|
+
"200":
|
|
92
|
+
description: Successful operation
|
|
93
|
+
content:
|
|
94
|
+
application/json:
|
|
95
|
+
schema:
|
|
96
|
+
$ref: '#/components/schemas/User'
|
|
97
|
+
"404":
|
|
98
|
+
description: User not found
|
|
99
|
+
content:
|
|
100
|
+
application/json:
|
|
101
|
+
schema:
|
|
102
|
+
$ref: '#/components/schemas/Error'
|
|
103
|
+
components:
|
|
104
|
+
schemas:
|
|
105
|
+
User:
|
|
106
|
+
type: object
|
|
107
|
+
properties:
|
|
108
|
+
id:
|
|
109
|
+
type: string
|
|
110
|
+
description: Unique identifier
|
|
111
|
+
name:
|
|
112
|
+
type: string
|
|
113
|
+
description: Full name of the user
|
|
114
|
+
email:
|
|
115
|
+
type: string
|
|
116
|
+
description: Email address
|
|
117
|
+
role:
|
|
118
|
+
type: string
|
|
119
|
+
description: User role in the system
|
|
120
|
+
enum: [admin, editor, viewer]
|
|
121
|
+
address:
|
|
122
|
+
$ref: '#/components/schemas/Address'
|
|
123
|
+
metadata:
|
|
124
|
+
$ref: '#/components/schemas/Metadata'
|
|
125
|
+
UserCreate:
|
|
126
|
+
type: object
|
|
127
|
+
required:
|
|
128
|
+
- name
|
|
129
|
+
- email
|
|
130
|
+
properties:
|
|
131
|
+
name:
|
|
132
|
+
type: string
|
|
133
|
+
description: Full name of the user
|
|
134
|
+
email:
|
|
135
|
+
type: string
|
|
136
|
+
description: Email address
|
|
137
|
+
role:
|
|
138
|
+
type: string
|
|
139
|
+
description: User role in the system
|
|
140
|
+
enum: [admin, editor, viewer]
|
|
141
|
+
address:
|
|
142
|
+
$ref: '#/components/schemas/Address'
|
|
143
|
+
Address:
|
|
144
|
+
type: object
|
|
145
|
+
properties:
|
|
146
|
+
street:
|
|
147
|
+
type: string
|
|
148
|
+
description: Street address
|
|
149
|
+
city:
|
|
150
|
+
type: string
|
|
151
|
+
description: City name
|
|
152
|
+
state:
|
|
153
|
+
type: string
|
|
154
|
+
description: State or province
|
|
155
|
+
zip:
|
|
156
|
+
type: string
|
|
157
|
+
description: Postal code
|
|
158
|
+
country:
|
|
159
|
+
type: string
|
|
160
|
+
description: Country name
|
|
161
|
+
Metadata:
|
|
162
|
+
type: object
|
|
163
|
+
properties:
|
|
164
|
+
createdAt:
|
|
165
|
+
type: string
|
|
166
|
+
format: date-time
|
|
167
|
+
description: Creation timestamp
|
|
168
|
+
updatedAt:
|
|
169
|
+
type: string
|
|
170
|
+
format: date-time
|
|
171
|
+
description: Last update timestamp
|
|
172
|
+
lastLogin:
|
|
173
|
+
type: string
|
|
174
|
+
format: date-time
|
|
175
|
+
description: Last login timestamp
|
|
176
|
+
loginCount:
|
|
177
|
+
type: integer
|
|
178
|
+
description: Total number of logins
|
|
179
|
+
Error:
|
|
180
|
+
type: object
|
|
181
|
+
properties:
|
|
182
|
+
code:
|
|
183
|
+
type: integer
|
|
184
|
+
description: Error code
|
|
185
|
+
message:
|
|
186
|
+
type: string
|
|
187
|
+
description: Error message
|
|
188
|
+
details:
|
|
189
|
+
type: string
|
|
190
|
+
description: Detailed error information
|