Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Updates #64

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
- name: Compile extension
run: |
yarn install --frozen-lockfile
yarn lint
yarn compile
# Run tests (including a special build of extension w/ tsc, not esbuild)
test:
Expand Down
21 changes: 20 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
"type": "array"
},
"syntaxTree.printWidth": {
"default": 80,
"markdownDescription": "The width to be used when formatting code.",
"type": "number"
},
Expand Down Expand Up @@ -99,6 +98,7 @@
"clean": "rm -rf ./out",
"compile": "yarn run esbuild-base --sourcemap",
"esbuild-base": "esbuild --bundle --external:vscode --external:vscode-languageclient --format=cjs --outfile=out/extension.js --platform=node src/extension.ts",
"lint": "eslint .",
"package": "vsce package --no-yarn --githubBranch main",
"publish": "vsce publish --no-yarn --githubBranch main",
"test": "node ./out/test/runTest.js",
Expand All @@ -115,13 +115,32 @@
"@types/mocha": "^9.1.1",
"@types/node": "^18.0.0",
"@types/vscode": "^1.68.0",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"@vscode/test-electron": "^1.6.2",
"esbuild": "^0.15.0",
"eslint": "^8.22.0",
"glob": "^8.0.3",
"mocha": "^10.0.0",
"typescript": "^4.7.4",
"vsce": "^2.9.2"
},
"eslintConfig": {
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"quotes": ["error", "double"],
"semi": "error"
},
"ignorePatterns": ["out"]
},
"__metadata": {
"id": "b46118f9-0f6f-4320-9e2e-75c96492b4cb",
"publisherDisplayName": "ruby-syntax-tree",
Expand Down
2 changes: 1 addition & 1 deletion src/Visualize.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { commands, Disposable, languages, OutputChannel, ProviderResult, TextDocumentContentProvider, Uri, ViewColumn, window, workspace } from "vscode";
import { Disposable, languages, OutputChannel, ProviderResult, TextDocumentContentProvider, Uri, ViewColumn, window, workspace } from "vscode";
import { LanguageClient } from "vscode-languageclient/node";

class Visualize implements Disposable, TextDocumentContentProvider {
Expand Down
42 changes: 22 additions & 20 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { promisify } from "util";
import { ExtensionContext, commands, window, workspace } from "vscode";
import { LanguageClient, ServerOptions } from "vscode-languageclient/node";

import * as variables from './variables';
import * as variables from "./variables";
import Visualize from "./Visualize";

const promiseExec = promisify(exec);
Expand Down Expand Up @@ -92,7 +92,10 @@ export async function activate(context: ExtensionContext) {
}

// Configure print width.
args.push(`--print-width=${config.get<number>("printWidth")}`)
const printWidth = config.get<number>("printWidth");
if (printWidth) {
args.push(`--print-width=${printWidth}`);
}

// There's a bit of complexity here. Basically, we try to locate
// an stree executable in three places, in order of preference:
Expand All @@ -108,7 +111,7 @@ export async function activate(context: ExtensionContext) {
// Explicit path varies between machines/users and is also victim to the
// oversimplification problem.
let run: ServerOptions = { command: "stree", args };
let commandPath = advancedConfig.get<string>('commandPath');
let commandPath = advancedConfig.get<string>("commandPath");
if (commandPath) {
commandPath = variables.substitute(commandPath);
try {
Expand All @@ -128,7 +131,7 @@ export async function activate(context: ExtensionContext) {
}
}

outputChannel.appendLine(`Starting language server: ${run.command} ${run.args?.join(' ')}`);
outputChannel.appendLine(`Starting language server: ${run.command} ${run.args?.join(" ")}`);

// Here, we instantiate the language client. This is the object that is
// responsible for the communication and management of the Ruby subprocess.
Expand All @@ -147,26 +150,26 @@ export async function activate(context: ExtensionContext) {
// add the various features to the extension. Each of them in turn
// implements Disposable so that they clean up their own resources.
visualizer = new Visualize(languageClient, outputChannel);
context.subscriptions.push(
visualizer
);
} catch (e: any) {
context.subscriptions.push(visualizer);
} catch (error) {
languageClient = null;
const items = ['Restart']
let msg = 'Something went wrong.';
if (typeof e === 'string') {
if (/ENOENT/.test(e)) {
msg = 'Command not found. Is the syntax_tree RubyGem installed?';
items.unshift('Install Gem');

const items = ["Restart"];
let msg = "Something went wrong.";

if (typeof error === "string") {
if (/ENOENT/.test(error)) {
msg = "Command not found. Is the syntax_tree gem installed?";
items.unshift("Install Gem");
}
}

const action = await window.showErrorMessage(msg, ...items);
switch (action) {
case 'Install Gem':
case "Install Gem":
installGem();
break;
case 'Restart':
case "Restart":
startLanguageServer();
break;
}
Expand Down Expand Up @@ -196,12 +199,11 @@ export async function activate(context: ExtensionContext) {
// This function is called when the user wants to recover from ENOENT
// on start. It starts the language server afterward.
async function installGem() {
const cwd = getCWD();
try {
await promiseExec("gem install syntax_tree", { cwd });
await promiseExec("gem install syntax_tree", { cwd: getCWD() });
startLanguageServer();
} catch (e) {
outputChannel.appendLine("Error installing gem: " + e);
} catch (error) {
outputChannel.appendLine(`Error installing gem: ${error}`);
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/test/runTest.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { runTests } from '@vscode/test-electron';
import * as path from 'path';
import { runTests } from "@vscode/test-electron";
import * as path from "path";

import { USER_DATA_DIR, WORKSPACE_DIR } from './suite/setup';
import { USER_DATA_DIR, WORKSPACE_DIR } from "./suite/setup";

async function main() {
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath = path.resolve(__dirname, '../../');
const extensionDevelopmentPath = path.resolve(__dirname, "../../");

// The path to the extension test script
// Passed to --extensionTestsPath
const extensionTestsPath = path.resolve(__dirname, './suite/index');
const extensionTestsPath = path.resolve(__dirname, "./suite/index");

// Download VS Code, unzip it and run the integration test
await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: ['--disable-extensions', '--disable-gpu', '--user-data-dir', USER_DATA_DIR, WORKSPACE_DIR] });
await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: ["--disable-extensions", "--disable-gpu", "--user-data-dir", USER_DATA_DIR, WORKSPACE_DIR] });
} catch (err) {
console.error('Failed to run tests');
console.error("Failed to run tests");
process.exit(1);
}
}
Expand Down
22 changes: 11 additions & 11 deletions src/test/suite/automation.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as assert from 'assert';
import * as path from 'path';
import { TextEncoder } from 'util';
import * as assert from "assert";
import * as path from "path";
import { TextEncoder } from "util";

import { Uri, commands, window, workspace } from 'vscode';
import { Uri, commands, window, workspace } from "vscode";

import { WORKSPACE_DIR } from './setup';
import { WORKSPACE_DIR } from "./setup";

export async function reset() {
await commands.executeCommand('workbench.action.closeAllEditors');
await commands.executeCommand("workbench.action.closeAllEditors");
}

export async function createEditor(content: string) {
Expand All @@ -25,21 +25,21 @@ export function findNewestEditor() {
}

export function formatDocument() {
return commands.executeCommand('editor.action.formatDocument', 'ruby-syntax-tree.vscode-syntax-tree');
return commands.executeCommand("editor.action.formatDocument", "ruby-syntax-tree.vscode-syntax-tree");
}

export function restart() {
return commands.executeCommand('syntaxTree.restart');
return commands.executeCommand("syntaxTree.restart");
}

export function start() {
return commands.executeCommand('syntaxTree.start');
return commands.executeCommand("syntaxTree.start");
}

export function stop() {
return commands.executeCommand('syntaxTree.stop');
return commands.executeCommand("syntaxTree.stop");
}

export function visualize() {
return commands.executeCommand('syntaxTree.visualize');
return commands.executeCommand("syntaxTree.visualize");
}
46 changes: 23 additions & 23 deletions src/test/suite/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as assert from 'assert';
import { before, beforeEach } from 'mocha';
import { State } from 'vscode-languageclient';
import * as assert from "assert";
import { before, beforeEach } from "mocha";
import { State } from "vscode-languageclient";

import * as auto from './automation';
import * as extension from '../../extension';
import * as auto from "./automation";
import * as extension from "../../extension";

const UNFORMATTED = `class Foo; def bar; puts 'baz'; end; end`;
const UNFORMATTED = "class Foo; def bar; puts 'baz'; end; end";

const FORMATTED = `class Foo
def bar
Expand All @@ -14,43 +14,43 @@ const FORMATTED = `class Foo
end
`;

suite('Syntax Tree', () => {
suite("Syntax Tree", () => {
beforeEach(auto.reset);

suite('lifecycle commands', () => {
test('start', async () => {
suite("lifecycle commands", () => {
test("start", async () => {
await auto.start();
assert.notEqual(extension.languageClient, null)
assert.equal(extension.languageClient?.state, State.Running)
assert.notEqual(extension.languageClient, null);
assert.equal(extension.languageClient?.state, State.Running);
});

test('stop', async () => {
test("stop", async () => {
await auto.start();
await auto.stop();
assert.equal(extension.languageClient, null)
})
assert.equal(extension.languageClient, null);
});

test('restart', async () => {
test("restart", async () => {
await auto.restart();
assert.notEqual(extension.languageClient, null)
assert.equal(extension.languageClient?.state, State.Running)
})
assert.notEqual(extension.languageClient, null);
assert.equal(extension.languageClient?.state, State.Running);
});
});

suite('functional commands', () => {
suite("functional commands", () => {
before(auto.start);

test('format', async () => {
test("format", async () => {
const editor = await auto.createEditor(UNFORMATTED);
await auto.formatDocument();
assert.equal(editor.document.getText(), FORMATTED);
});

test('visualize', async () => {
test("visualize", async () => {
await auto.createEditor(UNFORMATTED);
await auto.visualize();
const editor = auto.findNewestEditor();
assert.match(editor.document.getText(), /^\(program/);
})
})
});
});
});
14 changes: 7 additions & 7 deletions src/test/suite/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
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";

import { TIMEOUT_MS } from './setup';
import { TIMEOUT_MS } from "./setup";

export function run(): Promise<void> {
const mocha = new Mocha({
Expand All @@ -11,13 +11,13 @@ export function run(): Promise<void> {
forbidOnly: !!process.env.CI,
slow: TIMEOUT_MS / 4,
timeout: TIMEOUT_MS,
ui: 'tdd'
ui: "tdd"
});

const testsRoot = path.resolve(__dirname, '..');
const testsRoot = path.resolve(__dirname, "..");

return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
glob("**/**.test.js", { cwd: testsRoot }, (err, files) => {
if (err) {
return e(err);
}
Expand Down
12 changes: 6 additions & 6 deletions src/test/suite/setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as fs from "fs";
import * as os from "os";
import * as path from "path";

// Share scratch dir between runner and Code process via clever env trick
const inheritedScratchDir = process.env.RUBY_SYNTAX_TREE_TEST_SCRATCH_DIR;
Expand All @@ -13,13 +13,13 @@ export const TIMEOUT_MS = process.env.CI ? 30000 : 300000;

/// Holds profile, settings, etc - to give us a clean slate every time
/// & avoid polluting developer's real profile
export const USER_DATA_DIR = path.join(SCRATCH_DIR, 'user-data');
export const USER_DATA_DIR = path.join(SCRATCH_DIR, "user-data");

/// Holds text documents that we author during tests.
export const WORKSPACE_DIR = path.join(SCRATCH_DIR, 'workspace');
export const WORKSPACE_DIR = path.join(SCRATCH_DIR, "workspace");

if (!inheritedScratchDir) { // We're the parent; adulting is hard!
fs.mkdirSync(USER_DATA_DIR);
fs.mkdirSync(WORKSPACE_DIR);
console.log('Scratch folder:', SCRATCH_DIR);
console.log("Scratch folder:", SCRATCH_DIR);
}
12 changes: 6 additions & 6 deletions src/variables.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import * as os from 'os';
import * as path from 'path';
import * as os from "os";
import * as path from "path";

const substitution = new RegExp('\\$\\{([^}]*)\\}');
const substitution = new RegExp("\\$\\{([^}]*)\\}");

export function substitute(s: string) {
let match = substitution.exec(s);
while (match) {
const variable = match[1];
switch (variable) {
case 'cwd':
case "cwd":
s = s.replace(match[0], process.cwd());
break;
case 'pathSeparator':
case "pathSeparator":
s = s.replace(match[0], path.sep);
break;
case 'userHome':
case "userHome":
s = s.replace(match[0], os.homedir());
break;
}
Expand Down
Loading