@@ -7,15 +7,16 @@ import * as assert from 'assert';
7
7
import 'mocha' ;
8
8
import * as vscode from 'vscode' ;
9
9
import LinkProvider from '../features/documentLinkProvider' ;
10
+ import { createNewMarkdownEngine } from './engine' ;
10
11
import { InMemoryDocument } from './inMemoryDocument' ;
11
- import { noopToken } from './util' ;
12
+ import { joinLines , noopToken } from './util' ;
12
13
13
14
14
15
const testFile = vscode . Uri . joinPath ( vscode . workspace . workspaceFolders ! [ 0 ] . uri , 'x.md' ) ;
15
16
16
17
function getLinksForFile ( fileContents : string ) {
17
18
const doc = new InMemoryDocument ( testFile , fileContents ) ;
18
- const provider = new LinkProvider ( ) ;
19
+ const provider = new LinkProvider ( createNewMarkdownEngine ( ) ) ;
19
20
return provider . provideDocumentLinks ( doc , noopToken ) ;
20
21
}
21
22
@@ -27,103 +28,103 @@ function assertRangeEqual(expected: vscode.Range, actual: vscode.Range) {
27
28
}
28
29
29
30
suite ( 'markdown.DocumentLinkProvider' , ( ) => {
30
- test ( 'Should not return anything for empty document' , ( ) => {
31
- const links = getLinksForFile ( '' ) ;
31
+ test ( 'Should not return anything for empty document' , async ( ) => {
32
+ const links = await getLinksForFile ( '' ) ;
32
33
assert . strictEqual ( links . length , 0 ) ;
33
34
} ) ;
34
35
35
- test ( 'Should not return anything for simple document without links' , ( ) => {
36
- const links = getLinksForFile ( '# a\nfdasfdfsafsa' ) ;
36
+ test ( 'Should not return anything for simple document without links' , async ( ) => {
37
+ const links = await getLinksForFile ( '# a\nfdasfdfsafsa' ) ;
37
38
assert . strictEqual ( links . length , 0 ) ;
38
39
} ) ;
39
40
40
- test ( 'Should detect basic http links' , ( ) => {
41
- const links = getLinksForFile ( 'a [b](https://example.com) c' ) ;
41
+ test ( 'Should detect basic http links' , async ( ) => {
42
+ const links = await getLinksForFile ( 'a [b](https://example.com) c' ) ;
42
43
assert . strictEqual ( links . length , 1 ) ;
43
44
const [ link ] = links ;
44
45
assertRangeEqual ( link . range , new vscode . Range ( 0 , 6 , 0 , 25 ) ) ;
45
46
} ) ;
46
47
47
- test ( 'Should detect basic workspace links' , ( ) => {
48
+ test ( 'Should detect basic workspace links' , async ( ) => {
48
49
{
49
- const links = getLinksForFile ( 'a [b](./file) c' ) ;
50
+ const links = await getLinksForFile ( 'a [b](./file) c' ) ;
50
51
assert . strictEqual ( links . length , 1 ) ;
51
52
const [ link ] = links ;
52
53
assertRangeEqual ( link . range , new vscode . Range ( 0 , 6 , 0 , 12 ) ) ;
53
54
}
54
55
{
55
- const links = getLinksForFile ( 'a [b](file.png) c' ) ;
56
+ const links = await getLinksForFile ( 'a [b](file.png) c' ) ;
56
57
assert . strictEqual ( links . length , 1 ) ;
57
58
const [ link ] = links ;
58
59
assertRangeEqual ( link . range , new vscode . Range ( 0 , 6 , 0 , 14 ) ) ;
59
60
}
60
61
} ) ;
61
62
62
- test ( 'Should detect links with title' , ( ) => {
63
- const links = getLinksForFile ( 'a [b](https://example.com "abc") c' ) ;
63
+ test ( 'Should detect links with title' , async ( ) => {
64
+ const links = await getLinksForFile ( 'a [b](https://example.com "abc") c' ) ;
64
65
assert . strictEqual ( links . length , 1 ) ;
65
66
const [ link ] = links ;
66
67
assertRangeEqual ( link . range , new vscode . Range ( 0 , 6 , 0 , 25 ) ) ;
67
68
} ) ;
68
69
69
70
// #35245
70
- test ( 'Should handle links with escaped characters in name' , ( ) => {
71
- const links = getLinksForFile ( 'a [b\\]](./file)' ) ;
71
+ test ( 'Should handle links with escaped characters in name' , async ( ) => {
72
+ const links = await getLinksForFile ( 'a [b\\]](./file)' ) ;
72
73
assert . strictEqual ( links . length , 1 ) ;
73
74
const [ link ] = links ;
74
75
assertRangeEqual ( link . range , new vscode . Range ( 0 , 8 , 0 , 14 ) ) ;
75
76
} ) ;
76
77
77
78
78
- test ( 'Should handle links with balanced parens' , ( ) => {
79
+ test ( 'Should handle links with balanced parens' , async ( ) => {
79
80
{
80
- const links = getLinksForFile ( 'a [b](https://example.com/a()c) c' ) ;
81
+ const links = await getLinksForFile ( 'a [b](https://example.com/a()c) c' ) ;
81
82
assert . strictEqual ( links . length , 1 ) ;
82
83
const [ link ] = links ;
83
84
assertRangeEqual ( link . range , new vscode . Range ( 0 , 6 , 0 , 30 ) ) ;
84
85
}
85
86
{
86
- const links = getLinksForFile ( 'a [b](https://example.com/a(b)c) c' ) ;
87
+ const links = await getLinksForFile ( 'a [b](https://example.com/a(b)c) c' ) ;
87
88
assert . strictEqual ( links . length , 1 ) ;
88
89
const [ link ] = links ;
89
90
assertRangeEqual ( link . range , new vscode . Range ( 0 , 6 , 0 , 31 ) ) ;
90
91
91
92
}
92
93
{
93
94
// #49011
94
- const links = getLinksForFile ( '[A link](http://ThisUrlhasParens/A_link(in_parens))' ) ;
95
+ const links = await getLinksForFile ( '[A link](http://ThisUrlhasParens/A_link(in_parens))' ) ;
95
96
assert . strictEqual ( links . length , 1 ) ;
96
97
const [ link ] = links ;
97
98
assertRangeEqual ( link . range , new vscode . Range ( 0 , 9 , 0 , 50 ) ) ;
98
99
}
99
100
} ) ;
100
101
101
- test ( 'Should handle two links without space' , ( ) => {
102
- const links = getLinksForFile ( 'a ([test](test)[test2](test2)) c' ) ;
102
+ test ( 'Should handle two links without space' , async ( ) => {
103
+ const links = await getLinksForFile ( 'a ([test](test)[test2](test2)) c' ) ;
103
104
assert . strictEqual ( links . length , 2 ) ;
104
105
const [ link1 , link2 ] = links ;
105
106
assertRangeEqual ( link1 . range , new vscode . Range ( 0 , 10 , 0 , 14 ) ) ;
106
107
assertRangeEqual ( link2 . range , new vscode . Range ( 0 , 23 , 0 , 28 ) ) ;
107
108
} ) ;
108
109
109
110
// #49238
110
- test ( 'should handle hyperlinked images' , ( ) => {
111
+ test ( 'should handle hyperlinked images' , async ( ) => {
111
112
{
112
- const links = getLinksForFile ( '[](https://example.com)' ) ;
113
+ const links = await getLinksForFile ( '[](https://example.com)' ) ;
113
114
assert . strictEqual ( links . length , 2 ) ;
114
115
const [ link1 , link2 ] = links ;
115
116
assertRangeEqual ( link1 . range , new vscode . Range ( 0 , 13 , 0 , 22 ) ) ;
116
117
assertRangeEqual ( link2 . range , new vscode . Range ( 0 , 25 , 0 , 44 ) ) ;
117
118
}
118
119
{
119
- const links = getLinksForFile ( '[]( https://whitespace.com )' ) ;
120
+ const links = await getLinksForFile ( '[]( https://whitespace.com )' ) ;
120
121
assert . strictEqual ( links . length , 2 ) ;
121
122
const [ link1 , link2 ] = links ;
122
123
assertRangeEqual ( link1 . range , new vscode . Range ( 0 , 7 , 0 , 21 ) ) ;
123
124
assertRangeEqual ( link2 . range , new vscode . Range ( 0 , 26 , 0 , 48 ) ) ;
124
125
}
125
126
{
126
- const links = getLinksForFile ( '[](file1.txt) text [](file2.txt)' ) ;
127
+ const links = await getLinksForFile ( '[](file1.txt) text [](file2.txt)' ) ;
127
128
assert . strictEqual ( links . length , 4 ) ;
128
129
const [ link1 , link2 , link3 , link4 ] = links ;
129
130
assertRangeEqual ( link1 . range , new vscode . Range ( 0 , 6 , 0 , 14 ) ) ;
@@ -133,13 +134,13 @@ suite('markdown.DocumentLinkProvider', () => {
133
134
}
134
135
} ) ;
135
136
136
- test ( 'Should not consider link references starting with ^ character valid (#107471)' , ( ) => {
137
- const links = getLinksForFile ( '[^reference]: https://example.com' ) ;
137
+ test ( 'Should not consider link references starting with ^ character valid (#107471)' , async ( ) => {
138
+ const links = await getLinksForFile ( '[^reference]: https://example.com' ) ;
138
139
assert . strictEqual ( links . length , 0 ) ;
139
140
} ) ;
140
141
141
- test ( 'Should find definitions links with spaces in angle brackets (#136073)' , ( ) => {
142
- const links = getLinksForFile ( [
142
+ test ( 'Should find definitions links with spaces in angle brackets (#136073)' , async ( ) => {
143
+ const links = await getLinksForFile ( [
143
144
'[a]: <b c>' ,
144
145
'[b]: <cd>' ,
145
146
] . join ( '\n' ) ) ;
@@ -149,6 +150,75 @@ suite('markdown.DocumentLinkProvider', () => {
149
150
assertRangeEqual ( link1 . range , new vscode . Range ( 0 , 6 , 0 , 9 ) ) ;
150
151
assertRangeEqual ( link2 . range , new vscode . Range ( 1 , 6 , 1 , 8 ) ) ;
151
152
} ) ;
153
+
154
+ test ( 'Should not consider links in code fenced with backticks' , async ( ) => {
155
+ const text = joinLines (
156
+ '```' ,
157
+ '[b](https://example.com)' ,
158
+ '```' ) ;
159
+ const links = await getLinksForFile ( text ) ;
160
+ assert . strictEqual ( links . length , 0 ) ;
161
+ } ) ;
162
+
163
+ test ( 'Should not consider links in code fenced with tilda' , async ( ) => {
164
+ const text = joinLines (
165
+ '~~~' ,
166
+ '[b](https://example.com)' ,
167
+ '~~~' ) ;
168
+ const links = await getLinksForFile ( text ) ;
169
+ assert . strictEqual ( links . length , 0 ) ;
170
+ } ) ;
171
+
172
+ test ( 'Should not consider links in indented code' , async ( ) => {
173
+ const links = await getLinksForFile ( ' [b](https://example.com)' ) ;
174
+ assert . strictEqual ( links . length , 0 ) ;
175
+ } ) ;
176
+
177
+ test ( 'Should not consider links in inline code span' , async ( ) => {
178
+ const links = await getLinksForFile ( '`[b](https://example.com)`' ) ;
179
+ assert . strictEqual ( links . length , 0 ) ;
180
+ } ) ;
181
+
182
+ test ( 'Should not consider links with code span inside' , async ( ) => {
183
+ const links = await getLinksForFile ( '[li`nk](https://example.com`)' ) ;
184
+ assert . strictEqual ( links . length , 0 ) ;
185
+ } ) ;
186
+
187
+ test ( 'Should not consider links in multiline inline code span' , async ( ) => {
188
+ const text = joinLines (
189
+ '`` ' ,
190
+ '[b](https://example.com)' ,
191
+ '``' ) ;
192
+ const links = await getLinksForFile ( text ) ;
193
+ assert . strictEqual ( links . length , 0 ) ;
194
+ } ) ;
195
+
196
+ test ( 'Should not consider links in multiline inline code span between between text' , async ( ) => {
197
+ const text = joinLines (
198
+ '[b](https://1.com) `[b](https://2.com)' ,
199
+ '` [b](https://3.com)' ) ;
200
+ const links = await getLinksForFile ( text ) ;
201
+ assert . deepStrictEqual ( links . map ( l => l . target ?. authority ) , [ '1.com' , '3.com' ] )
202
+ } ) ;
203
+
204
+ test ( 'Should not consider links in multiline inline code span with new line after the first backtick' , async ( ) => {
205
+ const text = joinLines (
206
+ '`' ,
207
+ '[b](https://example.com)`' ) ;
208
+ const links = await getLinksForFile ( text ) ;
209
+ assert . strictEqual ( links . length , 0 ) ;
210
+ } ) ;
211
+
212
+ test ( 'Should not miss links in invalid multiline inline code span' , async ( ) => {
213
+ const text = joinLines (
214
+ '`` ' ,
215
+ '' ,
216
+ '[b](https://example.com)' ,
217
+ '' ,
218
+ '``' ) ;
219
+ const links = await getLinksForFile ( text ) ;
220
+ assert . strictEqual ( links . length , 1 ) ;
221
+ } ) ;
152
222
} ) ;
153
223
154
224
0 commit comments