1
1
/**
2
2
* @typedef {import('mdast').Root } Root
3
3
* @typedef {import('mdast').Blockquote } Blockquote
4
+ * @typedef {import('mdast').BlockContent } BlockContent
4
5
* @typedef {import('mdast').List } List
5
6
* @typedef {import('../index.js').Options } Options
6
7
*
10
11
* @typedef {Options & TestConfig } Config
11
12
*/
12
13
13
- import fs from 'node:fs '
14
- import path from 'node:path '
15
- import test from 'tape '
16
- import { unified } from 'unified '
17
- import remarkParse from 'remark-parse '
18
- import remarkGfm from 'remark -gfm'
14
+ import assert from 'node:assert/strict '
15
+ import fs from 'node:fs/promises '
16
+ import test from 'node:test '
17
+ import { fromMarkdown } from 'mdast-util-from-markdown '
18
+ import { gfmFromMarkdown } from 'mdast-util-gfm '
19
+ import { gfm } from 'micromark-extension -gfm'
19
20
import { visit } from 'unist-util-visit'
20
- import { u } from 'unist-builder'
21
21
import { toc } from '../index.js'
22
22
23
- const join = path . join
23
+ test ( 'mdast-util-toc' , ( ) => {
24
+ assert . equal ( typeof toc , 'function' , 'should be a function' )
24
25
25
- test ( 'mdast-util-toc' , ( t ) => {
26
- t . is ( typeof toc , 'function' , 'should be a function' )
27
-
28
- t . throws (
26
+ assert . throws (
29
27
( ) => {
30
28
// @ts -expect-error runtime.
31
29
toc ( )
32
30
} ,
33
31
/ C a n n o t r e a d p r o p e r t / ,
34
32
'should fail without node'
35
33
)
36
-
37
- t . end ( )
38
34
} )
39
35
40
- test ( 'Fixtures' , ( t ) => {
41
- const root = join ( 'test ', 'fixtures' )
42
- const files = fs . readdirSync ( root )
36
+ test ( 'Fixtures' , async ( ) => {
37
+ const root = new URL ( 'fixtures/ ', import . meta . url )
38
+ const files = await fs . readdir ( root )
43
39
let index = - 1
44
40
45
41
while ( ++ index < files . length ) {
46
42
const name = files [ index ]
47
43
48
44
if ( name . indexOf ( '.' ) === 0 ) continue
49
45
50
- const input = fs . readFileSync ( join ( root , name , ' input.md') )
46
+ const input = await fs . readFile ( new URL ( name + '/ input.md', root ) )
51
47
/** @type {Config } */
52
48
let config = { }
53
49
54
50
try {
55
51
config = JSON . parse (
56
- String ( fs . readFileSync ( join ( root , name , ' config.json') ) )
52
+ String ( await fs . readFile ( new URL ( name + '/ config.json', root ) ) )
57
53
)
58
54
} catch { }
59
55
60
- const processor = unified ( ) . use ( remarkParse ) . use ( remarkGfm )
61
56
const { useCustomHProperty, ...options } = config
62
57
58
+ const tree = fromMarkdown ( input , {
59
+ mdastExtensions : [ gfmFromMarkdown ( ) ] ,
60
+ extensions : [ gfm ( ) ]
61
+ } )
62
+
63
63
if ( useCustomHProperty ) {
64
- processor . use ( ( ) => ( tree ) => {
65
- const node = /** @type {Root } */ ( tree )
66
- visit ( node , 'heading' , ( heading ) => {
67
- heading . data = { hProperties : { id : 'b' } }
68
- } )
64
+ visit ( tree , 'heading' , ( heading ) => {
65
+ heading . data = { hProperties : { id : 'b' } }
69
66
} )
70
67
}
71
68
72
- const tree = /** @type {Root } */ ( processor . runSync ( processor . parse ( input ) ) )
73
69
const actual = toc ( tree , options )
70
+
74
71
/** @type {Root } */
75
72
const expected = JSON . parse (
76
- String ( fs . readFileSync ( join ( root , name , ' output.json') ) )
73
+ String ( await fs . readFile ( new URL ( name + '/ output.json', root ) ) )
77
74
)
78
75
79
- t . deepEqual ( actual , expected , name )
76
+ assert . deepEqual ( actual , expected , name )
80
77
}
81
-
82
- t . end ( )
83
78
} )
84
79
85
- test ( 'processing nodes' , ( t ) => {
86
- const rootNode = /** @type {Root } */ (
87
- u ( 'root' , [
88
- u ( 'heading' , { depth : 1 } , [ u ( 'text' , 'Alpha' ) ] ) ,
89
- u ( 'heading' , { depth : 2 } , [ u ( 'text' , 'Bravo' ) ] )
90
- ] )
91
- )
92
-
93
- const parentNode = /** @type {Blockquote } */ (
94
- u ( 'blockquote' , rootNode . children )
95
- )
96
-
97
- const blockquoteNode = /** @type {Root } */ (
98
- u ( 'root' , [
99
- u ( 'heading' , { depth : 1 } , [ u ( 'text' , 'Charlie' ) ] ) ,
100
- u ( 'heading' , { depth : 2 } , [ u ( 'text' , 'Delta' ) ] ) ,
101
- u ( 'blockquote' , rootNode . children )
102
- ] )
103
- )
80
+ test ( 'processing nodes' , ( ) => {
81
+ /** @type {Array<BlockContent> } */
82
+ const fragment = [
83
+ { type : 'heading' , depth : 1 , children : [ { type : 'text' , value : 'Alpha' } ] } ,
84
+ { type : 'heading' , depth : 2 , children : [ { type : 'text' , value : 'Bravo' } ] }
85
+ ]
104
86
105
87
/** @type {List } */
106
- const expectedRootMap = u ( 'list' , { ordered : false , spread : true } , [
107
- u ( 'listItem' , { spread : true } , [
108
- u ( 'paragraph' , [
109
- u ( 'link' , { title : null , url : '#alpha' } , [ u ( 'text' , 'Alpha' ) ] )
110
- ] ) ,
111
- u ( 'list' , { ordered : false , spread : false } , [
112
- u ( 'listItem' , { spread : false } , [
113
- u ( 'paragraph' , [
114
- u ( 'link' , { title : null , url : '#bravo' } , [ u ( 'text' , 'Bravo' ) ] )
115
- ] )
116
- ] )
117
- ] )
118
- ] )
119
- ] )
120
-
121
- t . deepEqual (
122
- toc ( rootNode ) ,
88
+ const expectedRootMap = {
89
+ type : 'list' ,
90
+ ordered : false ,
91
+ spread : true ,
92
+ children : [
93
+ {
94
+ type : 'listItem' ,
95
+ spread : true ,
96
+ children : [
97
+ {
98
+ type : 'paragraph' ,
99
+ children : [
100
+ {
101
+ type : 'link' ,
102
+ title : null ,
103
+ url : '#alpha' ,
104
+ children : [ { type : 'text' , value : 'Alpha' } ]
105
+ }
106
+ ]
107
+ } ,
108
+ {
109
+ type : 'list' ,
110
+ ordered : false ,
111
+ spread : false ,
112
+ children : [
113
+ {
114
+ type : 'listItem' ,
115
+ spread : false ,
116
+ children : [
117
+ {
118
+ type : 'paragraph' ,
119
+ children : [
120
+ {
121
+ type : 'link' ,
122
+ title : null ,
123
+ url : '#bravo' ,
124
+ children : [ { type : 'text' , value : 'Bravo' } ]
125
+ }
126
+ ]
127
+ }
128
+ ]
129
+ }
130
+ ]
131
+ }
132
+ ]
133
+ }
134
+ ]
135
+ }
136
+
137
+ assert . deepEqual (
138
+ toc ( { type : 'root' , children : fragment } ) ,
123
139
{
124
140
index : null ,
125
141
endIndex : null ,
@@ -128,8 +144,8 @@ test('processing nodes', (t) => {
128
144
'can process root nodes'
129
145
)
130
146
131
- t . deepEqual (
132
- toc ( parentNode ) ,
147
+ assert . deepEqual (
148
+ toc ( { type : 'blockquote' , children : fragment } ) ,
133
149
{
134
150
index : null ,
135
151
endIndex : null ,
@@ -138,15 +154,31 @@ test('processing nodes', (t) => {
138
154
'can process non-root nodes'
139
155
)
140
156
141
- t . deepEqual (
142
- toc ( blockquoteNode , { parents : 'blockquote' } ) ,
157
+ assert . deepEqual (
158
+ toc (
159
+ {
160
+ type : 'root' ,
161
+ children : [
162
+ {
163
+ type : 'heading' ,
164
+ depth : 1 ,
165
+ children : [ { type : 'text' , value : 'Charlie' } ]
166
+ } ,
167
+ {
168
+ type : 'heading' ,
169
+ depth : 2 ,
170
+ children : [ { type : 'text' , value : 'Delta' } ]
171
+ } ,
172
+ { type : 'blockquote' , children : fragment }
173
+ ]
174
+ } ,
175
+ { parents : 'blockquote' }
176
+ ) ,
143
177
{
144
178
index : null ,
145
179
endIndex : null ,
146
180
map : expectedRootMap
147
181
} ,
148
182
'can process custom parent nodes'
149
183
)
150
-
151
- t . end ( )
152
184
} )
0 commit comments