Consolidate foam-core within foam-vscode (#774)

* moved `foam-core` inside `foam-vscode`

* updated contribution guide to reflect new modules setup

* improved testing

* consolidate to root yarn.lock files

* tweaking CI workflow && using github secrets to force cache refresh

* improved linting configuration. `core` module cannot depend on other parts of the `foam-vscode` package
This commit is contained in:
Riccardo
2021-10-09 11:09:02 +02:00
committed by GitHub
parent ee7a891976
commit d222cfbbec
118 changed files with 717 additions and 13560 deletions

View File

@@ -1,20 +1,18 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/class-name-casing": "warn",
"@typescript-eslint/semi": "warn",
"curly": "warn",
"eqeqeq": "warn",
"no-throw-literal": "warn",
"semi": "off",
"require-await": "warn"
}
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "import"],
"rules": {
"@typescript-eslint/class-name-casing": "warn",
"@typescript-eslint/semi": "warn",
"curly": "warn",
"eqeqeq": "warn",
"no-throw-literal": "warn",
"semi": "off",
"require-await": "warn"
}
}

View File

@@ -3,17 +3,15 @@ name: CI
on:
push:
branches:
- '**'
# The following will also make the workflow run on all PRs, internal and external.
# This would create duplicate runs, that we are skipping by adding the "if" to the jobs below.
# See https://github.community/t/duplicate-checks-on-push-and-pull-request-simultaneous-event/18012
- master
pull_request:
branches:
- master
jobs:
lint:
name: Lint
runs-on: ubuntu-18.04
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != 'foambubble/foam'
steps:
- uses: actions/checkout@v1
- name: Setup Node
@@ -27,7 +25,7 @@ jobs:
node_modules
*/*/node_modules
packages/foam-vscode/.vscode-test
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock', 'packages/foam-vscode/src/test/run-tests.ts') }}
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock', 'packages/foam-vscode/src/test/run-tests.ts') }}-${{ secrets.CACHE_VERSION }}
- name: Install Dependencies
run: yarn
- name: Check Lint Rules
@@ -39,7 +37,6 @@ jobs:
matrix:
os: [macos-10.15, ubuntu-18.04, windows-2019]
runs-on: ${{ matrix.os }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != 'foambubble/foam'
env:
OS: ${{ matrix.os }}
steps:
@@ -55,7 +52,7 @@ jobs:
node_modules
*/*/node_modules
packages/foam-vscode/.vscode-test
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock', 'packages/foam-vscode/src/test/run-tests.ts') }}
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock', 'packages/foam-vscode/src/test/run-tests.ts') }}-${{ secrets.CACHE_VERSION }}
- name: Install Dependencies
run: yarn
- name: Build Packages

54
.vscode/tasks.json vendored
View File

@@ -1,31 +1,31 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"label": "watch: foam-vscode",
"type": "npm",
"script": "start:vscode",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "always"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "test: all packages",
"type": "npm",
"script": "test",
"problemMatcher": [],
"group": {
"kind": "test",
"isDefault": true
},
}
]
"version": "2.0.0",
"tasks": [
{
"label": "watch: foam-vscode",
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "always"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "test: all packages",
"type": "npm",
"script": "test",
"problemMatcher": [],
"group": {
"kind": "test",
"isDefault": true
}
}
]
}

View File

@@ -18,8 +18,6 @@ Before you start contributing we recommend that you read the following links:
We understand that diving in an unfamiliar codebase may seem scary,
to make it easier for new contributors we provide some resources:
- [[architecture]] - This document describes the architecture of Foam and how the repository is structured.
You can also see [existing issues](https://github.com/foambubble/foam/issues) and help out!
Finally, the easiest way to help, is to use it and provide feedback by [submitting issues](https://github.com/foambubble/foam/issues/new/choose) or participating in the [Foam Community Discord](https://foambubble.github.io/join-discord/g)!
@@ -35,22 +33,48 @@ If you're interested in contributing, this short guide will help you get things
`yarn install`
3. This project uses [Yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/). `foam-vscode` relies on `foam-core`. This means we need to compile it before we do any extension development. From the root, run the command:
3. From the root, run the command:
`yarn build`
You should now be ready to start working!
### Structure of the project
Foam code and documentation live in the monorepo at [foambubble/foam](https://github.com/foambubble/foam/).
- [/docs](https://github.com/foambubble/foam/tree/master/docs): documentation and [[recipes]].
Exceptions to the monorepo are:
- The starter template at [foambubble/foam-template](https://github.com/foambubble/)
- All other [[recommended-extensions]] live in their respective GitHub repos
This project uses [Yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/).
Originally Foam had:
- [/packages/foam-core](https://github.com/foambubble/foam/tree/master/packages/foam-core) - Powers the core functionality in Foam across all platforms.
- [/packages/foam-vscode](https://github.com/foambubble/foam/tree/master/packages/foam-vscode) - The core VS Code plugin.
To improve DX we have moved the `foam-core` module into `packages/foam-vscode/src/core`, but from a development point of view it's useful to think of the `foam-vscode/src/core` "submodule" as something that might be extracted in the future.
For all intents and purposes this means two things:
1. nothing in `foam-vscode/src/core` should depend on files outside of this directory
2. code in `foam-vscode/src/core` should NOT depend on `vscode` library
We have kept the yarn workspace for the time being as we might use it to pull out `foam-core` in the future, or we might need it for other packages that the VS Code plugin could depend upon (e.g. currently the graph visualization is inside the module, but it might be pulled out if its complexity increases).
### Testing
Code needs to come with tests.
We use the following convention in Foam:
- *.test.ts are unit tests
- *.spec.ts are integration tests
- `*.test.ts` are unit tests
- `*.spec.ts` are integration tests
Also, note that tests in `foam-core` live in the `test` directory.
Tests in `foam-vscode` live alongside the code in `src`.
Tests live alongside the code in `src`.
### The VS Code Extension
@@ -71,5 +95,6 @@ Feel free to modify and submit a PR if this guide is out-of-date or contains err
[//begin]: # "Autogenerated link references for markdown compatibility"
[principles]: principles.md "Principles"
[code-of-conduct]: code-of-conduct.md "Code of Conduct"
[architecture]: dev/architecture.md "Architecture"
[recipes]: recipes/recipes.md "Recipes"
[recommended-extensions]: recommended-extensions.md "Recommended Extensions"
[//end]: # "Autogenerated link references"

View File

@@ -1,23 +0,0 @@
---
tags: architecture
---
# Architecture
This document aims to provide a quick overview of the Foam architecture!
Foam code and documentation live in the monorepo at [foambubble/foam](https://github.com/foambubble/foam/).
- [/docs](https://github.com/foambubble/foam/tree/master/docs): documentation and [[recipes]].
- [/packages/foam-core](https://github.com/foambubble/foam/tree/master/packages/foam-core) - Powers the core functionality in Foam across all platforms.
- [/packages/foam-vscode](https://github.com/foambubble/foam/tree/master/packages/foam-vscode) - The core VSCode plugin.
Exceptions to the monorepo are:
- The starter template at [foambubble/foam-template](https://github.com/foambubble/)
- All other [[recommended-extensions]] live in their respective GitHub repos.
- [foam-cli](https://github.com/foambubble/foam-cli) - The Foam CLI tool.
[//begin]: # "Autogenerated link references for markdown compatibility"
[recipes]: ../recipes/recipes.md "Recipes"
[recommended-extensions]: ../recommended-extensions.md "Recommended Extensions"
[//end]: # "Autogenerated link references"

View File

@@ -9,10 +9,6 @@
"packages/*"
],
"scripts": {
"start:vscode": "yarn workspace foam-vscode vscode:start-debugging",
"build:core": "yarn workspace foam-core build",
"watch:core": "yarn workspace foam-core start",
"test:core": "yarn workspace foam-core test",
"vscode:package-extension": "yarn workspace foam-vscode package-extension",
"vscode:install-extension": "yarn workspace foam-vscode install-extension",
"vscode:publish-extension": "yarn workspace foam-vscode publish-extension",

View File

@@ -1,3 +0,0 @@
module.exports = {
plugins: [['@babel/plugin-transform-runtime', { helpers: false }]],
};

View File

@@ -1,21 +0,0 @@
# Foam Core
This module contains the core functions, model, and API of Foam.
It is used by its clients to integrate Foam in various use cases, from VsCode extension, to CLI, to CI integrations.
## Local Development
Below is a list of commands you will probably find useful.
### `yarn watch`
Runs the project in development/watch mode. Your project will be rebuilt upon changes.
### `yarn build`
Bundles the package to the `dist` folder. The package is optimized and bundled with Rollup into multiple formats (CommonJS, UMD, and ES Module).
### `yarn test`
Runs the test watcher (Jest) in an interactive mode.
By default, runs tests related to files changed since the last commit.

View File

@@ -1,49 +0,0 @@
{
"name": "foam-core",
"repository": "https://github.com/foambubble/foam",
"version": "0.15.0",
"license": "MIT",
"files": [
"dist"
],
"scripts": {
"clean": "rimraf dist",
"build": "tsdx build --tsconfig ./tsconfig.build.json",
"test": "tsdx test",
"lint": "tsdx lint src test",
"watch": "tsdx watch",
"prepare": "tsdx build --tsconfig ./tsconfig.build.json"
},
"devDependencies": {
"@babel/core": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"@babel/preset-typescript": "^7.10.4",
"@types/github-slugger": "^1.3.0",
"@types/lodash": "^4.14.157",
"@types/micromatch": "^4.0.1",
"@types/picomatch": "^2.2.1",
"husky": "^4.2.5",
"tsdx": "^0.13.2",
"tslib": "^2.0.0",
"typescript": "^3.9.5"
},
"dependencies": {
"detect-newline": "^3.1.0",
"fast-array-diff": "^1.0.1",
"github-slugger": "^1.3.0",
"glob": "^7.1.6",
"lodash": "^4.17.21",
"micromatch": "^4.0.2",
"remark-frontmatter": "^2.0.0",
"remark-parse": "^8.0.2",
"remark-wiki-link": "^0.0.4",
"replace-ext": "^2.0.0",
"title-case": "^3.0.2",
"unified": "^9.0.0",
"unist-util-visit": "^2.0.2",
"yaml": "^1.10.0"
},
"main": "dist/index.js",
"types": "dist/index.d.ts"
}

View File

@@ -1,64 +0,0 @@
import {
Resource,
ResourceLink,
NoteLinkDefinition,
ResourceParser,
Tag,
} from './model/note';
import { FoamConfig } from './config';
import {
IDataStore,
FileDataStore,
Matcher,
IMatcher,
} from './services/datastore';
import { ILogger } from './utils/log';
import { IDisposable, isDisposable } from './common/lifecycle';
import { FoamWorkspace } from './model/workspace';
import { FoamGraph } from '../src/model/graph';
import { URI } from './model/uri';
import { FoamTags } from '../src/model/tags';
export { Position } from './model/position';
export { Range } from './model/range';
export { IDataStore, FileDataStore, Matcher, IMatcher };
export { ILogger };
export { LogLevel, LogLevelThreshold, Logger, BaseLogger } from './utils/log';
export { Event, Emitter } from './common/event';
export { FoamConfig };
export { ResourceProvider } from './model/provider';
export { IDisposable, isDisposable };
export {
createMarkdownReferences,
stringifyMarkdownLinkReferenceDefinition,
createMarkdownParser,
MarkdownResourceProvider,
} from './markdown-provider';
export {
TextEdit,
generateHeading,
generateLinkReferences,
getKebabCaseFileName,
LINK_REFERENCE_DEFINITION_HEADER,
LINK_REFERENCE_DEFINITION_FOOTER,
} from './janitor';
export { applyTextEdit } from './janitor/apply-text-edit';
export { createConfigFromFolders } from './config';
export { Foam, Services, bootstrap } from './model/foam';
export {
Resource,
ResourceLink,
URI,
Tag,
FoamWorkspace,
FoamGraph,
FoamTags,
NoteLinkDefinition,
ResourceParser,
};

View File

@@ -1,99 +0,0 @@
import path from 'path';
import { FoamWorkspace } from '../src';
import { NoteLinkDefinition, Resource } from '../src/model/note';
import { IDataStore, Matcher } from '../src/services/datastore';
import { MarkdownResourceProvider } from '../src/markdown-provider';
import { Range } from '../src/model/range';
import { URI } from '../src/model/uri';
import { Logger } from '../src/utils/log';
Logger.setLevel('error');
const position = Range.create(0, 0, 0, 100);
const documentStart = position.start;
const documentEnd = position.end;
const eol = '\n';
/**
* Turns a string into a URI
* The goal of this function is to make sure we are consistent in the
* way we generate URIs (and therefore IDs) across the tests
*/
export const strToUri = URI.file;
export const noOpDataStore = (): IDataStore => ({
read: _ => Promise.resolve(''),
list: _ => Promise.resolve([]),
});
export const createTestWorkspace = () => {
const workspace = new FoamWorkspace();
const matcher = new Matcher([URI.file('/')], ['**/*']);
const provider = new MarkdownResourceProvider(
matcher,
undefined,
undefined,
noOpDataStore()
);
workspace.registerProvider(provider);
return workspace;
};
export const createTestNote = (params: {
uri: string;
title?: string;
definitions?: NoteLinkDefinition[];
links?: Array<{ slug: string } | { to: string }>;
text?: string;
root?: URI;
tags?: string[];
}): Resource => {
const root = params.root ?? URI.file('/');
return {
uri: URI.resolve(params.uri, root),
type: 'note',
properties: {},
title: params.title ?? path.parse(strToUri(params.uri).path).base,
definitions: params.definitions ?? [],
tags:
params.tags?.map(t => ({
label: t,
range: Range.create(0, 0, 0, 0),
})) ?? [],
links: params.links
? params.links.map((link, index) => {
const range = Range.create(
position.start.line + index,
position.start.character,
position.start.line + index,
position.end.character
);
return 'slug' in link
? {
type: 'wikilink',
target: link.slug,
label: link.slug,
range: range,
rawText: 'link text',
}
: {
type: 'link',
target: link.to,
label: 'link text',
range: range,
};
})
: [],
source: {
eol: eol,
end: documentEnd,
contentStart: documentStart,
text: params.text ?? '',
},
};
};
describe('Test utils', () => {
it('are happy', () => {});
});

View File

@@ -1,6 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "ESNext"
}
}

View File

@@ -1,29 +0,0 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": "src",
"composite": true,
"esModuleInterop": true,
"importHelpers": true,
"downlevelIteration": true,
// commonjs module format is used so that the incremental
// tsc build-mode ran during development can replace individual
// files (as opposed to generate the .cjs.development.js bundle.
//
// this is overridden in tsconfig.build.json for distribution
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
"rootDir": "./src",
"sourceMap": true,
"strict": true,
"lib": [
"ES2019", "es2020.string"
]
},
"include": [
"src",
"types"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -361,9 +361,11 @@
"build": "tsc -p ./",
"pretest": "yarn build",
"test": "node ./out/test/run-tests.js",
"lint": "tsdx lint",
"unit": "node ./out/test/run-tests.js --unit",
"e2e": "node ./out/test/run-tests.js --e2e",
"lint": "tsdx lint src",
"clean": "rimraf out",
"watch": "tsc --build ./tsconfig.json ../foam-core/tsconfig.json --watch",
"watch": "tsc --build ./tsconfig.json --watch",
"vscode:start-debugging": "yarn clean && yarn watch",
"vscode:prepublish": "yarn npm-install && yarn run build",
"npm-install": "rimraf node_modules && npm i",
@@ -376,34 +378,55 @@
},
"devDependencies": {
"@babel/core": "^7.11.0",
"@babel/plugin-transform-runtime": "^7.10.4",
"@babel/preset-env": "^7.11.0",
"@babel/preset-typescript": "^7.10.4",
"@types/dateformat": "^3.0.1",
"@types/github-slugger": "^1.3.0",
"@types/glob": "^7.1.1",
"@types/lodash": "^4.14.157",
"@types/markdown-it": "^12.0.1",
"@types/micromatch": "^4.0.1",
"@types/node": "^13.11.0",
"@types/picomatch": "^2.2.1",
"@types/remove-markdown": "^0.1.1",
"@types/vscode": "^1.47.1",
"@typescript-eslint/eslint-plugin": "^2.30.0",
"@typescript-eslint/parser": "^2.30.0",
"babel-jest": "^26.2.2",
"eslint": "^6.8.0",
"eslint-plugin-import": "^2.24.2",
"glob": "^7.1.6",
"husky": "^4.2.5",
"jest": "^26.2.2",
"jest-environment-vscode": "^1.0.0",
"jest-extended": "^0.11.5",
"markdown-it": "^12.0.4",
"rimraf": "^3.0.2",
"ts-jest": "^26.4.4",
"typescript": "^3.8.3",
"tsdx": "^0.13.2",
"tslib": "^2.0.0",
"typescript": "^3.9.5",
"vscode-test": "^1.3.0"
},
"dependencies": {
"dateformat": "^3.0.3",
"foam-core": "^0.15.0",
"detect-newline": "^3.1.0",
"fast-array-diff": "^1.0.1",
"github-slugger": "^1.3.0",
"glob": "^7.1.6",
"gray-matter": "^4.0.2",
"lodash": "^4.17.21",
"markdown-it-regex": "^0.2.0",
"micromatch": "^4.0.2",
"remove-markdown": "^0.3.0"
"remark-frontmatter": "^2.0.0",
"remark-parse": "^8.0.2",
"remark-wiki-link": "^0.0.4",
"remove-markdown": "^0.3.0",
"replace-ext": "^2.0.0",
"title-case": "^3.0.2",
"unified": "^9.0.0",
"unist-util-visit": "^2.0.2",
"yaml": "^1.10.0"
}
}

View File

@@ -0,0 +1,36 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"name": "vscode",
"message": "Core submodule must not depend on VS Code."
}
]
// Ideally we would also prevent the core module from depending on other modules
// but I have been struggling to get it to work.
// For future reference, below are some configurations I think should achieve this
// (but I couldn't manage to get working).
//
// "import/no-internal-modules": [
// "error",
// {
// "allow": ["./src/core"]
// }
// ]
// "import/no-restricted-paths": [
// "error",
// {
// "zones": [
// {
// "target": "./src/core",
// "from": "./src/(!core)",
// "message": "Core module can't have outside dependencies."
// }
// ]
// }
// ]
// "import/no-relative-parent-imports": "error"
// note: https://github.com/import-js/eslint-plugin-import/issues/1610
}
}

View File

@@ -1,10 +1,11 @@
import { createConfigFromFolders } from '../src/config';
import { Logger } from '../src/utils/log';
import { URI } from '../src/model/uri';
import { createConfigFromFolders } from './config';
import { Logger } from './utils/log';
import { URI } from './model/uri';
import { TEST_DATA_DIR } from '../test/test-utils';
Logger.setLevel('error');
const testFolder = URI.joinPath(URI.file(__dirname), 'test-config');
const testFolder = URI.joinPath(TEST_DATA_DIR, 'test-config');
describe('Foam configuration', () => {
it('can read settings from config.json', () => {

View File

@@ -1,6 +1,6 @@
import { applyTextEdit } from '../../src/janitor/apply-text-edit';
import { Range } from '../../src/model/range';
import { Logger } from '../../src/utils/log';
import { Range } from '../model/range';
import { Logger } from '../utils/log';
import { applyTextEdit } from './apply-text-edit';
Logger.setLevel('error');

View File

@@ -1,7 +1,7 @@
import os from 'os';
import detectNewline from 'detect-newline';
import { Position } from '../model/position';
import { TextEdit } from '../index';
import { TextEdit } from '.';
/**
*

View File

@@ -1,13 +1,14 @@
import * as path from 'path';
import { generateHeading } from '../../src/janitor';
import { createConfigFromFolders } from '../../src/config';
import { Resource } from '../../src/model/note';
import { FileDataStore, Matcher } from '../../src/services/datastore';
import { Logger } from '../../src/utils/log';
import { FoamWorkspace } from '../../src/model/workspace';
import { URI } from '../../src/model/uri';
import { Range } from '../../src/model/range';
import { MarkdownResourceProvider, bootstrap } from '../../src';
import { generateHeading } from '.';
import { TEST_DATA_DIR } from '../../test/test-utils';
import { createConfigFromFolders } from '../config';
import { MarkdownResourceProvider } from '../markdown-provider';
import { bootstrap } from '../model/foam';
import { Resource } from '../model/note';
import { Range } from '../model/range';
import { URI } from '../model/uri';
import { FoamWorkspace } from '../model/workspace';
import { FileDataStore, Matcher } from '../services/datastore';
import { Logger } from '../utils/log';
Logger.setLevel('error');
@@ -21,7 +22,7 @@ describe('generateHeadings', () => {
beforeAll(async () => {
const config = createConfigFromFolders([
URI.file(path.join(__dirname, '..', '__scaffold__')),
URI.joinPath(TEST_DATA_DIR, '__scaffold__'),
]);
const mdProvider = new MarkdownResourceProvider(
new Matcher(

View File

@@ -1,13 +1,14 @@
import * as path from 'path';
import { generateLinkReferences } from '../../src/janitor';
import { createConfigFromFolders } from '../../src/config';
import { FileDataStore, Matcher } from '../../src/services/datastore';
import { Logger } from '../../src/utils/log';
import { FoamWorkspace } from '../../src/model/workspace';
import { URI } from '../../src/model/uri';
import { Resource } from '../../src/model/note';
import { Range } from '../../src/model/range';
import { MarkdownResourceProvider, bootstrap } from '../../src';
import { generateLinkReferences } from '.';
import { TEST_DATA_DIR } from '../../test/test-utils';
import { createConfigFromFolders } from '../config';
import { MarkdownResourceProvider } from '../markdown-provider';
import { bootstrap } from '../model/foam';
import { Resource } from '../model/note';
import { Range } from '../model/range';
import { URI } from '../model/uri';
import { FoamWorkspace } from '../model/workspace';
import { FileDataStore, Matcher } from '../services/datastore';
import { Logger } from '../utils/log';
Logger.setLevel('error');
@@ -21,7 +22,7 @@ describe('generateLinkReferences', () => {
beforeAll(async () => {
const config = createConfigFromFolders([
URI.file(path.join(__dirname, '..', '__scaffold__')),
URI.joinPath(TEST_DATA_DIR, '__scaffold__'),
]);
const mdProvider = new MarkdownResourceProvider(
new Matcher(

View File

@@ -2,14 +2,14 @@ import {
createMarkdownParser,
createMarkdownReferences,
ParserPlugin,
} from '../src/markdown-provider';
import { DirectLink, WikiLink } from '../src/model/note';
import { Logger } from '../src/utils/log';
import { uriToSlug } from '../src/utils/slug';
import { URI } from '../src/model/uri';
import { FoamGraph } from '../src/model/graph';
import { createTestWorkspace } from './core.test';
import { Range } from '../src/model/range';
} from './markdown-provider';
import { DirectLink, WikiLink } from './model/note';
import { Logger } from './utils/log';
import { uriToSlug } from './utils/slug';
import { URI } from './model/uri';
import { FoamGraph } from './model/graph';
import { Range } from './model/range';
import { createTestWorkspace } from '../test/test-utils';
Logger.setLevel('error');

View File

@@ -27,9 +27,9 @@ import {
import { Logger } from './utils/log';
import { URI } from './model/uri';
import { FoamWorkspace } from './model/workspace';
import { ResourceProvider } from 'model/provider';
import { IDataStore, FileDataStore, IMatcher } from './services/datastore';
import { IDisposable } from 'common/lifecycle';
import { IDisposable } from './common/lifecycle';
import { ResourceProvider } from './model/provider';
const ALIAS_DIVIDER_CHAR = '|';

View File

@@ -2,9 +2,9 @@ import { diff } from 'fast-array-diff';
import { isEqual } from 'lodash';
import { Resource, ResourceLink } from './note';
import { URI } from './uri';
import { IDisposable } from '../index';
import { FoamWorkspace, uriToResourceName } from './workspace';
import { Range } from './range';
import { IDisposable } from '../common/lifecycle';
export type Connection = {
source: URI;

View File

@@ -1,6 +1,6 @@
import { IDisposable } from 'common/lifecycle';
import { ResourceLink, URI } from 'index';
import { Resource } from './note';
import { IDisposable } from '../common/lifecycle';
import { Resource, ResourceLink } from './note';
import { URI } from './uri';
import { FoamWorkspace } from './workspace';
export interface ResourceProvider extends IDisposable {

View File

@@ -1,5 +1,5 @@
import { FoamTags } from '../src/model/tags';
import { createTestNote, createTestWorkspace } from './core.test';
import { createTestNote, createTestWorkspace } from '../../test/test-utils';
import { FoamTags } from './tags';
describe('FoamTags', () => {
it('Collects tags from a list of resources', () => {

View File

@@ -1,7 +1,7 @@
import { FoamWorkspace } from './workspace';
import { URI } from './uri';
import { IDisposable } from '../index';
import { Resource } from './note';
import { IDisposable } from '../common/lifecycle';
export class FoamTags implements IDisposable {
public readonly tags: Map<string, URI[]> = new Map();

View File

@@ -1,6 +1,6 @@
import { Logger } from '../src';
import { URI } from '../src/model/uri';
import { uriToSlug } from '../src/utils/slug';
import { Logger } from '../utils/log';
import { uriToSlug } from '../utils/slug';
import { URI } from './uri';
Logger.setLevel('error');

View File

@@ -1,8 +1,8 @@
import { getReferenceType } from '../src/model/workspace';
import { FoamGraph } from '../src/model/graph';
import { Logger } from '../src/utils/log';
import { createTestNote, createTestWorkspace } from './core.test';
import { URI } from '../src/model/uri';
import { getReferenceType } from './workspace';
import { FoamGraph } from './graph';
import { Logger } from '../utils/log';
import { URI } from './uri';
import { createTestNote, createTestWorkspace } from '../../test/test-utils';
Logger.setLevel('error');

View File

@@ -3,8 +3,8 @@ import { Resource, ResourceLink } from './note';
import { URI } from './uri';
import { isSome, isNone } from '../utils';
import { Emitter } from '../common/event';
import { IDisposable } from '../index';
import { ResourceProvider } from './provider';
import { IDisposable } from '../common/lifecycle';
export function getReferenceType(
reference: URI | string

View File

@@ -1,11 +1,11 @@
import { Logger } from '../src/utils/log';
import { URI } from '../src/model/uri';
import { FileDataStore, Matcher } from '../src';
import { toMatcherPathFormat } from '../src/services/datastore';
import { TEST_DATA_DIR } from '../../test/test-utils';
import { URI } from '../model/uri';
import { Logger } from '../utils/log';
import { FileDataStore, Matcher, toMatcherPathFormat } from './datastore';
Logger.setLevel('error');
const testFolder = URI.joinPath(URI.file(__dirname), 'test-datastore');
const testFolder = URI.joinPath(TEST_DATA_DIR, 'test-datastore');
describe('Matcher', () => {
it('generates globs with the base dir provided', () => {

View File

@@ -1,19 +1,19 @@
import crypto from 'crypto';
export function isNotNull<T>(value: T | null): value is T {
return value != null;
return value != null; // eslint-disable-line
}
export function isSome<T>(
value: T | null | undefined | void
): value is NonNullable<T> {
return value != null;
return value != null; // eslint-disable-line
}
export function isNone<T>(
value: T | null | undefined | void
): value is null | undefined | void {
return value == null;
return value == null; // eslint-disable-line
}
export function isNumeric(value: string): boolean {

View File

@@ -1,5 +1,5 @@
import { extractHashtags } from '../src/utils';
import { Logger } from '../src/utils/log';
import { extractHashtags } from './index';
import { Logger } from './log';
Logger.setLevel('error');

View File

@@ -1,6 +1,6 @@
import { workspace } from 'vscode';
import { getDailyNotePath } from './dated-notes';
import { URI } from 'foam-core';
import { URI } from './core/model/uri';
import { isWindows } from './utils';
describe('getDailyNotePath', () => {

View File

@@ -2,7 +2,7 @@ import { workspace, WorkspaceConfiguration } from 'vscode';
import dateFormat from 'dateformat';
import { isAbsolute } from 'path';
import { focusNote, pathExists } from './utils';
import { URI } from 'foam-core';
import { URI } from './core/model/uri';
import { createNoteFromDailyNoteTemplate } from './features/create-from-template';
/**

View File

@@ -1,19 +1,15 @@
import { workspace, ExtensionContext, window } from 'vscode';
import {
bootstrap,
FoamConfig,
Logger,
FileDataStore,
Matcher,
MarkdownResourceProvider,
ResourceProvider,
} from 'foam-core';
import { FoamConfig } from './core/config';
import { MarkdownResourceProvider } from './core/markdown-provider';
import { bootstrap } from './core/model/foam';
import { FileDataStore, Matcher } from './core/services/datastore';
import { Logger } from './core/utils/log';
import { features } from './features';
import { getConfigFromVscode } from './services/config';
import { VsCodeOutputLogger, exposeLogger } from './services/logging';
function createMarkdownProvider(config: FoamConfig): ResourceProvider {
function createMarkdownProvider(config: FoamConfig): MarkdownResourceProvider {
const matcher = new Matcher(
config.workspaceFolders,
config.includeGlobs,

View File

@@ -1,16 +1,16 @@
import { workspace, window } from 'vscode';
import { URI, FoamGraph } from 'foam-core';
import { createTestNote, createTestWorkspace } from '../test/test-utils';
import {
cleanWorkspace,
closeEditors,
createNote,
createTestNote,
createTestWorkspace,
} from '../test/test-utils';
} from '../test/test-utils-vscode';
import { BacklinksTreeDataProvider, BacklinkTreeItem } from './backlinks';
import { ResourceTreeItem } from '../utils/grouped-resources-tree-data-provider';
import { OPEN_COMMAND } from './utility-commands';
import { toVsCodeUri } from '../utils/vsc-utils';
import { FoamGraph } from '../core/model/graph';
import { URI } from '../core/model/uri';
describe('Backlinks panel', () => {
beforeAll(async () => {

View File

@@ -1,17 +1,15 @@
import * as vscode from 'vscode';
import { groupBy } from 'lodash';
import {
Foam,
FoamWorkspace,
FoamGraph,
ResourceLink,
Resource,
URI,
Range,
} from 'foam-core';
import { URI } from '../core/model/uri';
import { getNoteTooltip, isNone } from '../utils';
import { FoamFeature } from '../types';
import { ResourceTreeItem } from '../utils/grouped-resources-tree-data-provider';
import { Foam } from '../core/model/foam';
import { FoamWorkspace } from '../core/model/workspace';
import { FoamGraph } from '../core/model/graph';
import { Resource, ResourceLink } from '../core/model/note';
import { Range } from '../core/model/range';
const feature: FoamFeature = {
activate: async (

View File

@@ -7,7 +7,7 @@ import {
} from './create-from-template';
import path from 'path';
import { isWindows } from '../utils';
import { URI } from 'foam-core';
import { URI } from '../core/model/uri';
describe('substituteFoamVariables', () => {
test('Does nothing if no Foam-specific variables are used', () => {

View File

@@ -1,7 +1,8 @@
import { URI } from 'foam-core';
import { URI } from '../core/model/uri';
import path from 'path';
import { toVsCodeUri } from '../utils/vsc-utils';
import { commands, window, workspace } from 'vscode';
describe('createFromTemplate', () => {
describe('create-note-from-template', () => {
afterEach(() => {

View File

@@ -1,4 +1,4 @@
import { URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { existsSync } from 'fs';
import * as path from 'path';
import { isAbsolute } from 'path';

View File

@@ -1,10 +1,12 @@
import * as vscode from 'vscode';
import * as path from 'path';
import { FoamFeature } from '../types';
import { Foam, Logger, URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { TextDecoder } from 'util';
import { getGraphStyle, getTitleMaxLength } from '../settings';
import { isSome } from '../utils';
import { Foam } from '../core/model/foam';
import { Logger } from '../core/utils/log';
const feature: FoamFeature = {
activate: (context: vscode.ExtensionContext, foamPromise: Promise<Foam>) => {

View File

@@ -1,11 +1,14 @@
import { debounce } from 'lodash';
import * as vscode from 'vscode';
import { Foam, FoamWorkspace, ResourceParser, URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { FoamFeature } from '../types';
import {
ConfigurationMonitor,
monitorFoamVsCodeConfig,
} from '../services/config';
import { ResourceParser } from '../core/model/note';
import { FoamWorkspace } from '../core/model/workspace';
import { Foam } from '../core/model/foam';
export const CONFIG_KEY = 'decorations.links.enable';

View File

@@ -1,15 +1,17 @@
import * as vscode from 'vscode';
import { FoamWorkspace, createMarkdownParser, URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { createTestWorkspace } from '../test/test-utils';
import {
cleanWorkspace,
closeEditors,
createFile,
createTestWorkspace,
showInEditor,
} from '../test/test-utils';
} from '../test/test-utils-vscode';
import { LinkProvider } from './document-link-provider';
import { OPEN_COMMAND } from './utility-commands';
import { toVsCodeUri } from '../utils/vsc-utils';
import { createMarkdownParser } from '../core/markdown-provider';
import { FoamWorkspace } from '../core/model/workspace';
describe('Document links provider', () => {
const parser = createMarkdownParser([]);

View File

@@ -1,10 +1,13 @@
import * as vscode from 'vscode';
import { Foam, FoamWorkspace, ResourceParser, URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { FoamFeature } from '../types';
import { mdDocSelector } from '../utils';
import { OPEN_COMMAND } from './utility-commands';
import { toVsCodeRange, toVsCodeUri } from '../utils/vsc-utils';
import { getFoamVsCodeConfig } from '../services/config';
import { Foam } from '../core/model/foam';
import { FoamWorkspace } from '../core/model/workspace';
import { ResourceParser } from '../core/model/note';
const feature: FoamFeature = {
activate: async (

View File

@@ -1,17 +1,17 @@
import * as vscode from 'vscode';
import {
FoamWorkspace,
createMarkdownParser,
Matcher,
MarkdownResourceProvider,
URI,
} from 'foam-core';
} from '../core/markdown-provider';
import { URI } from '../core/model/uri';
import { FoamWorkspace } from '../core/model/workspace';
import { Matcher } from '../core/services/datastore';
import {
cleanWorkspace,
closeEditors,
createFile,
showInEditor,
} from '../test/test-utils';
} from '../test/test-utils-vscode';
import { HoverProvider } from './hover-provider';
describe('Hover provider', () => {

View File

@@ -1,13 +1,16 @@
import * as vscode from 'vscode';
import { Foam, FoamWorkspace, ResourceParser, URI, Range } from 'foam-core';
import { URI } from '../core/model/uri';
import { FoamFeature } from '../types';
import { getNoteTooltip, mdDocSelector, isSome } from '../utils';
import { toVsCodeRange } from '../utils/vsc-utils';
import { ResourceLink } from 'foam-core';
import {
ConfigurationMonitor,
monitorFoamVsCodeConfig,
} from '../services/config';
import { ResourceLink, ResourceParser } from '../core/model/note';
import { Foam } from '../core/model/foam';
import { FoamWorkspace } from '../core/model/workspace';
import { Range } from '../core/model/range';
export const CONFIG_KEY = 'links.hover.enable';

View File

@@ -7,21 +7,18 @@ import {
} from 'vscode';
import * as fs from 'fs';
import { FoamFeature } from '../types';
import {
applyTextEdit,
generateLinkReferences,
generateHeading,
Foam,
Resource,
Range,
URI,
} from 'foam-core';
import { URI } from '../core/model/uri';
import {
getWikilinkDefinitionSetting,
LinkReferenceDefinitionsSetting,
} from '../settings';
import { toVsCodePosition, toVsCodeRange } from '../utils/vsc-utils';
import { Foam } from '../core/model/foam';
import { Resource } from '../core/model/note';
import { generateHeading, generateLinkReferences } from '../core/janitor';
import { Range } from '../core/model/range';
import { applyTextEdit } from '../core/janitor/apply-text-edit';
const feature: FoamFeature = {
activate: (context: ExtensionContext, foamPromise: Promise<Foam>) => {

View File

@@ -1,12 +1,13 @@
import * as vscode from 'vscode';
import { FoamGraph, FoamWorkspace } from 'foam-core';
import { FoamGraph } from '../core/model/graph';
import { FoamWorkspace } from '../core/model/workspace';
import { createTestNote } from '../test/test-utils';
import {
cleanWorkspace,
closeEditors,
createFile,
createTestNote,
showInEditor,
} from '../test/test-utils';
} from '../test/test-utils-vscode';
import { CompletionProvider } from './link-completion';
describe('Link Completion', () => {

View File

@@ -1,5 +1,8 @@
import * as vscode from 'vscode';
import { Foam, FoamWorkspace, URI, FoamGraph } from 'foam-core';
import { Foam } from '../core/model/foam';
import { FoamGraph } from '../core/model/graph';
import { URI } from '../core/model/uri';
import { FoamWorkspace } from '../core/model/workspace';
import { FoamFeature } from '../types';
import { getNoteTooltip, mdDocSelector } from '../utils';
import { toVsCodeUri } from '../utils/vsc-utils';

View File

@@ -1,7 +1,8 @@
import { Foam, URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { ExtensionContext, commands, window } from 'vscode';
import { FoamFeature } from '../types';
import { focusNote } from '../utils';
import { Foam } from '../core/model/foam';
const feature: FoamFeature = {
activate: (context: ExtensionContext, foamPromise: Promise<Foam>) => {

View File

@@ -1,4 +1,4 @@
import { FoamGraph } from 'foam-core';
import { FoamGraph } from '../core/model/graph';
import { createTestNote, createTestWorkspace } from '../test/test-utils';
import { isOrphan } from './orphans';

View File

@@ -1,5 +1,7 @@
import * as vscode from 'vscode';
import { Foam, FoamGraph, URI } from 'foam-core';
import { Foam } from '../core/model/foam';
import { FoamGraph } from '../core/model/graph';
import { URI } from '../core/model/uri';
import { getOrphansConfig } from '../settings';
import { FoamFeature } from '../types';
import {

View File

@@ -1,4 +1,5 @@
import { FoamWorkspace, URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { FoamWorkspace } from '../core/model/workspace';
import { createTestNote } from '../test/test-utils';
import { isPlaceholderResource } from './placeholders';

View File

@@ -1,5 +1,7 @@
import * as vscode from 'vscode';
import { Foam, FoamWorkspace, URI } from 'foam-core';
import { Foam } from '../core/model/foam';
import { URI } from '../core/model/uri';
import { FoamWorkspace } from '../core/model/workspace';
import { getPlaceholdersConfig } from '../settings';
import { FoamFeature } from '../types';
import {

View File

@@ -1,5 +1,6 @@
import MarkdownIt from 'markdown-it';
import { FoamWorkspace, URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { FoamWorkspace } from '../core/model/workspace';
import { createTestNote } from '../test/test-utils';
import {
markdownItWithFoamLinks,

View File

@@ -1,8 +1,11 @@
import { Foam, FoamWorkspace, Logger, URI } from 'foam-core';
import { URI } from '../core/model/uri';
import markdownItRegex from 'markdown-it-regex';
import * as vscode from 'vscode';
import { FoamFeature } from '../types';
import { isNone } from '../utils';
import { Foam } from '../core/model/foam';
import { FoamWorkspace } from '../core/model/workspace';
import { Logger } from '../core/utils/log';
const ALIAS_DIVIDER_CHAR = '|';
const refsStack: string[] = [];

View File

@@ -1,12 +1,13 @@
import * as vscode from 'vscode';
import { FoamTags, FoamWorkspace } from 'foam-core';
import { FoamTags } from '../core/model/tags';
import { FoamWorkspace } from '../core/model/workspace';
import { createTestNote } from '../test/test-utils';
import {
cleanWorkspace,
closeEditors,
createFile,
createTestNote,
showInEditor,
} from '../test/test-utils';
} from '../test/test-utils-vscode';
import { TagCompletionProvider } from './tag-completion';
describe('Tag Completion', () => {

View File

@@ -1,6 +1,6 @@
import { Foam } from 'foam-core';
import { FoamTags } from 'packages/foam-core/src/model/tags';
import * as vscode from 'vscode';
import { Foam } from '../core/model/foam';
import { FoamTags } from '../core/model/tags';
import { FoamFeature } from '../types';
import { mdDocSelector } from '../utils';

View File

@@ -1,20 +1,10 @@
import {
cleanWorkspace,
closeEditors,
createTestNote,
} from '../../test/test-utils';
import { createTestNote } from '../../test/test-utils';
import { cleanWorkspace, closeEditors } from '../../test/test-utils-vscode';
import { TagItem, TagReference, TagsProvider } from '.';
import {
bootstrap,
createConfigFromFolders,
Foam,
FileDataStore,
FoamConfig,
MarkdownResourceProvider,
Matcher,
} from 'foam-core';
import { bootstrap, Foam } from '../../core/model/foam';
import { createConfigFromFolders, FoamConfig } from '../../core/config';
import { MarkdownResourceProvider } from '../../core/markdown-provider';
import { FileDataStore, Matcher } from '../../core/services/datastore';
describe('Tags tree panel', () => {
let _foam: Foam;

View File

@@ -1,8 +1,11 @@
import { Foam, FoamWorkspace, Resource, Tag, URI } from 'foam-core';
import { URI } from '../../core/model/uri';
import * as vscode from 'vscode';
import { FoamFeature } from '../../types';
import { getNoteTooltip, isSome } from '../../utils';
import { toVsCodeRange, toVsCodeUri } from '../../utils/vsc-utils';
import { Foam } from '../../core/model/foam';
import { FoamWorkspace } from '../../core/model/workspace';
import { Resource, Tag } from '../../core/model/note';
const TAG_SEPARATOR = '/';
const feature: FoamFeature = {

View File

@@ -1,7 +1,6 @@
import * as vscode from 'vscode';
import { FoamFeature } from '../types';
import { commands } from 'vscode';
import { URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { toVsCodeUri } from '../utils/vsc-utils';
import { createNoteForPlaceholderWikilink } from './create-from-template';
@@ -47,7 +46,10 @@ export const OPEN_COMMAND = {
const feature: FoamFeature = {
activate: (context: vscode.ExtensionContext) => {
context.subscriptions.push(
commands.registerCommand(OPEN_COMMAND.command, OPEN_COMMAND.execute)
vscode.commands.registerCommand(
OPEN_COMMAND.command,
OPEN_COMMAND.execute
)
);
},
};

View File

@@ -12,15 +12,6 @@ import {
workspace,
Position,
} from 'vscode';
import {
createMarkdownReferences,
stringifyMarkdownLinkReferenceDefinition,
FoamWorkspace,
Foam,
LINK_REFERENCE_DEFINITION_HEADER,
LINK_REFERENCE_DEFINITION_FOOTER,
} from 'foam-core';
import {
hasEmptyTrailing,
docConfig,
@@ -34,6 +25,16 @@ import {
getWikilinkDefinitionSetting,
LinkReferenceDefinitionsSetting,
} from '../settings';
import { Foam } from '../core/model/foam';
import { FoamWorkspace } from '../core/model/workspace';
import {
createMarkdownReferences,
stringifyMarkdownLinkReferenceDefinition,
} from '../core/markdown-provider';
import {
LINK_REFERENCE_DEFINITION_FOOTER,
LINK_REFERENCE_DEFINITION_HEADER,
} from '../core/janitor';
const feature: FoamFeature = {
activate: async (context: ExtensionContext, foamPromise: Promise<Foam>) => {

View File

@@ -1,5 +1,5 @@
import { Disposable, workspace } from 'vscode';
import { FoamConfig, createConfigFromFolders } from 'foam-core';
import { createConfigFromFolders, FoamConfig } from '../core/config';
import { getIgnoredFilesSetting } from '../settings';
// TODO this is still to be improved - foam config should

View File

@@ -1,5 +1,6 @@
import { window, commands, ExtensionContext } from 'vscode';
import { ILogger, IDisposable, LogLevel, BaseLogger } from 'foam-core';
import { IDisposable } from '../core/common/lifecycle';
import { BaseLogger, ILogger, LogLevel } from '../core/utils/log';
import { getFoamLoggerLevel } from '../settings';
export interface VsCodeLogger extends ILogger, IDisposable {

View File

@@ -1,5 +1,5 @@
import { workspace, GlobPattern } from 'vscode';
import { LogLevel } from 'foam-core';
import { LogLevel } from './core/utils/log';
export enum LinkReferenceDefinitionsSetting {
withExtensions = 'withExtensions',

View File

@@ -2,8 +2,18 @@ import * as path from 'path';
import fs from 'fs';
import os from 'os';
import { runTests } from 'vscode-test';
import { runUnit } from './suite-unit';
function parseArgs(): { unit: boolean; e2e: boolean } {
const args = process.argv.slice(2);
const unit = args.length === 0 || args.some(arg => arg === '--unit');
const e2e = args.length === 0 || args.some(arg => arg === '--e2e');
return { unit, e2e };
}
async function main() {
const { unit, e2e } = parseArgs();
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
@@ -11,22 +21,29 @@ async function main() {
// The path to the extension test script
// Passed to --extensionTestsPath
const extensionTestsPath = path.resolve(__dirname, './suite');
if (unit) {
console.log('Running unit tests');
await runUnit();
}
const tmpWorkspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'foam-'));
if (e2e) {
console.log('Running e2e tests');
const extensionTestsPath = path.resolve(__dirname, './suite');
const tmpWorkspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'foam-'));
// Download VS Code, unzip it and run the integration test
await runTests({
extensionDevelopmentPath,
extensionTestsPath,
launchArgs: [tmpWorkspaceDir, '--disable-extensions'],
// Running the tests with vscode 1.53.0 is causing issues in `suite.ts:23`,
// which is causing a stack overflow, possibly due to a recursive callback.
// Also see https://github.com/foambubble/foam/pull/479#issuecomment-774167127
// Forcing the version to 1.52.0 solves the problem.
// TODO: to review, further investigate, and roll back this workaround.
version: '1.52.0',
});
// Download VS Code, unzip it and run the integration test
await runTests({
extensionDevelopmentPath,
extensionTestsPath,
launchArgs: [tmpWorkspaceDir, '--disable-extensions'],
// Running the tests with vscode 1.53.0 is causing issues in `suite.ts:23`,
// which is causing a stack overflow, possibly due to a recursive callback.
// Also see https://github.com/foambubble/foam/pull/479#issuecomment-774167127
// Forcing the version to 1.52.0 solves the problem.
// TODO: to review, further investigate, and roll back this workaround.
version: '1.52.0',
});
}
} catch (err) {
console.error('Failed to run tests');
process.exit(1);

View File

@@ -0,0 +1,57 @@
// Based on https://github.com/svsool/vscode-memo/blob/master/src/test/testRunner.ts
/**
* We use the following convention in Foam:
* - *.test.ts are unit tests
* they might still rely on vscode API and hence will be run in this environment, but
* are fundamentally about testing functions in isolation
* - *.spec.ts are integration tests
* they will make direct use of the vscode API to be invoked as commands, create editors,
* and so on..
*/
import path from 'path';
import { runCLI } from '@jest/core';
const rootDir = path.resolve(__dirname, '../..');
export function runUnit(): Promise<void> {
process.env.FORCE_COLOR = '1';
process.env.NODE_ENV = 'test';
process.env.BABEL_ENV = 'test';
return new Promise(async (resolve, reject) => {
try {
const { results } = await runCLI(
{
rootDir,
roots: ['<rootDir>/src'],
transform: JSON.stringify({ '^.+\\.ts$': 'ts-jest' }),
runInBand: true,
testRegex: '\\.(test)\\.ts$',
setupFiles: ['<rootDir>/src/test/support/jest-setup.ts'],
setupFilesAfterEnv: ['jest-extended'],
globals: JSON.stringify({
'ts-jest': {
tsconfig: path.resolve(rootDir, './tsconfig.json'),
},
}),
testTimeout: 20000,
verbose: false,
silent: false,
colors: true,
} as any,
[rootDir]
);
const failures = results.testResults.reduce(
(acc, res) => (res.failureMessage ? acc + 1 : acc),
0
);
return failures === 0
? resolve()
: reject(`${failures} tests have failed!`);
} catch (error) {
return reject(error);
}
});
}

View File

@@ -9,22 +9,37 @@
* and so on..
*/
import { EOL } from 'os';
import path from 'path';
import { runCLI } from '@jest/core';
const rootDir = path.resolve(__dirname, '../..');
const bufferLinesAndLog = (out: (value: string) => void) => {
let currentLine = '';
return (buffer: string) => {
const lines = buffer.split(EOL);
const partialLine = lines.pop() ?? '';
if (lines.length > 0) {
const [endOfCurrentLine, ...otherFullLines] = lines;
currentLine += endOfCurrentLine;
[currentLine, ...otherFullLines].forEach(l => out(l));
currentLine = '';
}
currentLine += partialLine;
return true;
};
};
export function run(): Promise<void> {
process.stdout.write = (buffer: string) => {
console.log(buffer);
return true;
};
process.stderr.write = (buffer: string) => {
console.error(buffer);
return true;
};
process.stdout.write = bufferLinesAndLog(console.log.bind(console));
process.stderr.write = bufferLinesAndLog(console.error.bind(console));
process.on('unhandledRejection', err => {
throw err;
});
process.env.FORCE_COLOR = '1';
process.env.NODE_ENV = 'test';
process.env.BABEL_ENV = 'test';
return new Promise(async (resolve, reject) => {
try {

View File

@@ -0,0 +1,61 @@
/*
* This file depends on VS Code as it's used for integration/e2e tests
*/
import * as vscode from 'vscode';
import path from 'path';
import { TextEncoder } from 'util';
import { toVsCodeUri } from '../utils/vsc-utils';
import { Logger } from '../core/utils/log';
import { URI } from '../core/model/uri';
import { Resource } from '../core/model/note';
import { randomString, wait } from './test-utils';
Logger.setLevel('error');
export const cleanWorkspace = async () => {
const files = await vscode.workspace.findFiles('**', '.vscode');
await Promise.all(files.map(f => vscode.workspace.fs.delete(f)));
};
export const showInEditor = async (uri: URI) => {
const doc = await vscode.workspace.openTextDocument(toVsCodeUri(uri));
const editor = await vscode.window.showTextDocument(doc);
return { doc, editor };
};
export const closeEditors = async () => {
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
await wait(100);
};
/**
* Creates a file with a some content.
*
* @param content the file content
* @param path relative file path
* @returns an object containing various information about the file created
*/
export const createFile = async (content: string, filepath?: string) => {
const rootUri = vscode.workspace.workspaceFolders[0].uri;
filepath = filepath ?? randomString() + '.md';
const uri = vscode.Uri.joinPath(rootUri, filepath);
const filenameComponents = path.parse(uri.fsPath);
await vscode.workspace.fs.writeFile(uri, new TextEncoder().encode(content));
return { uri, content, ...filenameComponents };
};
export const createNote = (r: Resource) => {
let content = `# ${r.title}
some content and ${r.links
.map(l =>
l.type === 'wikilink' ? `[[${l.label}]]` : `[${l.label}](${l.target})`
)
.join(' some content between links.\n')}
last line.
`;
return vscode.workspace.fs.writeFile(
toVsCodeUri(r.uri),
new TextEncoder().encode(content)
);
};

View File

@@ -1,23 +1,24 @@
// TODO: this file has some utility functions also present in foam-core testing
// they should be consolidated
import * as vscode from 'vscode';
/*
* This file should not depend on VS Code as it's used for unit tests
*/
import path from 'path';
import {
URI,
NoteLinkDefinition,
Resource,
Range,
FoamWorkspace,
Matcher,
MarkdownResourceProvider,
Logger,
} from 'foam-core';
import { TextEncoder } from 'util';
import { toVsCodeUri } from '../utils/vsc-utils';
import { Logger } from '../core/utils/log';
import { Range } from '../core/model/range';
import { URI } from '../core/model/uri';
import { FoamWorkspace } from '../core/model/workspace';
import { Matcher } from '../core/services/datastore';
import { MarkdownResourceProvider } from '../core/markdown-provider';
import { NoteLinkDefinition, Resource } from '../core/model/note';
Logger.setLevel('error');
export const TEST_DATA_DIR = URI.joinPath(
URI.file(__dirname),
'..',
'..',
'test-data'
);
const position = Range.create(0, 0, 0, 100);
const documentStart = position.start;
@@ -96,60 +97,12 @@ export const createTestNote = (params: {
};
};
export const cleanWorkspace = async () => {
const files = await vscode.workspace.findFiles('**', '.vscode');
await Promise.all(files.map(f => vscode.workspace.fs.delete(f)));
};
export const wait = (ms: number) =>
new Promise(resolve => setTimeout(resolve, ms));
export const showInEditor = async (uri: URI) => {
const doc = await vscode.workspace.openTextDocument(toVsCodeUri(uri));
const editor = await vscode.window.showTextDocument(doc);
return { doc, editor };
};
export const closeEditors = async () => {
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
await wait(100);
};
const chars = 'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWYXZ1234567890';
export const randomString = (len = 5) =>
new Array(len)
.fill('')
.map(() => chars.charAt(Math.floor(Math.random() * chars.length)))
.join('');
/**
* Creates a file with a some content.
*
* @param content the file content
* @param path relative file path
* @returns an object containing various information about the file created
*/
export const createFile = async (content: string, filepath?: string) => {
const rootUri = vscode.workspace.workspaceFolders[0].uri;
filepath = filepath ?? randomString() + '.md';
const uri = vscode.Uri.joinPath(rootUri, filepath);
const filenameComponents = path.parse(uri.fsPath);
await vscode.workspace.fs.writeFile(uri, new TextEncoder().encode(content));
return { uri, content, ...filenameComponents };
};
export const createNote = (r: Resource) => {
let content = `# ${r.title}
some content and ${r.links
.map(l =>
l.type === 'wikilink' ? `[[${l.label}]]` : `[${l.label}](${l.target})`
)
.join(' some content between links.\n')}
last line.
`;
return vscode.workspace.fs.writeFile(
toVsCodeUri(r.uri),
new TextEncoder().encode(content)
);
};

View File

@@ -1,5 +1,5 @@
import { Foam } from 'foam-core';
import { ExtensionContext } from 'vscode';
import { Foam } from './core/model/foam';
export interface FoamFeature {
activate: (

View File

@@ -12,11 +12,12 @@ import {
ViewColumn,
} from 'vscode';
import * as fs from 'fs';
import { Logger, URI } from 'foam-core';
import matter from 'gray-matter';
import removeMarkdown from 'remove-markdown';
import os from 'os';
import { toVsCodeUri } from './utils/vsc-utils';
import { Logger } from './core/utils/log';
import { URI } from './core/model/uri';
export const isWindows = os.platform() === 'win32';

View File

@@ -1,4 +1,4 @@
import { FoamWorkspace } from 'foam-core';
import { FoamWorkspace } from '../core/model/workspace';
import { OPEN_COMMAND } from '../features/utility-commands';
import {
GroupedResoucesConfigGroupBy,

View File

@@ -1,6 +1,5 @@
import * as path from 'path';
import * as vscode from 'vscode';
import { URI, FoamWorkspace, Resource } from 'foam-core';
import micromatch from 'micromatch';
import {
GroupedResourcesConfig,
@@ -9,6 +8,9 @@ import {
import { getContainsTooltip, getNoteTooltip, isSome } from '../utils';
import { OPEN_COMMAND } from '../features/utility-commands';
import { toVsCodeUri } from './vsc-utils';
import { URI } from '../core/model/uri';
import { Resource } from '../core/model/note';
import { FoamWorkspace } from '../core/model/workspace';
/**
* Provides the ability to expose a TreeDataExplorerView in VSCode. This class will

View File

@@ -1,6 +1,6 @@
import os from 'os';
import { workspace, Uri } from 'vscode';
import { URI } from 'foam-core';
import { URI } from '../core/model/uri';
import { fromVsCodeUri, toVsCodeUri } from './vsc-utils';
describe('uri conversion', () => {

View File

@@ -1,9 +1,7 @@
import { Position, Range, Uri } from 'vscode';
import {
Position as FoamPosition,
Range as FoamRange,
URI as FoamURI,
} from 'foam-core';
import { Position as FoamPosition } from '../core/model/position';
import { Range as FoamRange } from '../core/model/range';
import { URI as FoamURI } from '../core/model/uri';
export const toVsCodePosition = (p: FoamPosition): Position =>
new Position(p.line, p.character);

Some files were not shown because too many files have changed in this diff Show More