Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split up MD link tests #153048

Merged
merged 1 commit into from Jun 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -220,7 +220,7 @@ const linkPattern = new RegExp(
/**
* Matches `[text][ref]` or `[shorthand]`
*/
const referenceLinkPattern = /(^|[^\]\\])(?:(?:(\[((?:\\\]|[^\]])+)\]\[\s*?)([^\s\]]*?)\]|\[\s*?([^\s\]]*?)\])(?![\:\(]))/gm;
const referenceLinkPattern = /(^|[^\]\\])(?:(?:(\[((?:\\\]|[^\]])+)\]\[\s*?)([^\s\]]*?)\]|\[\s*?([^\s\\\]]*?)\])(?![\:\(]))/gm;

/**
* Matches `<http://example.com>`
Expand Down Expand Up @@ -352,12 +352,17 @@ export class MdLinkComputer {
let linkStart: vscode.Position;
let linkEnd: vscode.Position;
let reference = match[4];
if (reference) { // [text][ref]
if (reference === '') { // [ref][],
reference = match[3];
const offset = ((match.index ?? 0) + match[1].length) + 1;
linkStart = document.positionAt(offset);
linkEnd = document.positionAt(offset + reference.length);
} else if (reference) { // [text][ref]
const pre = match[2];
const offset = ((match.index ?? 0) + match[1].length) + pre.length;
linkStart = document.positionAt(offset);
linkEnd = document.positionAt(offset + reference.length);
} else if (match[5]) { // [ref][], [ref]
} else if (match[5]) { // [ref]
reference = match[5];
const offset = ((match.index ?? 0) + match[1].length) + 1;
linkStart = document.positionAt(offset);
Expand Down Expand Up @@ -526,6 +531,8 @@ export class MdVsCodeLinkProvider implements vscode.DocumentLinkProvider {
return documentLink;
}
case 'reference': {
// We only render reference links in the editor if they are actually defined.
// This matches how reference links are rendered by markdown-it.
const def = definitionSet.lookup(link.href.ref);
if (def) {
const documentLink = new vscode.DocumentLink(
Expand Down
Expand Up @@ -6,7 +6,7 @@
import * as assert from 'assert';
import 'mocha';
import * as vscode from 'vscode';
import { MdLinkProvider, MdVsCodeLinkProvider } from '../languageFeatures/documentLinks';
import { MdLink, MdLinkComputer, MdLinkProvider, MdVsCodeLinkProvider } from '../languageFeatures/documentLinks';
import { noopToken } from '../util/cancellation';
import { InMemoryDocument } from '../util/inMemoryDocument';
import { createNewMarkdownEngine } from './engine';
Expand All @@ -15,25 +15,23 @@ import { nulLogger } from './nulLogging';
import { assertRangeEqual, joinLines, workspacePath } from './util';


function getLinksForFile(fileContents: string) {
const doc = new InMemoryDocument(workspacePath('x.md'), fileContents);
const workspace = new InMemoryMdWorkspace([doc]);
suite('Markdown: MdLinkComputer', () => {

const engine = createNewMarkdownEngine();
const linkProvider = new MdLinkProvider(engine, workspace, nulLogger);
const provider = new MdVsCodeLinkProvider(linkProvider);
return provider.provideDocumentLinks(doc, noopToken);
}
function getLinksForFile(fileContents: string): Promise<MdLink[]> {
const doc = new InMemoryDocument(workspacePath('x.md'), fileContents);
const engine = createNewMarkdownEngine();
const linkProvider = new MdLinkComputer(engine);
return linkProvider.getAllLinks(doc, noopToken);
}

function assertLinksEqual(actualLinks: readonly vscode.DocumentLink[], expectedRanges: readonly vscode.Range[]) {
assert.strictEqual(actualLinks.length, expectedRanges.length);
function assertLinksEqual(actualLinks: readonly MdLink[], expectedRanges: readonly vscode.Range[]) {
assert.strictEqual(actualLinks.length, expectedRanges.length);

for (let i = 0; i < actualLinks.length; ++i) {
assertRangeEqual(actualLinks[i].range, expectedRanges[i], `Range ${i} to be equal`);
for (let i = 0; i < actualLinks.length; ++i) {
assertRangeEqual(actualLinks[i].source.hrefRange, expectedRanges[i], `Range ${i} to be equal`);
}
}
}

suite('Markdown: DocumentLinkProvider', () => {
test('Should not return anything for empty document', async () => {
const links = await getLinksForFile('');
assertLinksEqual(links, []);
Expand Down Expand Up @@ -182,30 +180,32 @@ suite('Markdown: DocumentLinkProvider', () => {
});

test('Should find reference link shorthand (#141285)', async () => {
{
const links = await getLinksForFile(joinLines(
'[ref]',
'[ref]: https://example.com',
));
assertLinksEqual(links, [
new vscode.Range(0, 1, 0, 4),
new vscode.Range(1, 7, 1, 26),
]);
}
{
const links = await getLinksForFile(joinLines(
'[Does Not Work]',
'[def]: https://example.com',
));
assertLinksEqual(links, [
new vscode.Range(1, 7, 1, 26),
]);
}
const links = await getLinksForFile(joinLines(
'[ref]',
'[ref]: https://example.com',
));
assertLinksEqual(links, [
new vscode.Range(0, 1, 0, 4),
new vscode.Range(1, 7, 1, 26),
]);
});

test('Should not include reference link shorthand when source does not exist (#141285)', async () => {
const links = await getLinksForFile('[Works]');
assertLinksEqual(links, []);
test('Should find reference link shorthand using empty closing brackets (#141285)', async () => {
const links = await getLinksForFile(joinLines(
'[ref][]',
));
assertLinksEqual(links, [
new vscode.Range(0, 1, 0, 4),
]);
});

test.skip('Should find reference link shorthand for link with space in label (#141285)', async () => {
const links = await getLinksForFile(joinLines(
'[ref with space]',
));
assertLinksEqual(links, [
new vscode.Range(0, 7, 0, 26),
]);
});

test('Should not include reference links with escaped leading brackets', async () => {
Expand Down Expand Up @@ -462,3 +462,46 @@ suite('Markdown: DocumentLinkProvider', () => {
]);
});
});


suite('Markdown: VS Code DocumentLinkProvider', () => {

function getLinksForFile(fileContents: string) {
const doc = new InMemoryDocument(workspacePath('x.md'), fileContents);
const workspace = new InMemoryMdWorkspace([doc]);

const engine = createNewMarkdownEngine();
const linkProvider = new MdLinkProvider(engine, workspace, nulLogger);
const provider = new MdVsCodeLinkProvider(linkProvider);
return provider.provideDocumentLinks(doc, noopToken);
}

function assertLinksEqual(actualLinks: readonly vscode.DocumentLink[], expectedRanges: readonly vscode.Range[]) {
assert.strictEqual(actualLinks.length, expectedRanges.length);

for (let i = 0; i < actualLinks.length; ++i) {
assertRangeEqual(actualLinks[i].range, expectedRanges[i], `Range ${i} to be equal`);
}
}

test('Should include defined reference links (#141285)', async () => {
const links = await getLinksForFile(joinLines(
'[ref]',
'[ref][]',
'[ref][ref]',
'',
'[ref]: http://example.com'
));
assertLinksEqual(links, [
new vscode.Range(0, 1, 0, 4),
new vscode.Range(1, 1, 1, 4),
new vscode.Range(2, 6, 2, 9),
new vscode.Range(4, 7, 4, 25),
]);
});

test('Should not include reference link shorthand when definition does not exist (#141285)', async () => {
const links = await getLinksForFile('[ref]');
assertLinksEqual(links, []);
});
});