From 887ffe9b01b55ac94aef6d19e50755650ea7f61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Sun, 24 May 2020 14:38:40 +0200 Subject: [PATCH 01/13] Add some basic tests --- .vscode/launch.json | 2 +- src/test/suite/ast.json | 235 +++++++++++++++++++++++++++++++ src/test/suite/extension.test.ts | 37 +++-- tsconfig.json | 1 + 4 files changed, 266 insertions(+), 9 deletions(-) create mode 100644 src/test/suite/ast.json diff --git a/.vscode/launch.json b/.vscode/launch.json index 7752da2..ad9c5d3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -24,7 +24,7 @@ "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" ], "outFiles": ["${workspaceFolder}/out/test/**/*.js"], - "preLaunchTask": "${defaultBuildTask}" + "preLaunchTask": "npm: watch" } ] } diff --git a/src/test/suite/ast.json b/src/test/suite/ast.json new file mode 100644 index 0000000..0fa7da6 --- /dev/null +++ b/src/test/suite/ast.json @@ -0,0 +1,235 @@ +{ + "type": "root", + "children": [ + { + "type": "heading", + "depth": 1, + "children": [ + { + "type": "text", + "value": "Links", + "position": { + "start": { "line": 1, "column": 3, "offset": 2 }, + "end": { "line": 1, "column": 8, "offset": 7 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 1, "column": 1, "offset": 0 }, + "end": { "line": 1, "column": 8, "offset": 7 }, + "indent": [] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": null, + "url": "another.md", + "children": [ + { + "type": "text", + "value": "Another", + "position": { + "start": { "line": 3, "column": 2, "offset": 10 }, + "end": { "line": 3, "column": 9, "offset": 17 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 3, "column": 1, "offset": 9 }, + "end": { "line": 3, "column": 22, "offset": 30 }, + "indent": [] + } + }, + { + "type": "text", + "value": "\n", + "position": { + "start": { "line": 3, "column": 22, "offset": 30 }, + "end": { "line": 4, "column": 1, "offset": 31 }, + "indent": [1] + } + }, + { + "type": "link", + "title": null, + "url": "other.md", + "children": [ + { + "type": "text", + "value": "Other", + "position": { + "start": { "line": 4, "column": 2, "offset": 32 }, + "end": { "line": 4, "column": 7, "offset": 37 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 4, "column": 1, "offset": 31 }, + "end": { "line": 4, "column": 18, "offset": 48 }, + "indent": [] + } + }, + { + "type": "text", + "value": "\n", + "position": { + "start": { "line": 4, "column": 18, "offset": 48 }, + "end": { "line": 5, "column": 1, "offset": 49 }, + "indent": [1] + } + }, + { + "type": "link", + "title": null, + "url": "nested.md", + "children": [ + { + "type": "text", + "value": "Nested", + "position": { + "start": { "line": 5, "column": 2, "offset": 50 }, + "end": { "line": 5, "column": 8, "offset": 56 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 5, "column": 1, "offset": 49 }, + "end": { "line": 5, "column": 20, "offset": 68 }, + "indent": [] + } + }, + { + "type": "text", + "value": "\n", + "position": { + "start": { "line": 5, "column": 20, "offset": 68 }, + "end": { "line": 6, "column": 1, "offset": 69 }, + "indent": [1] + } + }, + { + "type": "link", + "title": null, + "url": "error.md", + "children": [ + { + "type": "text", + "value": "Error", + "position": { + "start": { "line": 6, "column": 2, "offset": 70 }, + "end": { "line": 6, "column": 7, "offset": 75 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 6, "column": 1, "offset": 69 }, + "end": { "line": 6, "column": 18, "offset": 86 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 3, "column": 1, "offset": 9 }, + "end": { "line": 6, "column": 18, "offset": 86 }, + "indent": [1, 1, 1] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "linkReference", + "identifier": "more", + "label": "More", + "referenceType": "shortcut", + "children": [ + { + "type": "text", + "value": "More", + "position": { + "start": { "line": 8, "column": 2, "offset": 89 }, + "end": { "line": 8, "column": 6, "offset": 93 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 8, "column": 1, "offset": 88 }, + "end": { "line": 8, "column": 7, "offset": 94 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 8, "column": 1, "offset": 88 }, + "end": { "line": 8, "column": 7, "offset": 94 }, + "indent": [] + } + }, + { + "type": "definition", + "identifier": "more", + "label": "more", + "title": null, + "url": "more.md", + "position": { + "start": { "line": 10, "column": 1, "offset": 96 }, + "end": { "line": 10, "column": 16, "offset": 111 }, + "indent": [] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "linkReference", + "identifier": "nowhere", + "label": "nowhere", + "referenceType": "shortcut", + "children": [ + { + "type": "text", + "value": "nowhere", + "position": { + "start": { "line": 12, "column": 2, "offset": 114 }, + "end": { "line": 12, "column": 9, "offset": 121 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 12, "column": 1, "offset": 113 }, + "end": { "line": 12, "column": 10, "offset": 122 }, + "indent": [] + } + }, + { + "type": "text", + "value": ": <>", + "position": { + "start": { "line": 12, "column": 10, "offset": 122 }, + "end": { "line": 12, "column": 14, "offset": 126 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 12, "column": 1, "offset": 113 }, + "end": { "line": 12, "column": 14, "offset": 126 }, + "indent": [] + } + } + ], + "position": { + "start": { "line": 1, "column": 1, "offset": 0 }, + "end": { "line": 13, "column": 1, "offset": 127 } + } +} diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index 08a6f78..ce8bce8 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -1,15 +1,36 @@ -import * as assert from 'assert'; +import * as assert from "assert"; // You can import and use all API from the 'vscode' module // as well as import your extension to test it -import * as vscode from 'vscode'; +import * as vscode from "vscode"; +import * as ast from "./ast.json"; +import { findLinks, findTitle, id } from "../../utils"; // import * as myExtension from '../../extension'; -suite('Extension Test Suite', () => { - vscode.window.showInformationMessage('Start all tests.'); +suite("Tests", () => { + vscode.window.showInformationMessage("Start all tests."); - test('Sample test', () => { - assert.equal(-1, [1, 2, 3].indexOf(5)); - assert.equal(-1, [1, 2, 3].indexOf(0)); - }); + test("findLinks works", () => { + const links = findLinks(ast); + const expected = [ + "another.md", + "other.md", + "nested.md", + "error.md", + "more.md", + ]; + + assert.deepStrictEqual(links, expected); + }); + + test("findTitle works", () => { + assert.equal(findTitle(ast), "Links"); + }); + + test("id works", () => { + assert.equal( + id("/Users/example/Desktop/notes/1.md"), + "daea8e534ce10d7a2e16635f182c29b8" + ); + }); }); diff --git a/tsconfig.json b/tsconfig.json index f113fdc..ea4a595 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,7 @@ "sourceMap": true, "rootDir": "src", "noImplicitAny": false, + "resolveJsonModule": true, "strict": true /* enable all strict type-checking options */ /* Additional Checks */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ From cbaafb738bc04075bdc3fdf9700c71f5ddb4aba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Sun, 24 May 2020 14:57:38 +0200 Subject: [PATCH 02/13] Add basic unit tests --- src/test/suite/extension.test.ts | 70 ++++++++++++++++++++++++++++++-- src/utils.ts | 8 ++-- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index ce8bce8..5e45c39 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -4,12 +4,31 @@ import * as assert from "assert"; // as well as import your extension to test it import * as vscode from "vscode"; import * as ast from "./ast.json"; -import { findLinks, findTitle, id } from "../../utils"; -// import * as myExtension from '../../extension'; +import { + findLinks, + findTitle, + id, + getDot, + exists, + filterNonExistingEdges, +} from "../../utils"; suite("Tests", () => { vscode.window.showInformationMessage("Start all tests."); + const getGraph = () => ({ + nodes: [ + { id: "1", label: "First", path: "/Users/test/Desktop/notes/1.md" }, + { id: "2", label: "Second", path: "/Users/test/Desktop/notes/2.md" }, + { id: "3", label: "Third", path: "/Users/test/Desktop/notes/3.md" }, + ], + edges: [ + { source: "1", target: "2" }, + { source: "1", target: "3" }, + { source: "3", target: "2" }, + ], + }); + test("findLinks works", () => { const links = findLinks(ast); const expected = [ @@ -29,8 +48,51 @@ suite("Tests", () => { test("id works", () => { assert.equal( - id("/Users/example/Desktop/notes/1.md"), - "daea8e534ce10d7a2e16635f182c29b8" + id("/Users/test/Desktop/notes/1.md"), + "a2c0c4c2697d0cde5f0e3888bf1d7630" ); }); + + test("getColumnSetting works", () => { + // TODO: mock vscode.workspace.getConfiguration + }); + + test("getFileIdRegexp", () => { + // TODO: mock vscode.workspace.getConfiguration + }); + + test("getDot works", () => { + const graph = getGraph(); + const dot = getDot(graph); + const expected = + 'digraph g {\n 1 [label="First"];\n 2 [label="Second"];\n 3 [label="Third"];\n 1 -> 2\n 1 -> 3\n 3 -> 2\n}'; + + assert.equal(dot, expected); + }); + + test("exists works", () => { + const graph = getGraph(); + assert.equal(exists(graph, "1"), true); + assert.equal(exists(graph, "First"), false); + }); + + test("filterNonExistingEdges", () => { + const graph = getGraph(); + graph.edges.push({ source: "2", target: "https://wikipedia.org" }); + graph.edges.push({ source: "2", target: "4" }); + + assert.equal(graph.edges.length, 5); + filterNonExistingEdges(graph); + assert.equal(graph.edges.length, 3); + }); + + test("idResolver works", () => {}); + + test("parseFile works", () => {}); + + test("findFileId works", () => {}); + + test("learnFileId works", () => {}); + + test("parseDirectory works", () => {}); }); diff --git a/src/utils.ts b/src/utils.ts index 7e0a246..4c21ef4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -85,11 +85,9 @@ export const getFileIdRegexp = () => { export const FILE_ID_REGEXP = getFileIdRegexp(); export const getDot = (graph: Graph) => `digraph g { - ${graph.nodes - .map((node) => ` ${node.id} [label="${node.label}"];`) - .join("\n")} - ${graph.edges.map((edge) => ` ${edge.source} -> ${edge.target}`).join("\n")} - }`; +${graph.nodes.map((node) => ` ${node.id} [label="${node.label}"];`).join("\n")} +${graph.edges.map((edge) => ` ${edge.source} -> ${edge.target}`).join("\n")} +}`; export const exists = (graph: Graph, id: string) => !!graph.nodes.find((node) => node.id === id); From 59edbd47f89c920d36e6bbf1193a4328bc0a9661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Sun, 24 May 2020 16:48:22 +0200 Subject: [PATCH 03/13] Add more tests --- src/extension.ts | 6 +++--- src/parsing.ts | 7 +++++- src/test/suite/extension.test.ts | 37 ++++++++++++++++++++++++++++---- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 42fa96f..27ca4d4 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,7 +1,7 @@ import * as vscode from "vscode"; import { TextDecoder } from "util"; import * as path from "path"; -import { parseFile, parseDirectory, learnFileId } from "./parsing"; +import { parseDirectory, learnFileId, processFile } from "./parsing"; import { filterNonExistingEdges, getColumnSetting } from "./utils"; import { Graph } from "./types"; @@ -30,7 +30,7 @@ const watch = ( // Watch file changes in case user adds a link. watcher.onDidChange(async (event) => { - await parseFile(graph, event.path); + processFile(graph, event.path); filterNonExistingEdges(graph); sendGraph(); }); @@ -129,7 +129,7 @@ export function activate(context: vscode.ExtensionContext) { }; await parseDirectory(graph, vscode.workspace.rootPath, learnFileId); - await parseDirectory(graph, vscode.workspace.rootPath, parseFile); + await parseDirectory(graph, vscode.workspace.rootPath, processFile); filterNonExistingEdges(graph); const d3Uri = panel.webview.asWebviewUri( diff --git a/src/parsing.ts b/src/parsing.ts index 57d2eaa..0e55f74 100644 --- a/src/parsing.ts +++ b/src/parsing.ts @@ -24,9 +24,14 @@ const parser = unified() .use(wikiLinkPlugin, { pageResolver: idResolver }) .use(frontmatter); -export const parseFile = async (graph: Graph, filePath: string) => { +export const processFile = async (graph: Graph, filePath: string) => { const buffer = await vscode.workspace.fs.readFile(vscode.Uri.file(filePath)); const content = new TextDecoder("utf-8").decode(buffer); + + return parseFile(graph, filePath, content); +}; + +export const parseFile = (graph: Graph, filePath: string, content: string) => { const ast: MarkdownNode = parser.parse(content); let title: string | null = findTitle(ast); diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index 5e45c39..29f0450 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -12,6 +12,8 @@ import { exists, filterNonExistingEdges, } from "../../utils"; +import { Graph } from "../../types"; +import { parseFile } from "../../parsing"; suite("Tests", () => { vscode.window.showInformationMessage("Start all tests."); @@ -88,11 +90,38 @@ suite("Tests", () => { test("idResolver works", () => {}); - test("parseFile works", () => {}); + test("parseFile works", () => { + const graph: Graph = { + nodes: [], + edges: [], + }; + + const path = "/Users/test/Desktop/notes"; + const firstFileName = "1.md"; + const firstFilePath = `${path}/${firstFileName}`; + const secondFileName = "2.md"; + const title = "Test"; + const content = `# ${title}\n\n[Link](${secondFileName})\n`; + + parseFile(graph, firstFilePath, content); + + assert.deepStrictEqual(graph.nodes, [ + { id: id(firstFilePath), label: title, path: firstFilePath }, + ]); + assert.deepStrictEqual(graph.edges, [ + { source: id(firstFilePath), target: id(`${path}/${secondFileName}`) }, + ]); + }); - test("findFileId works", () => {}); + test("findFileId works", () => { + // TODO: mocks. + }); - test("learnFileId works", () => {}); + test("learnFileId works", () => { + // TODO: mocks. + }); - test("parseDirectory works", () => {}); + test("parseDirectory works", () => { + // TODO: mocks. + }); }); From 3688d16e9ce3c4871e2e803505f85cbcc456e46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Sun, 24 May 2020 17:17:22 +0200 Subject: [PATCH 04/13] Add doc comments --- src/parsing.ts | 36 ++++++++++++++++++++++++++++++++++-- src/types.ts | 22 ++++++++++++++++++++++ src/utils.ts | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/parsing.ts b/src/parsing.ts index 0e55f74..6eb1839 100644 --- a/src/parsing.ts +++ b/src/parsing.ts @@ -6,10 +6,14 @@ import * as wikiLinkPlugin from "remark-wiki-link"; import * as frontmatter from "remark-frontmatter"; import { MarkdownNode, Graph } from "./types"; import { TextDecoder } from "util"; -import { findTitle, findLinks, id, FILE_ID_REGEXP } from "./utils"; +import { findTitle, findLinks, id, getFileIdRegexp } from "./utils"; let idToPath: Record = {}; +/** + * ?? + * @param id ?? + */ export const idResolver = (id: string) => { const filePath = idToPath[id]; if (filePath === undefined) { @@ -24,6 +28,11 @@ const parser = unified() .use(wikiLinkPlugin, { pageResolver: idResolver }) .use(frontmatter); +/** + * Wrapper for `parseFile` that reads a file. Uses `vscode.workspace.fs`. + * @param graph object that will be altered. + * @param filePath absolute path to the file. Used for reading the file. + */ export const processFile = async (graph: Graph, filePath: string) => { const buffer = await vscode.workspace.fs.readFile(vscode.Uri.file(filePath)); const content = new TextDecoder("utf-8").decode(buffer); @@ -31,6 +40,13 @@ export const processFile = async (graph: Graph, filePath: string) => { return parseFile(graph, filePath, content); }; +/** + * Alters given graph, adding a node and some edges if file is properly + * structured. + * @param graph object that will be altered. + * @param filePath absolute path to the file. Isn't used for reading the file. + * @param content content of the file as utf-8 string. + */ export const parseFile = (graph: Graph, filePath: string, content: string) => { const ast: MarkdownNode = parser.parse(content); @@ -68,14 +84,23 @@ export const parseFile = (graph: Graph, filePath: string, content: string) => { } }; +/** + * For given file path, returns its ID or null. Uses `vscode.workspace.fs`. + * @param filePath absolute path of the file. + */ export const findFileId = async (filePath: string): Promise => { const buffer = await vscode.workspace.fs.readFile(vscode.Uri.file(filePath)); const content = new TextDecoder("utf-8").decode(buffer); - const match = content.match(FILE_ID_REGEXP); + const match = content.match(getFileIdRegexp()); return match ? match[1] : null; }; +/** + * Populates `idToPath` with ID from the file if one is found there. + * @param _graph unused. + * @param filePath absolute path of the file. + */ export const learnFileId = async (_graph: Graph, filePath: string) => { const id = await findFileId(filePath); if (id !== null) { @@ -83,6 +108,13 @@ export const learnFileId = async (_graph: Graph, filePath: string) => { } }; +/** + * Recursively reads content of the given directory and calls specified + * callback on each file (not a symlink) with `*.md` extensions. + * @param graph object to be altered. + * @param directory path of the directory. + * @param fileCallback + */ export const parseDirectory = async ( graph: Graph, directory: string, diff --git a/src/types.ts b/src/types.ts index 6da48df..52d1666 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,19 +1,41 @@ +/** + * Defines directed edge between two nodes. + * @param source ID of the starting node of the edge. + * @param target ID of ending node of the edge. + */ export type Edge = { source: string; target: string; }; +/** + * @param id ID of the node. Should be unique. Used for identifying the nodes + * and matching them with edges. + * @param path absolute path of the file. Used for opening files. + * @param label label used while displaying the node. + */ export type Node = { id: string; path: string; label: string; }; +/** + * Graph representation using list of nodes and list of edges. + */ export type Graph = { nodes: Node[]; edges: Edge[]; }; +/** + * Based on the output of `remark-parse` with `remark-wiki-link` and + * `remark-frontmatter` plugins. + * To make it simpler, most fields are made + * optional. + * The reason it is used instead of the official type is because it + * was too general. + */ export type MarkdownNode = { type: string; children?: MarkdownNode[]; diff --git a/src/utils.ts b/src/utils.ts index 4c21ef4..ad3f2ab 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,6 +2,13 @@ import * as vscode from "vscode"; import * as md5 from "md5"; import { MarkdownNode, Graph } from "./types"; +/** + * Finds links to other Markdown files in the given file. Handles: + * - simple local links `[Link](1.md)`. + * - references `[Reference] [reference]: 1.md`. + * - wiki-style links `[[Link]]`. + * @param ast abstract syntax tree of a Markdown file. + */ export const findLinks = (ast: MarkdownNode): string[] => { if (ast.type === "link" || ast.type === "definition") { return [ast.url!]; @@ -23,6 +30,11 @@ export const findLinks = (ast: MarkdownNode): string[] => { return links; }; +/** + * Finds title of the given file which is the first heading of depth one + * (# Like this) encountered. If there is no such thing, returns null. + * @param ast abstract syntax tree of a Markdown file. + */ export const findTitle = (ast: MarkdownNode): string | null => { if (!ast.children) { return null; @@ -38,9 +50,15 @@ export const findTitle = (ast: MarkdownNode): string | null => { return child.children[0].value!; } } + return null; }; +/** + * Translates given path to ID. IDs are unique as long as paths are (which + * should remain true). + * @param path absolute path of the file. + */ export const id = (path: string): string => { return md5(path); @@ -50,6 +68,11 @@ export const id = (path: string): string => { // return fileName.split(".")[0]; }; +/** + * Returns value of configuration for the given key. + * @param key configuration key. For example in `markdown-links.showColumn`, + * configuration key is `showColumn`. + */ export const getConfiguration = (key: string) => vscode.workspace.getConfiguration("markdown-links")[key]; @@ -67,31 +90,51 @@ const settingToValue: { [key: string]: vscode.ViewColumn | undefined } = { nine: 9, }; +/** + * For given configuration key, returns mapping to the vscode.ViewColumn value. + * @param key configuration key. + */ export const getColumnSetting = (key: string) => { const column = getConfiguration(key); return settingToValue[column] || vscode.ViewColumn.One; }; +/** + * Returns regular expression for finding file IDs in a file. + */ export const getFileIdRegexp = () => { const DEFAULT_VALUE = "\\d{14}"; const userValue = getConfiguration("fileIdRegexp") || DEFAULT_VALUE; - // Ensure the id is not preceeded by [[, which would make it a part of + // TODO: make `[[` also configurable. + // Ensure the id is not preceeded by `[[`, which would make it a part of // wiki-style link, and put the user-supplied regex in a capturing group to // retrieve matching string. return new RegExp(`(? `digraph g { ${graph.nodes.map((node) => ` ${node.id} [label="${node.label}"];`).join("\n")} ${graph.edges.map((edge) => ` ${edge.source} -> ${edge.target}`).join("\n")} }`; +/** + * Returns whether file with given ID is present in the given graph. + * @param graph graph to check. + * @param id ID of the file to look for. + */ export const exists = (graph: Graph, id: string) => !!graph.nodes.find((node) => node.id === id); +/** + * Filters `edges` array to leave only those that have node in `nodes` for + * both `source` and `target` of given edge. + * @param graph object to alter. + */ export const filterNonExistingEdges = (graph: Graph) => { graph.edges = graph.edges.filter( (edge) => exists(graph, edge.source) && exists(graph, edge.target) From b357072b19a8ea5a237a2b00e71235d9e2aa0a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Sun, 24 May 2020 22:22:38 +0200 Subject: [PATCH 05/13] Switch from TDD to BDD runner in mocha --- package.json | 2 ++ src/test/suite/extension.test.ts | 47 ++++++++++++++++-------- src/test/suite/index.ts | 62 ++++++++++++++++---------------- yarn.lock | 10 ++++++ 4 files changed, 75 insertions(+), 46 deletions(-) diff --git a/package.json b/package.json index 1280f91..f8816cb 100644 --- a/package.json +++ b/package.json @@ -68,12 +68,14 @@ "@types/glob": "^7.1.1", "@types/mocha": "^7.0.2", "@types/node": "^13.11.0", + "@types/simple-mock": "^0.8.1", "@types/vscode": "^1.45.0", "@typescript-eslint/eslint-plugin": "^2.33.0", "@typescript-eslint/parser": "^2.33.0", "eslint": "^6.8.0", "glob": "^7.1.6", "mocha": "^7.1.2", + "simple-mock": "^0.8.0", "ts-loader": "^7.0.4", "typescript": "^3.8.3", "vscode-test": "^1.3.0", diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index 29f0450..ee9aaa0 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -1,8 +1,13 @@ import * as assert from "assert"; +import * as simple from "simple-mock"; // You can import and use all API from the 'vscode' module // as well as import your extension to test it import * as vscode from "vscode"; + +import * as unified from "unified"; +import * as markdown from "remark-parse"; + import * as ast from "./ast.json"; import { findLinks, @@ -15,7 +20,7 @@ import { import { Graph } from "../../types"; import { parseFile } from "../../parsing"; -suite("Tests", () => { +describe("Tests", () => { vscode.window.showInformationMessage("Start all tests."); const getGraph = () => ({ @@ -31,7 +36,9 @@ suite("Tests", () => { ], }); - test("findLinks works", () => { + const parser = unified().use(markdown); + + it("findLinks works", () => { const links = findLinks(ast); const expected = [ "another.md", @@ -44,26 +51,36 @@ suite("Tests", () => { assert.deepStrictEqual(links, expected); }); - test("findTitle works", () => { - assert.equal(findTitle(ast), "Links"); + describe("findTitle", () => { + it("works", () => { + assert.equal(findTitle(ast), "Links"); + }); + + it("selects correct title out of many", () => { + assert.equal(findTitle(parser.parse("# First\n\n# Second")), "First"); + }); + + it("does not find title if none exists", () => { + assert.equal(findTitle(parser.parse("No title\n\nAnywhere here.")), null); + }); }); - test("id works", () => { + it("id works", () => { assert.equal( id("/Users/test/Desktop/notes/1.md"), "a2c0c4c2697d0cde5f0e3888bf1d7630" ); }); - test("getColumnSetting works", () => { + xit("getColumnSetting works", () => { // TODO: mock vscode.workspace.getConfiguration }); - test("getFileIdRegexp", () => { + xit("getFileIdRegexp", () => { // TODO: mock vscode.workspace.getConfiguration }); - test("getDot works", () => { + it("getDot works", () => { const graph = getGraph(); const dot = getDot(graph); const expected = @@ -72,13 +89,13 @@ suite("Tests", () => { assert.equal(dot, expected); }); - test("exists works", () => { + it("exists works", () => { const graph = getGraph(); assert.equal(exists(graph, "1"), true); assert.equal(exists(graph, "First"), false); }); - test("filterNonExistingEdges", () => { + it("filterNonExistingEdges", () => { const graph = getGraph(); graph.edges.push({ source: "2", target: "https://wikipedia.org" }); graph.edges.push({ source: "2", target: "4" }); @@ -88,9 +105,9 @@ suite("Tests", () => { assert.equal(graph.edges.length, 3); }); - test("idResolver works", () => {}); + xit("idResolver works", () => {}); - test("parseFile works", () => { + it("parseFile works", () => { const graph: Graph = { nodes: [], edges: [], @@ -113,15 +130,15 @@ suite("Tests", () => { ]); }); - test("findFileId works", () => { + xit("findFileId works", () => { // TODO: mocks. }); - test("learnFileId works", () => { + xit("learnFileId works", () => { // TODO: mocks. }); - test("parseDirectory works", () => { + xit("parseDirectory works", () => { // TODO: mocks. }); }); diff --git a/src/test/suite/index.ts b/src/test/suite/index.ts index 7029e38..d3cd395 100644 --- a/src/test/suite/index.ts +++ b/src/test/suite/index.ts @@ -1,38 +1,38 @@ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +import * as path from "path"; +import * as Mocha from "mocha"; +import * as glob from "glob"; export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'tdd', - color: true - }); + // Create the mocha test + const mocha = new Mocha({ + ui: "bdd", + color: true, + }); - const testsRoot = path.resolve(__dirname, '..'); + const testsRoot = path.resolve(__dirname, ".."); - return new Promise((c, e) => { - glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } + return new Promise((c, e) => { + glob("**/**.test.js", { cwd: testsRoot }, (err, files) => { + if (err) { + return e(err); + } - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); + // Add files to the test suite + files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))); - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); + try { + // Run the mocha test + mocha.run((failures) => { + if (failures > 0) { + e(new Error(`${failures} tests failed.`)); + } else { + c(); + } + }); + } catch (err) { + console.error(err); + e(err); + } + }); + }); } diff --git a/yarn.lock b/yarn.lock index 4c7e202..52eefaf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -81,6 +81,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.5.tgz#96ec3b0afafd64a4ccea9107b75bf8489f0e5765" integrity sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g== +"@types/simple-mock@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@types/simple-mock/-/simple-mock-0.8.1.tgz#bcb7d4bdd1d7c142008af3c32603c7088ad9af33" + integrity sha512-Mn5n1v3S5yhhegOSUpXl2WTujBJfM1Oa0YTb9PpaYUq6Iqj6yOxy8h8lwMtNidKs3pAByhp1uIK0QP+OZCsotQ== + "@types/unist@^2.0.0", "@types/unist@^2.0.2": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" @@ -3302,6 +3307,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +simple-mock@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/simple-mock/-/simple-mock-0.8.0.tgz#49c9a223fa6eea8e2c4fd6948fe8300cd8a594f3" + integrity sha1-ScmiI/pu6o4sT9aUj+gwDNillPM= + slice-ansi@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" From 949ae51937321b0dab7732cf0fe72f873508a4b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Mon, 25 May 2020 00:46:24 +0200 Subject: [PATCH 06/13] Add sinon and mock parts of the vscode API --- package.json | 6 +- src/test/suite/extension.test.ts | 141 ++++++++++++++++++++++++------- yarn.lock | 110 ++++++++++++++++++++++-- 3 files changed, 214 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index f8816cb..b932b57 100644 --- a/package.json +++ b/package.json @@ -66,16 +66,17 @@ }, "devDependencies": { "@types/glob": "^7.1.1", + "@types/md5": "^2.2.0", "@types/mocha": "^7.0.2", "@types/node": "^13.11.0", - "@types/simple-mock": "^0.8.1", + "@types/sinon": "^9.0.4", "@types/vscode": "^1.45.0", "@typescript-eslint/eslint-plugin": "^2.33.0", "@typescript-eslint/parser": "^2.33.0", "eslint": "^6.8.0", "glob": "^7.1.6", "mocha": "^7.1.2", - "simple-mock": "^0.8.0", + "sinon": "^9.0.2", "ts-loader": "^7.0.4", "typescript": "^3.8.3", "vscode-test": "^1.3.0", @@ -83,7 +84,6 @@ "webpack-cli": "^3.3.11" }, "dependencies": { - "@types/md5": "^2.2.0", "md5": "^2.2.1", "remark-frontmatter": "^2.0.0", "remark-parse": "^8.0.2", diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index ee9aaa0..fbf8771 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -1,5 +1,5 @@ import * as assert from "assert"; -import * as simple from "simple-mock"; +import * as sinon from "sinon"; // You can import and use all API from the 'vscode' module // as well as import your extension to test it @@ -16,11 +16,32 @@ import { getDot, exists, filterNonExistingEdges, + getColumnSetting, + getFileIdRegexp, } from "../../utils"; import { Graph } from "../../types"; -import { parseFile } from "../../parsing"; +import { + parseFile, + findFileId, + parseDirectory, + processFile, +} from "../../parsing"; +import { TextEncoder } from "util"; describe("Tests", () => { + let stub; + + before(() => { + stub = sinon.stub(vscode.workspace, "getConfiguration").returns({ + openColumn: "one", + fileIdRegexp: "\\d{10}", + } as any); + }); + + after(() => { + stub.reset(); + }); + vscode.window.showInformationMessage("Start all tests."); const getGraph = () => ({ @@ -72,12 +93,24 @@ describe("Tests", () => { ); }); - xit("getColumnSetting works", () => { - // TODO: mock vscode.workspace.getConfiguration + it("getColumnSetting works", () => { + const setting = getColumnSetting("openColumn"); + assert.equal(setting, vscode.ViewColumn.One); }); - xit("getFileIdRegexp", () => { - // TODO: mock vscode.workspace.getConfiguration + describe("getFileIdRegexp", () => { + it("works", () => { + const regexp = getFileIdRegexp(); + + assert.equal( + regexp.test("# Title\n\n1234567890\n\nThat was an ID."), + true + ); + + assert.equal(regexp.test("# Title\n\n123456\n\nThat was an ID."), false); + }); + + xit("defaults if no regexp is set", () => {}); }); it("getDot works", () => { @@ -97,7 +130,7 @@ describe("Tests", () => { it("filterNonExistingEdges", () => { const graph = getGraph(); - graph.edges.push({ source: "2", target: "https://wikipedia.org" }); + graph.edges.push({ source: "2", target: "https://wikipedia.org/" }); graph.edges.push({ source: "2", target: "4" }); assert.equal(graph.edges.length, 5); @@ -107,38 +140,82 @@ describe("Tests", () => { xit("idResolver works", () => {}); - it("parseFile works", () => { - const graph: Graph = { - nodes: [], - edges: [], - }; - - const path = "/Users/test/Desktop/notes"; - const firstFileName = "1.md"; - const firstFilePath = `${path}/${firstFileName}`; - const secondFileName = "2.md"; - const title = "Test"; - const content = `# ${title}\n\n[Link](${secondFileName})\n`; - - parseFile(graph, firstFilePath, content); - - assert.deepStrictEqual(graph.nodes, [ - { id: id(firstFilePath), label: title, path: firstFilePath }, - ]); - assert.deepStrictEqual(graph.edges, [ - { source: id(firstFilePath), target: id(`${path}/${secondFileName}`) }, - ]); + describe("parseFile", () => { + it("works", () => { + const graph: Graph = { + nodes: [], + edges: [], + }; + + const path = "/Users/test/Desktop/notes"; + const firstFileName = "1.md"; + const firstFilePath = `${path}/${firstFileName}`; + const secondFileName = "2.md"; + const title = "Test"; + const content = `# ${title}\n\n[Link](${secondFileName})\n`; + + parseFile(graph, firstFilePath, content); + + assert.deepStrictEqual(graph.nodes, [ + { id: id(firstFilePath), label: title, path: firstFilePath }, + ]); + assert.deepStrictEqual(graph.edges, [ + { source: id(firstFilePath), target: id(`${path}/${secondFileName}`) }, + ]); + }); }); - xit("findFileId works", () => { - // TODO: mocks. + it("findFileId works", async () => { + const file = "# Title\n\n1234567890\n\nThat was an ID."; + + const promise: Promise = new Promise((resolve) => + resolve(new TextEncoder().encode(file)) + ); + + const stub = sinon.stub(vscode.workspace.fs, "readFile").returns(promise); + + assert.equal( + await findFileId("/Users/test/Desktop/notes/1.md"), + "1234567890" + ); + + stub.reset(); }); xit("learnFileId works", () => { // TODO: mocks. }); - xit("parseDirectory works", () => { - // TODO: mocks. + describe("parseDirectory", () => { + xit("works", async () => { + const promise: Promise<[string, vscode.FileType][]> = new Promise( + (resolve) => + resolve([ + ["/Users/test/Desktop/notes/1.md", vscode.FileType.File], + ["/Users/test/Desktop/notes/2.md", vscode.FileType.File], + ]) + ); + + const stub = sinon + .stub(vscode.workspace.fs, "readDirectory") + .returns(promise); + + const graph = { + nodes: [], + edges: [], + }; + + // TODO: + // - mock readFile to give proper content + // - assert to make check if parseDirectory populates the graph + + await parseDirectory(graph, "/Users/test/Desktop/notes", processFile); + + stub.reset(); + }); + + xit("returns empty graph for non-existing directory", async () => {}); + + xit("", async () => {}); }); }); diff --git a/yarn.lock b/yarn.lock index 52eefaf..b979d8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -30,6 +30,42 @@ dependencies: regenerator-runtime "^0.13.4" +"@sinonjs/commons@^1", "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.7.2": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.0.tgz#c8d68821a854c555bba172f3b06959a0039b236d" + integrity sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^6.0.0", "@sinonjs/fake-timers@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" + integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@sinonjs/formatio@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-5.0.1.tgz#f13e713cb3313b1ab965901b01b0828ea6b77089" + integrity sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ== + dependencies: + "@sinonjs/commons" "^1" + "@sinonjs/samsam" "^5.0.2" + +"@sinonjs/samsam@^5.0.2", "@sinonjs/samsam@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.0.3.tgz#86f21bdb3d52480faf0892a480c9906aa5a52938" + integrity sha512-QucHkc2uMJ0pFGjJUDP3F9dq5dx8QIaqISl9QgwLOh6P9yv877uONPGXh/OH/0zmM3tW1JjuJltAZV2l7zU+uQ== + dependencies: + "@sinonjs/commons" "^1.6.0" + lodash.get "^4.4.2" + type-detect "^4.0.8" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" + integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -81,10 +117,17 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.5.tgz#96ec3b0afafd64a4ccea9107b75bf8489f0e5765" integrity sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g== -"@types/simple-mock@^0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@types/simple-mock/-/simple-mock-0.8.1.tgz#bcb7d4bdd1d7c142008af3c32603c7088ad9af33" - integrity sha512-Mn5n1v3S5yhhegOSUpXl2WTujBJfM1Oa0YTb9PpaYUq6Iqj6yOxy8h8lwMtNidKs3pAByhp1uIK0QP+OZCsotQ== +"@types/sinon@^9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.4.tgz#e934f904606632287a6e7f7ab0ce3f08a0dad4b1" + integrity sha512-sJmb32asJZY6Z2u09bl0G2wglSxDlROlAejCjsnor+LzBMz17gu8IU7vKC/vWDnv9zEq2wqADHVXFjf4eE8Gdw== + dependencies: + "@types/sinonjs__fake-timers" "*" + +"@types/sinonjs__fake-timers@*": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e" + integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA== "@types/unist@^2.0.0", "@types/unist@^2.0.2": version "2.0.3" @@ -1105,6 +1148,11 @@ diff@3.5.0: resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -2168,6 +2216,11 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2225,6 +2278,11 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +just-extend@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.0.tgz#7278a4027d889601640ee0ce0e5a00b992467da4" + integrity sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA== + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -2295,6 +2353,11 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + lodash@^4.17.14, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" @@ -2581,6 +2644,17 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +nise@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nise/-/nise-4.0.3.tgz#9f79ff02fa002ed5ffbc538ad58518fa011dc913" + integrity sha512-EGlhjm7/4KvmmE6B/UFsKh7eHykRl9VH+au8dduHLCyWUO/hr7+N+WtTvDUwc9zHuM1IaIJs/0lQ6Ag1jDkQSg== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@sinonjs/fake-timers" "^6.0.0" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + path-to-regexp "^1.7.0" + node-environment-flags@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" @@ -2852,6 +2926,13 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + pbkdf2@^3.0.3: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -3307,10 +3388,18 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== -simple-mock@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/simple-mock/-/simple-mock-0.8.0.tgz#49c9a223fa6eea8e2c4fd6948fe8300cd8a594f3" - integrity sha1-ScmiI/pu6o4sT9aUj+gwDNillPM= +sinon@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.0.2.tgz#b9017e24633f4b1c98dfb6e784a5f0509f5fd85d" + integrity sha512-0uF8Q/QHkizNUmbK3LRFqx5cpTttEVXudywY9Uwzy8bTfZUhljZ7ARzSxnRHWYWtVTeh4Cw+tTb3iU21FQVO9A== + dependencies: + "@sinonjs/commons" "^1.7.2" + "@sinonjs/fake-timers" "^6.0.1" + "@sinonjs/formatio" "^5.0.1" + "@sinonjs/samsam" "^5.0.3" + diff "^4.0.2" + nise "^4.0.1" + supports-color "^7.1.0" slice-ansi@^2.1.0: version "2.1.0" @@ -3750,6 +3839,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@4.0.8, type-detect@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" From 062af8ce1d94d0915ee314d31c247a15e4869272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Fri, 26 Jun 2020 01:20:44 +0200 Subject: [PATCH 07/13] Commit past changes --- src/extension.ts | 3 ++- src/utils.ts | 8 ++++---- static/webview.html | 29 +++++++++++++++++++++++------ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 27ca4d4..17dd71b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -2,7 +2,7 @@ import * as vscode from "vscode"; import { TextDecoder } from "util"; import * as path from "path"; import { parseDirectory, learnFileId, processFile } from "./parsing"; -import { filterNonExistingEdges, getColumnSetting } from "./utils"; +import { filterNonExistingEdges, getColumnSetting, getDot } from "./utils"; import { Graph } from "./types"; const watch = ( @@ -138,6 +138,7 @@ export function activate(context: vscode.ExtensionContext) { panel.webview.html = await getWebviewContent(context, graph, d3Uri); + console.log(getDot(graph)); watch(context, panel, graph); }) ); diff --git a/src/utils.ts b/src/utils.ts index ad3f2ab..4aabda7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -60,12 +60,12 @@ export const findTitle = (ast: MarkdownNode): string | null => { * @param path absolute path of the file. */ export const id = (path: string): string => { - return md5(path); + // return md5(path); // Extracting file name without extension: - // const fullPath = path.split("/"); - // const fileName = fullPath[fullPath.length - 1]; - // return fileName.split(".")[0]; + const fullPath = path.split("/"); + const fileName = fullPath[fullPath.length - 1]; + return fileName.split(".")[0]; }; /** diff --git a/static/webview.html b/static/webview.html index e722678..f3dffd6 100644 --- a/static/webview.html +++ b/static/webview.html @@ -11,7 +11,7 @@ } .links line { - stroke: #ccc; + stroke: #000; } .nodes circle { @@ -48,19 +48,37 @@ 1.00x