git.iko.soy/typeable/remark-validate-links
on main help sign in
Add support for GitLab, Bitbucket repositories

Closes GH-16. Closes GH-17.

commitc88aed4a868c48c63429b1903ac463b8c2ff1093 authorTitus Wormer <tituswormer@gmail.com> dateTue 22 Aug 2017, 20:20 (9 years ago) parentd86b38a
11 files changed+581−216
index.js+76−47 package.json+1−1 readme.md+14−10 test/fixtures/bitbucket.md+63 test/fixtures/examples/bitbucket.md+39 test/fixtures/examples/example.md → test/fixtures/examples/github.md+9−9 test/fixtures/examples/gitlab.md+39 test/fixtures/example.md → test/fixtures/github.md+12−12 test/fixtures/gitlab.md+63 test/fixtures/suggestions.md+2−2 test/index.js+263−135
index.js+76−47
@@ -6,20 +6,37 @@ var path = require('path');
66var propose = require('propose');
77var visit = require('unist-util-visit');
88var definitions = require('mdast-util-definitions');
9−var gh = require('github-url-to-object');
9+var hostedGitInfo = require('hosted-git-info');
1010var urljoin = require('urljoin');
1111var slug = require('remark-slug');
1212var xtend = require('xtend');
1313
1414module.exports = attacher;
1515
16−completer.pluginId = 'remark-validate-links';
16+var referenceId = 'remarkValidateLinksReferences';
17+var landmarkId = 'remarkValidateLinksLandmarks';
18+var sourceId = 'remark-validate-links';
19+
20+completer.pluginId = sourceId;
1721
1822var exists = fs.existsSync;
1923var parse = url.parse;
2024
25+var viewPaths = {
26+ github: 'blob',
27+ gitlab: 'blob',
28+ bitbucket: 'src'
29+};
30+
31+var headingPrefixes = {
32+ github: '#',
33+ gitlab: '#',
34+ bitbucket: '#markdown-header-'
35+};
36+
2137function attacher(options, fileSet) {
2238 var repo = (options || {}).repository;
39+ var info;
2340 var pack;
2441
2542 /* Throw when not on the CLI. */
@@ -40,17 +57,25 @@ function attacher(options, fileSet) {
4057 repo = pack.repository ? pack.repository.url || pack.repository : '';
4158 }
4259
43− repo = repo ? gh(repo) : {};
60+ if (repo) {
61+ info = hostedGitInfo.fromUrl(repo);
62+
63+ if (!info) {
64+ throw new Error('remark-validate-links cannot parse `repository` (`' + repo + '`)');
65+ } else if (info.domain === 'gist.github.com') {
66+ throw new Error('remark-validate-links does not support gist repositories');
67+ }
68+ }
4469
4570 /* Attach a `completer`. */
4671 fileSet.use(completer);
4772
48− /* Attach `slug`. */
73+ /* Attach `slug` and a plugin that adds our transformer after it. */
4974 this.use(slug).use(subplugin);
5075
5176 function subplugin() {
5277 /* Expose transformer. */
53− return transformerFactory({user: repo.user, repo: repo.repo}, fileSet);
78+ return transformerFactory(fileSet, info);
5479 }
5580}
5681
@@ -58,27 +83,30 @@ function attacher(options, fileSet) {
5883function completer(set, done) {
5984 var exposed = {};
6085
61− set.valueOf().forEach(function (file) {
62− var landmarks = file.data.remarkValidateLinksLandmarks;
86+ set.valueOf().forEach(expose);
87+ set.valueOf().forEach(check);
88+
89+ done();
90+
91+ function expose(file) {
92+ var landmarks = file.data[landmarkId];
6393
6494 if (landmarks) {
6595 exposed = xtend(exposed, landmarks);
6696 }
67− });
97+ }
6898
69− set.valueOf().forEach(function (file) {
99+ function check(file) {
70100 /* istanbul ignore else - stdin */
71101 if (file.path) {
72102 validate(exposed, file);
73103 }
74− });
75−
76− done();
104+ }
77105}
78106
79107/* Factory to create a transformer based on the given
80− * project and set. */
81−function transformerFactory(project, fileSet) {
108+ * info and set. */
109+function transformerFactory(fileSet, info) {
82110 return transformer;
83111
84112 /* Transformer. Adds references files to the set. */
@@ -97,7 +125,7 @@ function transformerFactory(project, fileSet) {
97125 return;
98126 }
99127
100− references = gatherReferences(file, ast, project);
128+ references = gatherReferences(file, ast, info);
101129 current = getPathname(filePath);
102130
103131 for (link in references) {
@@ -115,7 +143,12 @@ function transformerFactory(project, fileSet) {
115143
116144 landmarks[filePath] = true;
117145
118− visit(ast, function (node) {
146+ visit(ast, mark);
147+
148+ space[referenceId] = references;
149+ space[landmarkId] = landmarks;
150+
151+ function mark(node) {
119152 var data = node.data || {};
120153 var attrs = data.hProperties || data.htmlAttributes || {};
121154 var id = attrs.name || attrs.id || data.id;
@@ -123,18 +156,13 @@ function transformerFactory(project, fileSet) {
123156 if (id) {
124157 landmarks[filePath + '#' + id] = true;
125158 }
126− });
127−
128− space.remarkValidateLinksReferences = references;
129− space.remarkValidateLinksLandmarks = landmarks;
159+ }
130160 }
131161}
132162
133−/* Check if `file` references headings or files not in
134− * `exposed`. If `project` is given, normalizes GitHub blob
135− * URLs. */
163+/* Check if `file` references headings or files not in `exposed`. */
136164function validate(exposed, file) {
137− var references = file.data.remarkValidateLinksReferences;
165+ var references = file.data[referenceId];
138166 var filePath = file.path;
139167 var reference;
140168 var nodes;
@@ -186,19 +214,29 @@ function validate(exposed, file) {
186214
187215/* Gather references: a map of file-paths references
188216 * to be one or more nodes. */
189−function gatherReferences(file, tree, project) {
217+function gatherReferences(file, tree, info) {
190218 var cache = {};
191219 var filePath = file.path;
192220 var dirname = file.dirname;
193221 var getDefinition;
194222 var prefix = '';
223+ var headingPrefix = '#';
195224
196225 getDefinition = definitions(tree);
197226
198− if (project.user && project.repo) {
199− prefix = '/' + project.user + '/' + project.repo + '/blob/';
227+ if (info && info.type in viewPaths) {
228+ prefix = '/' + info.path() + '/' + viewPaths[info.type] + '/';
200229 }
201230
231+ if (info && info.type in headingPrefixes) {
232+ headingPrefix = headingPrefixes[info.type];
233+ }
234+
235+ visit(tree, 'link', onlink);
236+ visit(tree, 'linkReference', onlink);
237+
238+ return cache;
239+
202240 /* Handle new links. */
203241 function onlink(node) {
204242 var link = node.url;
@@ -235,18 +273,13 @@ function gatherReferences(file, tree, project) {
235273 }
236274 }
237275
238− /* Handle full links.
239− * Only works with GitHub.
240− */
276+ /* Handle full links. */
241277 if (uri.hostname) {
242278 if (!prefix) {
243279 return;
244280 }
245281
246− if (
247− uri.hostname !== 'github.com' ||
248− uri.pathname.slice(0, prefix.length) !== prefix
249− ) {
282+ if (uri.hostname !== info.domain || uri.pathname.slice(0, prefix.length) !== prefix) {
250283 return;
251284 }
252285
@@ -260,20 +293,18 @@ function gatherReferences(file, tree, project) {
260293 * Currently, I’m ignoring this and just not
261294 * supporting branches. */
262295 link = link.slice(link.indexOf('/') + 1);
263−
264− uri = parse(link);
265296 }
266297
267298 /* Handle file links, or combinations of files
268299 * and hashes. */
269− index = link.indexOf('#');
300+ index = link.indexOf(headingPrefix);
270301
271302 if (index === -1) {
272303 pathname = link;
273304 hash = null;
274305 } else {
275306 pathname = link.slice(0, index);
276− hash = link.slice(index + 1);
307+ hash = link.slice(index + headingPrefix.length);
277308 }
278309
279310 if (!cache[pathname]) {
@@ -283,6 +314,7 @@ function gatherReferences(file, tree, project) {
283314 cache[pathname].push(node);
284315
285316 if (hash) {
317+ link = pathname + '#' + hash;
286318 if (!cache[link]) {
287319 cache[link] = [];
288320 }
@@ -290,21 +322,18 @@ function gatherReferences(file, tree, project) {
290322 cache[link].push(node);
291323 }
292324 }
293−
294− visit(tree, 'link', onlink);
295− visit(tree, 'linkReference', onlink);
296−
297− return cache;
298325}
299326
300327/* Utilitity to warn `reason` for each node in `nodes`,
301328 * on `file`. */
302329function warnAll(file, nodes, reason) {
303− nodes.forEach(function (node) {
330+ nodes.forEach(one);
331+
332+ function one(node) {
304333 var message = file.message(reason, node);
305− message.source = 'remark-validate-links';
306− message.ruleId = 'remark-validate-links';
307− });
334+ message.source = sourceId;
335+ message.ruleId = sourceId;
336+ }
308337}
309338
310339/* Suggest a possible similar reference. */
package.json+1−1
@@ -21,7 +21,7 @@
2121 "index.js"
2222 ],
2323 "dependencies": {
24− "github-url-to-object": "^4.0.0",
24+ "hosted-git-info": "^2.5.0",
2525 "mdast-util-definitions": "^1.0.0",
2626 "propose": "0.0.5",
2727 "remark-slug": "^4.2.1",
readme.md+14−10
@@ -81,27 +81,31 @@ directory.
8181remark --use 'validate-links=repository:"foo/bar"' example.md
8282```
8383
84−When a repository is given or detected, links to GitHub are normalized
85−to the file-system. For example,
86−`https://github.com/foo/bar/blob/master/example.md` becomes `example.md`.
84+When a repository is given or detected (supporting GitHub, GitLab, and
85+Bitbucket), links to the only files are normalized to the file-system.
86+For example, `https://github.com/foo/bar/blob/master/example.md` becomes
87+`example.md`.
8788
8889You can define this repository in [configuration files][cli] too.
8990An example `.remarkrc` file could look as follows:
9091
9192```json
9293{
93− "plugins": {
94− "validate-links": {
95− "repository": "foo/bar"
96− }
97− }
94+ "plugins": [
95+ [
96+ "validate-links",
97+ {
98+ "repository": "foo/bar"
99+ }
100+ ]
101+ ]
98102}
99103```
100104
101105## Integration
102106
103−**remark-validate-links** can detect anchors on nodes through
104−several properties on nodes:
107+`remark-validate-links` can detect anchors on nodes through several properties
108+on nodes:
105109
106110* `node.data.hProperties.name` — Used by [`remark-html`][remark-html]
107111 to create a `name` attribute, which anchors can link to
test/fixtures/bitbucket.mdnew file+63
@@ -0,0 +1,63 @@
1+# Hello
2+
3+This is a valid relative heading [link](#markdown-header-hello).
4+
5+This is an invalid relative heading [link](#markdown-header-world).
6+
7+## Files
8+
9+This is a valid relative file [link](https://bitbucket.org/wooorm/test/src/master/examples/bitbucket.md).
10+
11+So is this [link](https://bitbucket.org/wooorm/test/src/foo-bar/examples/bitbucket.md).
12+
13+And this [link](./examples/bitbucket.md).
14+
15+And this [link](examples/bitbucket.md).
16+
17+This is a valid external [file](../index.js).
18+
19+This is an invalid relative file [link](https://bitbucket.org/wooorm/test/src/master/examples/world.md).
20+
21+So is this [link](https://bitbucket.org/wooorm/test/src/foo-bar/examples/world.md).
22+
23+And this [link](./examples/world.md).
24+
25+And this [link](examples/world.md).
26+
27+## Combination
28+
29+Valid: [a](./examples/bitbucket.md#markdown-header-hello).
30+
31+Valid: [b](examples/bitbucket.md#markdown-header-hello).
32+
33+Valid: [c](https://bitbucket.org/wooorm/test/src/master/examples/bitbucket.md#markdown-header-hello).
34+
35+Valid: [d](https://bitbucket.org/wooorm/test/src/foo-bar/examples/bitbucket.md#markdown-header-hello).
36+
37+Invalid: [e](./examples/bitbucket.md#markdown-header-world).
38+
39+Invalid: [f](examples/bitbucket.md#markdown-header-world).
40+
41+Invalid: [g](https://bitbucket.org/wooorm/test/src/master/examples/bitbucket.md#markdown-header-world).
42+
43+Invalid: [h](https://bitbucket.org/wooorm/test/src/foo-bar/examples/bitbucket.md#markdown-header-world).
44+
45+Invalid: [i](./examples/world.md#markdown-header-hello).
46+
47+Invalid: [j](examples/world.md#markdown-header-hello).
48+
49+Invalid: [k](https://bitbucket.org/wooorm/test/src/master/examples/world.md#markdown-header-hello).
50+
51+Invalid: [l](https://bitbucket.org/wooorm/test/src/foo-bar/examples/world.md#markdown-header-hello).
52+
53+## External
54+
55+These are all invalid, because they do not link to Bitbucket.
56+
57+Valid: [a](irc://foo).
58+
59+Valid: [b](http://example.com).
60+
61+Valid: [b](http://example.com/foo/bar/baz).
62+
63+Valid: [b](http://github.com/wooorm/test/blob/foo-bar/examples/world.md#markdown-header-hello).
test/fixtures/examples/bitbucket.mdnew file+39
@@ -0,0 +1,39 @@
1+# Hello
2+
3+This is a valid relative heading [link](#markdown-header-hello).
4+
5+This is an invalid relative heading [link](#markdown-header-world).
6+
7+## Files
8+
9+This is a valid relative file [link](https://bitbucket.org/wooorm/test/src/master/bitbucket.md).
10+
11+So is this [link](https://bitbucket.org/wooorm/test/src/foo-bar/bitbucket.md).
12+
13+And this [link](../bitbucket.md).
14+
15+This is an invalid relative file [link](https://bitbucket.org/wooorm/test/src/master/world.md).
16+
17+So is this [link](https://bitbucket.org/wooorm/test/src/foo-bar/world.md).
18+
19+And this [link](../world.md).
20+
21+## Combination
22+
23+Valid: [a](../bitbucket.md#markdown-header-hello).
24+
25+Valid: [b](https://bitbucket.org/wooorm/test/src/master/bitbucket.md#markdown-header-hello).
26+
27+Valid: [c](https://bitbucket.org/wooorm/test/src/foo-bar/bitbucket.md#markdown-header-hello).
28+
29+Invalid: [d](../bitbucket.md#markdown-header-world).
30+
31+Invalid: [e](https://bitbucket.org/wooorm/test/src/master/bitbucket.md#markdown-header-world).
32+
33+Invalid: [f](https://bitbucket.org/wooorm/test/src/foo-bar/bitbucket.md#markdown-header-world).
34+
35+Invalid: [g](../world.md#markdown-header-hello).
36+
37+Invalid: [h](https://bitbucket.org/wooorm/test/src/master/world.md#markdown-header-hello).
38+
39+Invalid: [i](https://bitbucket.org/wooorm/test/src/foo-bar/world.md#markdown-header-hello).
test/fixtures/examples/example.md → test/fixtures/examples/github.mdrenamed+9−9
@@ -6,11 +6,11 @@ This is an invalid relative heading [link](#world).
66
77## Files
88
9−This is a valid relative file [link](https://github.com/wooorm/test/blob/master/example.md).
9+This is a valid relative file [link](https://github.com/wooorm/test/blob/master/github.md).
1010
11−So is this [link](https://github.com/wooorm/test/blob/foo-bar/example.md).
11+So is this [link](https://github.com/wooorm/test/blob/foo-bar/github.md).
1212
13−And this [link](../example.md).
13+And this [link](../github.md).
1414
1515This is an invalid relative file [link](https://github.com/wooorm/test/blob/master/world.md).
1616
@@ -20,17 +20,17 @@ And this [link](../world.md).
2020
2121## Combination
2222
23−Valid: [a](../example.md#hello).
23+Valid: [a](../github.md#hello).
2424
25−Valid: [b](https://github.com/wooorm/test/blob/master/example.md#hello).
25+Valid: [b](https://github.com/wooorm/test/blob/master/github.md#hello).
2626
27−Valid: [c](https://github.com/wooorm/test/blob/foo-bar/example.md#hello).
27+Valid: [c](https://github.com/wooorm/test/blob/foo-bar/github.md#hello).
2828
29−Invalid: [d](../example.md#world).
29+Invalid: [d](../github.md#world).
3030
31−Invalid: [e](https://github.com/wooorm/test/blob/master/example.md#world).
31+Invalid: [e](https://github.com/wooorm/test/blob/master/github.md#world).
3232
33−Invalid: [f](https://github.com/wooorm/test/blob/foo-bar/example.md#world).
33+Invalid: [f](https://github.com/wooorm/test/blob/foo-bar/github.md#world).
3434
3535Invalid: [g](../world.md#hello).
3636
test/fixtures/examples/gitlab.mdnew file+39
@@ -0,0 +1,39 @@
1+# Hello
2+
3+This is a valid relative heading [link](#hello).
4+
5+This is an invalid relative heading [link](#world).
6+
7+## Files
8+
9+This is a valid relative file [link](https://gitlab.com/wooorm/test/blob/master/gitlab.md).
10+
11+So is this [link](https://gitlab.com/wooorm/test/blob/foo-bar/gitlab.md).
12+
13+And this [link](../gitlab.md).
14+
15+This is an invalid relative file [link](https://gitlab.com/wooorm/test/blob/master/world.md).
16+
17+So is this [link](https://gitlab.com/wooorm/test/blob/foo-bar/world.md).
18+
19+And this [link](../world.md).
20+
21+## Combination
22+
23+Valid: [a](../gitlab.md#hello).
24+
25+Valid: [b](https://gitlab.com/wooorm/test/blob/master/gitlab.md#hello).
26+
27+Valid: [c](https://gitlab.com/wooorm/test/blob/foo-bar/gitlab.md#hello).
28+
29+Invalid: [d](../gitlab.md#world).
30+
31+Invalid: [e](https://gitlab.com/wooorm/test/blob/master/gitlab.md#world).
32+
33+Invalid: [f](https://gitlab.com/wooorm/test/blob/foo-bar/gitlab.md#world).
34+
35+Invalid: [g](../world.md#hello).
36+
37+Invalid: [h](https://gitlab.com/wooorm/test/blob/master/world.md#hello).
38+
39+Invalid: [i](https://gitlab.com/wooorm/test/blob/foo-bar/world.md#hello).
test/fixtures/example.md → test/fixtures/github.mdrenamed+12−12
@@ -6,13 +6,13 @@ This is an invalid relative heading [link](#world).
66
77## Files
88
9−This is a valid relative file [link](https://github.com/wooorm/test/blob/master/examples/example.md).
9+This is a valid relative file [link](https://github.com/wooorm/test/blob/master/examples/github.md).
1010
11−So is this [link](https://github.com/wooorm/test/blob/foo-bar/examples/example.md).
11+So is this [link](https://github.com/wooorm/test/blob/foo-bar/examples/github.md).
1212
13−And this [link](./examples/example.md).
13+And this [link](./examples/github.md).
1414
15−And this [link](examples/example.md).
15+And this [link](examples/github.md).
1616
1717This is a valid external [file](../index.js).
1818
@@ -26,21 +26,21 @@ And this [link](examples/world.md).
2626
2727## Combination
2828
29−Valid: [a](./examples/example.md#hello).
29+Valid: [a](./examples/github.md#hello).
3030
31−Valid: [b](examples/example.md#hello).
31+Valid: [b](examples/github.md#hello).
3232
33−Valid: [c](https://github.com/wooorm/test/blob/master/examples/example.md#hello).
33+Valid: [c](https://github.com/wooorm/test/blob/master/examples/github.md#hello).
3434
35−Valid: [d](https://github.com/wooorm/test/blob/foo-bar/examples/example.md#hello).
35+Valid: [d](https://github.com/wooorm/test/blob/foo-bar/examples/github.md#hello).
3636
37−Invalid: [e](./examples/example.md#world).
37+Invalid: [e](./examples/github.md#world).
3838
39−Invalid: [f](examples/example.md#world).
39+Invalid: [f](examples/github.md#world).
4040
41−Invalid: [g](https://github.com/wooorm/test/blob/master/examples/example.md#world).
41+Invalid: [g](https://github.com/wooorm/test/blob/master/examples/github.md#world).
4242
43−Invalid: [h](https://github.com/wooorm/test/blob/foo-bar/examples/example.md#world).
43+Invalid: [h](https://github.com/wooorm/test/blob/foo-bar/examples/github.md#world).
4444
4545Invalid: [i](./examples/world.md#hello).
4646
test/fixtures/gitlab.mdnew file+63
@@ -0,0 +1,63 @@
1+# Hello
2+
3+This is a valid relative heading [link](#hello).
4+
5+This is an invalid relative heading [link](#world).
6+
7+## Files
8+
9+This is a valid relative file [link](https://gitlab.com/wooorm/test/blob/master/examples/gitlab.md).
10+
11+So is this [link](https://gitlab.com/wooorm/test/blob/foo-bar/examples/gitlab.md).
12+
13+And this [link](./examples/gitlab.md).
14+
15+And this [link](examples/gitlab.md).
16+
17+This is a valid external [file](../index.js).
18+
19+This is an invalid relative file [link](https://gitlab.com/wooorm/test/blob/master/examples/world.md).
20+
21+So is this [link](https://gitlab.com/wooorm/test/blob/foo-bar/examples/world.md).
22+
23+And this [link](./examples/world.md).
24+
25+And this [link](examples/world.md).
26+
27+## Combination
28+
29+Valid: [a](./examples/gitlab.md#hello).
30+
31+Valid: [b](examples/gitlab.md#hello).
32+
33+Valid: [c](https://gitlab.com/wooorm/test/blob/master/examples/gitlab.md#hello).
34+
35+Valid: [d](https://gitlab.com/wooorm/test/blob/foo-bar/examples/gitlab.md#hello).
36+
37+Invalid: [e](./examples/gitlab.md#world).
38+
39+Invalid: [f](examples/gitlab.md#world).
40+
41+Invalid: [g](https://gitlab.com/wooorm/test/blob/master/examples/gitlab.md#world).
42+
43+Invalid: [h](https://gitlab.com/wooorm/test/blob/foo-bar/examples/gitlab.md#world).
44+
45+Invalid: [i](./examples/world.md#hello).
46+
47+Invalid: [j](examples/world.md#hello).
48+
49+Invalid: [k](https://gitlab.com/wooorm/test/blob/master/examples/world.md#hello).
50+
51+Invalid: [l](https://gitlab.com/wooorm/test/blob/foo-bar/examples/world.md#hello).
52+
53+## External
54+
55+These are all invalid, because they do not link to GitLab.
56+
57+Valid: [a](irc://foo).
58+
59+Valid: [b](http://example.com).
60+
61+Valid: [b](http://example.com/foo/bar/baz).
62+
63+Valid: [b](http://bitbucket.com/wooorm/test/blob/foo-bar/examples/world.md#hello).
test/fixtures/suggestions.md+2−2
@@ -4,8 +4,8 @@ This should suggest: [link](#helloo).
44
55## Files
66
7−So should this: [k](example.md#fiiiles).
7+So should this: [k](github.md#fiiiles).
88
9−##
9+##
1010
1111An empty header.
test/index.js+263−135
@@ -19,7 +19,7 @@ var bin = path.join('..', '..', 'node_modules', '.bin', 'remark');
1919var source = ' remark-validate-links remark-validate-links';
2020
2121test('remark-validate-links', function (t) {
22− t.plan(8);
22+ t.plan(12);
2323
2424 t.throws(
2525 function () {
@@ -29,18 +29,65 @@ test('remark-validate-links', function (t) {
2929 'should throw an error when not on the CLI'
3030 );
3131
32+ t.test('should throw on unparsable git repositories', function (st) {
33+ st.plan(1);
34+
35+ execa(bin, [
36+ '--no-config',
37+ '--no-ignore',
38+ '--use',
39+ '../..=repository:"invalid:shortcode"',
40+ 'definitions.md'
41+ ]).then(function () {
42+ st.fail('should not be successful');
43+ }, function (err) {
44+ st.equal(
45+ strip(err.stderr).split('\n').slice(0, 2).join('\n'),
46+ [
47+ 'definitions.md',
48+ ' 1:1 error Error: remark-validate-links cannot parse `repository` (`invalid:shortcode`)'
49+ ].join('\n'),
50+ 'should report an error'
51+ );
52+ });
53+ });
54+
55+ t.test('should throw on gist repositories', function (st) {
56+ st.plan(1);
57+
58+ execa(bin, [
59+ '--no-config',
60+ '--no-ignore',
61+ '--use',
62+ '../..=repository:"gist:wooorm/8504606"',
63+ 'definitions.md'
64+ ]).then(function () {
65+ st.fail('should not be successful');
66+ }, function (err) {
67+ st.equal(
68+ strip(err.stderr).split('\n').slice(0, 2).join('\n'),
69+ [
70+ 'definitions.md',
71+ ' 1:1 error Error: remark-validate-links does not support gist repositories'
72+ ].join('\n'),
73+ 'should report an error'
74+ );
75+ });
76+ });
77+
3278 t.test('should ignore unfound files', function (st) {
33− st.plan(2);
79+ st.plan(1);
3480
35− execa.stderr(bin, [
81+ execa(bin, [
3682 '--no-config',
3783 '--no-ignore',
3884 '--use',
39− '../../index',
85+ '../..',
4086 'definitions.md',
4187 'FOOOO'
42− ]).catch(function (err) {
43− st.equal(err.code, 1, 'should exit with `1`');
88+ ]).then(function () {
89+ st.fail('should not be successful');
90+ }, function (err) {
4491 st.equal(
4592 strip(err.stderr),
4693 [
@@ -53,7 +100,7 @@ test('remark-validate-links', function (t) {
53100 '2 messages (✖ 1 error, ⚠ 1 warning)',
54101 ''
55102 ].join('\n'),
56− 'should report'
103+ 'should report an error'
57104 );
58105 });
59106 });
@@ -61,85 +108,85 @@ test('remark-validate-links', function (t) {
61108 t.test('should work when not all files are given', function (st) {
62109 st.plan(1);
63110
64− execa.stderr(bin, [
111+ execa(bin, [
65112 '--no-config',
66113 '--no-ignore',
67114 '--use',
68− '../../index',
69− 'example.md'
70− ]).then(function (stderr) {
115+ '../..',
116+ 'github.md'
117+ ]).then(function (result) {
71118 st.equal(
72− strip(stderr),
119+ strip(result.stderr),
73120 [
74− 'example.md',
75− ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
76− ' 23:10-23:37 warning Link to unknown file: `examples/world.md` ' + source,
77− ' 25:10-25:35 warning Link to unknown file: `examples/world.md` ' + source,
78− ' 37:10-37:42 warning Link to unknown heading in `examples/example.md`: `world`' + source,
79− ' 39:10-39:40 warning Link to unknown heading in `examples/example.md`: `world`' + source,
80− ' 45:10-45:40 warning Link to unknown file: `examples/world.md` ' + source,
81− ' 45:10-45:40 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
82− ' 47:10-47:38 warning Link to unknown file: `examples/world.md` ' + source,
83− ' 47:10-47:38 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
121+ 'github.md',
122+ ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
123+ ' 23:10-23:37 warning Link to unknown file: `examples/world.md` ' + source,
124+ ' 25:10-25:35 warning Link to unknown file: `examples/world.md` ' + source,
125+ ' 37:10-37:41 warning Link to unknown heading in `examples/github.md`: `world`' + source,
126+ ' 39:10-39:39 warning Link to unknown heading in `examples/github.md`: `world`' + source,
127+ ' 45:10-45:40 warning Link to unknown file: `examples/world.md` ' + source,
128+ ' 45:10-45:40 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
129+ ' 47:10-47:38 warning Link to unknown file: `examples/world.md` ' + source,
130+ ' 47:10-47:38 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
84131 '',
85132 '⚠ 9 warnings'
86133 ].join('\n'),
87134 'should report'
88135 );
89− });
136+ }, st.error);
90137 });
91138
92139 t.test('should work when all files are given', function (st) {
93140 st.plan(1);
94141
95− execa.stderr(bin, [
142+ execa(bin, [
96143 '--no-config',
97144 '--no-ignore',
98145 '--use',
99− '../../index',
100− 'example.md',
101− 'examples/example.md'
102− ]).then(function (stderr) {
146+ '../..',
147+ 'github.md',
148+ 'examples/github.md'
149+ ]).then(function (result) {
103150 st.equal(
104− strip(stderr),
151+ strip(result.stderr),
105152 [
106− 'example.md',
107− ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
108− ' 23:10-23:37 warning Link to unknown file: `examples/world.md` ' + source,
109− ' 25:10-25:35 warning Link to unknown file: `examples/world.md` ' + source,
110− ' 37:10-37:42 warning Link to unknown heading in `examples/example.md`: `world`' + source,
111− ' 39:10-39:40 warning Link to unknown heading in `examples/example.md`: `world`' + source,
112− ' 45:10-45:40 warning Link to unknown file: `examples/world.md` ' + source,
113− ' 45:10-45:40 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
114− ' 47:10-47:38 warning Link to unknown file: `examples/world.md` ' + source,
115− ' 47:10-47:38 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
153+ 'examples/github.md',
154+ ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
155+ ' 19:10-19:29 warning Link to unknown file: `world.md` ' + source,
156+ ' 29:10-29:33 warning Link to unknown heading in `github.md`: `world` ' + source,
157+ ' 35:10-35:32 warning Link to unknown file: `world.md` ' + source,
158+ ' 35:10-35:32 warning Link to unknown heading in `world.md`: `hello` ' + source,
116159 '',
117− 'examples/example.md',
118− ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
119− ' 19:10-19:29 warning Link to unknown file: `world.md` ' + source,
120− ' 29:10-29:34 warning Link to unknown heading in `example.md`: `world` ' + source,
121− ' 35:10-35:32 warning Link to unknown file: `world.md` ' + source,
122− ' 35:10-35:32 warning Link to unknown heading in `world.md`: `hello` ' + source,
160+ 'github.md',
161+ ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
162+ ' 23:10-23:37 warning Link to unknown file: `examples/world.md` ' + source,
163+ ' 25:10-25:35 warning Link to unknown file: `examples/world.md` ' + source,
164+ ' 37:10-37:41 warning Link to unknown heading in `examples/github.md`: `world`' + source,
165+ ' 39:10-39:39 warning Link to unknown heading in `examples/github.md`: `world`' + source,
166+ ' 45:10-45:40 warning Link to unknown file: `examples/world.md` ' + source,
167+ ' 45:10-45:40 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
168+ ' 47:10-47:38 warning Link to unknown file: `examples/world.md` ' + source,
169+ ' 47:10-47:38 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
123170 '',
124171 '⚠ 14 warnings'
125172 ].join('\n'),
126173 'should report'
127174 );
128− });
175+ }, st.error);
129176 });
130177
131178 t.test('should work with definitions', function (st) {
132179 st.plan(1);
133180
134− execa.stderr(bin, [
181+ execa(bin, [
135182 '--no-config',
136183 '--no-ignore',
137184 '--use',
138− '../../index',
185+ '../..',
139186 'definitions.md'
140− ]).then(function (stderr) {
187+ ]).then(function (result) {
141188 st.equal(
142− strip(stderr),
189+ strip(result.stderr),
143190 [
144191 'definitions.md',
145192 ' 5:12-5:21 warning Link to unknown heading: `world`' + source,
@@ -148,62 +195,62 @@ test('remark-validate-links', function (t) {
148195 ].join('\n'),
149196 'should report'
150197 );
151− });
198+ }, st.error);
152199 });
153200
154201 t.test('should work on GitHub URLs when given a repo', function (st) {
155202 st.plan(1);
156203
157− execa.stderr(bin, [
204+ execa(bin, [
158205 '--no-config',
159206 '--no-ignore',
160207 '--use',
161− '../../index=repository:"wooorm/test"',
162− 'example.md',
163− 'examples/example.md'
164− ]).then(function (stderr) {
208+ '../..=repository:"wooorm/test"',
209+ 'github.md',
210+ 'examples/github.md'
211+ ]).then(function (result) {
165212 st.equal(
166− strip(stderr),
213+ strip(result.stderr),
167214 [
168− 'example.md',
169− ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
170− ' 19:34-19:102 warning Link to unknown file: `examples/world.md` ' + source,
171− ' 21:12-21:81 warning Link to unknown file: `examples/world.md` ' + source,
172− ' 23:10-23:37 warning Link to unknown file: `examples/world.md` ' + source,
173− ' 25:10-25:35 warning Link to unknown file: `examples/world.md` ' + source,
174− ' 37:10-37:42 warning Link to unknown heading in `examples/example.md`: `world`' + source,
175− ' 39:10-39:40 warning Link to unknown heading in `examples/example.md`: `world`' + source,
176− ' 41:10-41:83 warning Link to unknown heading in `examples/example.md`: `world`' + source,
177− ' 43:10-43:84 warning Link to unknown heading in `examples/example.md`: `world`' + source,
178− ' 45:10-45:40 warning Link to unknown file: `examples/world.md` ' + source,
179− ' 45:10-45:40 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
180− ' 47:10-47:38 warning Link to unknown file: `examples/world.md` ' + source,
181− ' 47:10-47:38 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
182− ' 49:10-49:81 warning Link to unknown file: `examples/world.md` ' + source,
183− ' 49:10-49:81 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
184− ' 51:10-51:82 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
185− ' 51:10-51:82 warning Link to unknown file: `examples/world.md` ' + source,
215+ 'examples/github.md',
216+ ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
217+ ' 15:34-15:93 warning Link to unknown file: `world.md` ' + source,
218+ ' 17:12-17:72 warning Link to unknown file: `world.md` ' + source,
219+ ' 19:10-19:29 warning Link to unknown file: `world.md` ' + source,
220+ ' 29:10-29:33 warning Link to unknown heading in `github.md`: `world` ' + source,
221+ ' 31:10-31:73 warning Link to unknown heading in `github.md`: `world` ' + source,
222+ ' 33:10-33:74 warning Link to unknown heading in `github.md`: `world` ' + source,
223+ ' 35:10-35:32 warning Link to unknown file: `world.md` ' + source,
224+ ' 35:10-35:32 warning Link to unknown heading in `world.md`: `hello` ' + source,
225+ ' 37:10-37:72 warning Link to unknown file: `world.md` ' + source,
226+ ' 37:10-37:72 warning Link to unknown heading in `world.md`: `hello` ' + source,
227+ ' 39:10-39:73 warning Link to unknown heading in `world.md`: `hello` ' + source,
228+ ' 39:10-39:73 warning Link to unknown file: `world.md` ' + source,
186229 '',
187− 'examples/example.md',
188− ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
189− ' 15:34-15:93 warning Link to unknown file: `world.md` ' + source,
190− ' 17:12-17:72 warning Link to unknown file: `world.md` ' + source,
191− ' 19:10-19:29 warning Link to unknown file: `world.md` ' + source,
192− ' 29:10-29:34 warning Link to unknown heading in `example.md`: `world` ' + source,
193− ' 31:10-31:74 warning Link to unknown heading in `example.md`: `world` ' + source,
194− ' 33:10-33:75 warning Link to unknown heading in `example.md`: `world` ' + source,
195− ' 35:10-35:32 warning Link to unknown file: `world.md` ' + source,
196− ' 35:10-35:32 warning Link to unknown heading in `world.md`: `hello` ' + source,
197− ' 37:10-37:72 warning Link to unknown file: `world.md` ' + source,
198− ' 37:10-37:72 warning Link to unknown heading in `world.md`: `hello` ' + source,
199− ' 39:10-39:73 warning Link to unknown heading in `world.md`: `hello` ' + source,
200− ' 39:10-39:73 warning Link to unknown file: `world.md` ' + source,
230+ 'github.md',
231+ ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
232+ ' 19:34-19:102 warning Link to unknown file: `examples/world.md` ' + source,
233+ ' 21:12-21:81 warning Link to unknown file: `examples/world.md` ' + source,
234+ ' 23:10-23:37 warning Link to unknown file: `examples/world.md` ' + source,
235+ ' 25:10-25:35 warning Link to unknown file: `examples/world.md` ' + source,
236+ ' 37:10-37:41 warning Link to unknown heading in `examples/github.md`: `world`' + source,
237+ ' 39:10-39:39 warning Link to unknown heading in `examples/github.md`: `world`' + source,
238+ ' 41:10-41:82 warning Link to unknown heading in `examples/github.md`: `world`' + source,
239+ ' 43:10-43:83 warning Link to unknown heading in `examples/github.md`: `world`' + source,
240+ ' 45:10-45:40 warning Link to unknown file: `examples/world.md` ' + source,
241+ ' 45:10-45:40 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
242+ ' 47:10-47:38 warning Link to unknown file: `examples/world.md` ' + source,
243+ ' 47:10-47:38 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
244+ ' 49:10-49:81 warning Link to unknown file: `examples/world.md` ' + source,
245+ ' 49:10-49:81 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
246+ ' 51:10-51:82 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
247+ ' 51:10-51:82 warning Link to unknown file: `examples/world.md` ' + source,
201248 '',
202249 '⚠ 30 warnings'
203250 ].join('\n'),
204251 'should report'
205252 );
206− });
253+ }, st.error);
207254 });
208255
209256 t.test('should work on GitHub URLs when with package.json', function (st) {
@@ -218,80 +265,161 @@ test('remark-validate-links', function (t) {
218265 fs.unlinkSync('./package.json');
219266 }
220267
221− execa.stderr(bin, [
268+ execa(bin, [
222269 '--no-config',
223270 '--no-ignore',
224271 '--use',
225272 '../..',
226− 'example.md',
227− 'examples/example.md'
228− ]).then(function (stderr) {
273+ 'github.md',
274+ 'examples/github.md'
275+ ]).then(function (result) {
229276 clean();
230277 st.equal(
231− strip(stderr),
278+ strip(result.stderr),
232279 [
233− 'example.md',
234− ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
235− ' 19:34-19:102 warning Link to unknown file: `examples/world.md` ' + source,
236− ' 21:12-21:81 warning Link to unknown file: `examples/world.md` ' + source,
237− ' 23:10-23:37 warning Link to unknown file: `examples/world.md` ' + source,
238− ' 25:10-25:35 warning Link to unknown file: `examples/world.md` ' + source,
239− ' 37:10-37:42 warning Link to unknown heading in `examples/example.md`: `world`' + source,
240− ' 39:10-39:40 warning Link to unknown heading in `examples/example.md`: `world`' + source,
241− ' 41:10-41:83 warning Link to unknown heading in `examples/example.md`: `world`' + source,
242− ' 43:10-43:84 warning Link to unknown heading in `examples/example.md`: `world`' + source,
243− ' 45:10-45:40 warning Link to unknown file: `examples/world.md` ' + source,
244− ' 45:10-45:40 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
245− ' 47:10-47:38 warning Link to unknown file: `examples/world.md` ' + source,
246− ' 47:10-47:38 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
247− ' 49:10-49:81 warning Link to unknown file: `examples/world.md` ' + source,
248− ' 49:10-49:81 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
249− ' 51:10-51:82 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
250− ' 51:10-51:82 warning Link to unknown file: `examples/world.md` ' + source,
280+ 'examples/github.md',
281+ ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
282+ ' 15:34-15:93 warning Link to unknown file: `world.md` ' + source,
283+ ' 17:12-17:72 warning Link to unknown file: `world.md` ' + source,
284+ ' 19:10-19:29 warning Link to unknown file: `world.md` ' + source,
285+ ' 29:10-29:33 warning Link to unknown heading in `github.md`: `world` ' + source,
286+ ' 31:10-31:73 warning Link to unknown heading in `github.md`: `world` ' + source,
287+ ' 33:10-33:74 warning Link to unknown heading in `github.md`: `world` ' + source,
288+ ' 35:10-35:32 warning Link to unknown file: `world.md` ' + source,
289+ ' 35:10-35:32 warning Link to unknown heading in `world.md`: `hello` ' + source,
290+ ' 37:10-37:72 warning Link to unknown file: `world.md` ' + source,
291+ ' 37:10-37:72 warning Link to unknown heading in `world.md`: `hello` ' + source,
292+ ' 39:10-39:73 warning Link to unknown heading in `world.md`: `hello` ' + source,
293+ ' 39:10-39:73 warning Link to unknown file: `world.md` ' + source,
251294 '',
252− 'examples/example.md',
253− ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
254− ' 15:34-15:93 warning Link to unknown file: `world.md` ' + source,
255− ' 17:12-17:72 warning Link to unknown file: `world.md` ' + source,
256− ' 19:10-19:29 warning Link to unknown file: `world.md` ' + source,
257− ' 29:10-29:34 warning Link to unknown heading in `example.md`: `world` ' + source,
258− ' 31:10-31:74 warning Link to unknown heading in `example.md`: `world` ' + source,
259− ' 33:10-33:75 warning Link to unknown heading in `example.md`: `world` ' + source,
260− ' 35:10-35:32 warning Link to unknown file: `world.md` ' + source,
261− ' 35:10-35:32 warning Link to unknown heading in `world.md`: `hello` ' + source,
262− ' 37:10-37:72 warning Link to unknown file: `world.md` ' + source,
263− ' 37:10-37:72 warning Link to unknown heading in `world.md`: `hello` ' + source,
264− ' 39:10-39:73 warning Link to unknown heading in `world.md`: `hello` ' + source,
265− ' 39:10-39:73 warning Link to unknown file: `world.md` ' + source,
295+ 'github.md',
296+ ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
297+ ' 19:34-19:102 warning Link to unknown file: `examples/world.md` ' + source,
298+ ' 21:12-21:81 warning Link to unknown file: `examples/world.md` ' + source,
299+ ' 23:10-23:37 warning Link to unknown file: `examples/world.md` ' + source,
300+ ' 25:10-25:35 warning Link to unknown file: `examples/world.md` ' + source,
301+ ' 37:10-37:41 warning Link to unknown heading in `examples/github.md`: `world`' + source,
302+ ' 39:10-39:39 warning Link to unknown heading in `examples/github.md`: `world`' + source,
303+ ' 41:10-41:82 warning Link to unknown heading in `examples/github.md`: `world`' + source,
304+ ' 43:10-43:83 warning Link to unknown heading in `examples/github.md`: `world`' + source,
305+ ' 45:10-45:40 warning Link to unknown file: `examples/world.md` ' + source,
306+ ' 45:10-45:40 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
307+ ' 47:10-47:38 warning Link to unknown file: `examples/world.md` ' + source,
308+ ' 47:10-47:38 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
309+ ' 49:10-49:81 warning Link to unknown file: `examples/world.md` ' + source,
310+ ' 49:10-49:81 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
311+ ' 51:10-51:82 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
312+ ' 51:10-51:82 warning Link to unknown file: `examples/world.md` ' + source,
266313 '',
267314 '⚠ 30 warnings'
268315 ].join('\n'),
269316 'should report'
270317 );
271− }, clean);
318+ }, function (err) {
319+ clean();
320+ st.error(err);
321+ });
322+ });
323+
324+ t.test('should support a GitLab shortcode', function (st) {
325+ st.plan(1);
326+
327+ execa(bin, [
328+ '--no-config',
329+ '--no-ignore',
330+ '--use',
331+ '../..=repository:"gitlab:wooorm/test"',
332+ 'gitlab.md'
333+ ]).then(function (result) {
334+ st.equal(
335+ strip(result.stderr),
336+ [
337+ 'gitlab.md',
338+ ' 5:37-5:51 warning Link to unknown heading: `world` ' + source,
339+ ' 19:34-19:102 warning Link to unknown file: `examples/world.md`. Did you mean `examples/gitlab.md`' + source,
340+ ' 21:12-21:81 warning Link to unknown file: `examples/world.md`. Did you mean `examples/gitlab.md`' + source,
341+ ' 23:10-23:37 warning Link to unknown file: `examples/world.md`. Did you mean `examples/gitlab.md`' + source,
342+ ' 25:10-25:35 warning Link to unknown file: `examples/world.md`. Did you mean `examples/gitlab.md`' + source,
343+ ' 37:10-37:41 warning Link to unknown heading in `examples/gitlab.md`: `world` ' + source,
344+ ' 39:10-39:39 warning Link to unknown heading in `examples/gitlab.md`: `world` ' + source,
345+ ' 41:10-41:82 warning Link to unknown heading in `examples/gitlab.md`: `world` ' + source,
346+ ' 43:10-43:83 warning Link to unknown heading in `examples/gitlab.md`: `world` ' + source,
347+ ' 45:10-45:40 warning Link to unknown file: `examples/world.md`. Did you mean `examples/gitlab.md`' + source,
348+ ' 45:10-45:40 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
349+ ' 47:10-47:38 warning Link to unknown file: `examples/world.md`. Did you mean `examples/gitlab.md`' + source,
350+ ' 47:10-47:38 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
351+ ' 49:10-49:81 warning Link to unknown file: `examples/world.md`. Did you mean `examples/gitlab.md`' + source,
352+ ' 49:10-49:81 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
353+ ' 51:10-51:82 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
354+ ' 51:10-51:82 warning Link to unknown file: `examples/world.md`. Did you mean `examples/gitlab.md`' + source,
355+ '',
356+ '⚠ 17 warnings'
357+ ].join('\n'),
358+ 'should report'
359+ );
360+ }, st.error);
361+ });
362+
363+ t.test('should support a Bitbucket shortcode', function (st) {
364+ st.plan(1);
365+
366+ execa(bin, [
367+ '--no-config',
368+ '--no-ignore',
369+ '--use',
370+ '../..=repository:"bitbucket:wooorm/test"',
371+ 'bitbucket.md'
372+ ]).then(function (result) {
373+ st.equal(
374+ strip(result.stderr),
375+ [
376+ 'bitbucket.md',
377+ ' 5:37-5:67 warning Link to unknown heading: `world` ' + source,
378+ ' 19:34-19:104 warning Link to unknown file: `examples/world.md` ' + source,
379+ ' 21:12-21:83 warning Link to unknown file: `examples/world.md` ' + source,
380+ ' 23:10-23:37 warning Link to unknown file: `examples/world.md` ' + source,
381+ ' 25:10-25:35 warning Link to unknown file: `examples/world.md` ' + source,
382+ ' 37:10-37:60 warning Link to unknown heading in `examples/bitbucket.md`: `world`' + source,
383+ ' 39:10-39:58 warning Link to unknown heading in `examples/bitbucket.md`: `world`' + source,
384+ ' 41:10-41:103 warning Link to unknown heading in `examples/bitbucket.md`: `world`' + source,
385+ ' 43:10-43:104 warning Link to unknown heading in `examples/bitbucket.md`: `world`' + source,
386+ ' 45:10-45:56 warning Link to unknown file: `examples/world.md` ' + source,
387+ ' 45:10-45:56 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
388+ ' 47:10-47:54 warning Link to unknown file: `examples/world.md` ' + source,
389+ ' 47:10-47:54 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
390+ ' 49:10-49:99 warning Link to unknown file: `examples/world.md` ' + source,
391+ ' 49:10-49:99 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
392+ ' 51:10-51:100 warning Link to unknown heading in `examples/world.md`: `hello` ' + source,
393+ ' 51:10-51:100 warning Link to unknown file: `examples/world.md` ' + source,
394+ '',
395+ '⚠ 17 warnings'
396+ ].join('\n'),
397+ 'should report'
398+ );
399+ }, st.error);
272400 });
273401
274402 t.test('should suggest similar links', function (st) {
275403 st.plan(1);
276404
277− execa.stderr(bin, [
405+ execa(bin, [
278406 '--no-config',
279407 '--no-ignore',
280408 '--use',
281− '../../index',
409+ '../..',
282410 'suggestions.md'
283− ]).then(function (stderr) {
411+ ]).then(function (result) {
284412 st.equal(
285− strip(stderr),
413+ strip(result.stderr),
286414 [
287415 'suggestions.md',
288− ' 3:22-3:37 warning Link to unknown heading: `helloo`. Did you mean `hello` ' + source,
289− ' 7:17-7:40 warning Link to unknown heading in `example.md`: `fiiiles`. Did you mean `files`' + source,
416+ ' 3:22-3:37 warning Link to unknown heading: `helloo`. Did you mean `hello` ' + source,
417+ ' 7:17-7:39 warning Link to unknown heading in `github.md`: `fiiiles`. Did you mean `files`' + source,
290418 '',
291419 '⚠ 2 warnings'
292420 ].join('\n'),
293421 'should report'
294422 );
295− });
423+ }, st.error);
296424 });
297425});