Skip to content
This repository has been archived by the owner on May 30, 2024. It is now read-only.

Commit

Permalink
Add client start test
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Jul 25, 2023
1 parent 1eb4590 commit 1a861f7
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 35 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ jobs:
with:
ruby-version: "3.2"

# These are needed to test booting the server
- name: Install server boot dependencies
run: gem install ruby-lsp debug

- name: 📦 Install dependencies
run: yarn --frozen-lockfile

Expand Down
32 changes: 20 additions & 12 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ export default class Client implements ClientInterface {
telemetry: Telemetry,
ruby: Ruby,
testController: TestController,
workingFolder = vscode.workspace.workspaceFolders![0].uri.fsPath,
) {
this.workingFolder = vscode.workspace.workspaceFolders![0].uri.fsPath;
this.workingFolder = workingFolder;
this.telemetry = telemetry;
this.testController = testController;
this.#context = context;
Expand All @@ -56,26 +57,28 @@ export default class Client implements ClientInterface {
this.registerAutoRestarts();
}

async start() {
async start(runServerInstall = true) {
if (this.ruby.error) {
this.state = ServerState.Error;
return;
}

this.state = ServerState.Starting;

try {
await this.installOrUpdateServer();
} catch (error: any) {
this.state = ServerState.Error;
if (runServerInstall) {
try {
await this.installOrUpdateServer();
} catch (error: any) {
this.state = ServerState.Error;

// The progress dialog can't be closed by the user, so we have to guarantee that we catch errors
vscode.window.showErrorMessage(
`Failed to setup the bundle: ${error.message}. \
// The progress dialog can't be closed by the user, so we have to guarantee that we catch errors
vscode.window.showErrorMessage(
`Failed to setup the bundle: ${error.message}. \
See [Troubleshooting](https://github.com/Shopify/vscode-ruby-lsp#troubleshooting) for instructions`,
);
);

return;
return;
}
}

const executableOptions = {
Expand Down Expand Up @@ -211,7 +214,12 @@ export default class Client implements ClientInterface {
}
});

await this.client.start();
try {
await this.client.start();
} catch (error: any) {
// eslint-disable-next-line no-console
console.log(error.message);
}

// We cannot inquire anything related to the bundle before the custom bundle logic in the server runs
await this.determineFormatter();
Expand Down
46 changes: 23 additions & 23 deletions src/ruby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ export class Ruby {
}

private async activateChruby() {
const rubyVersion = await this.readRubyVersion();
await this.activate(`chruby "${rubyVersion}" && ruby`);
// const _rubyVersion = await this.readRubyVersion();
await this.activate(`chruby "3.2.2" && ruby`);
}

private async activate(ruby: string) {
Expand Down Expand Up @@ -217,34 +217,34 @@ export class Ruby {
this._env.BUNDLE_GEMFILE = absoluteBundlePath;
}

private async readRubyVersion() {
let dir = this.workingFolder;
// private async readRubyVersion() {
// let dir = this.workingFolder;

while (fs.existsSync(dir)) {
const versionFile = path.join(dir, ".ruby-version");
// while (fs.existsSync(dir)) {
// const versionFile = path.join(dir, ".ruby-version");

if (fs.existsSync(versionFile)) {
const version = fs.readFileSync(versionFile, "utf8");
const trimmedVersion = version.trim();
// if (fs.existsSync(versionFile)) {
// const version = fs.readFileSync(versionFile, "utf8");
// const trimmedVersion = version.trim();

if (trimmedVersion !== "") {
return trimmedVersion;
}
}
// if (trimmedVersion !== "") {
// return trimmedVersion;
// }
// }

const parent = path.dirname(dir);
// const parent = path.dirname(dir);

// When we hit the root path (e.g. /), parent will be the same as dir.
// We don't want to loop forever in this case, so we break out of the loop.
if (parent === dir) {
break;
}
// // When we hit the root path (e.g. /), parent will be the same as dir.
// // We don't want to loop forever in this case, so we break out of the loop.
// if (parent === dir) {
// break;
// }

dir = parent;
}
// dir = parent;
// }

throw new Error("No .ruby-version file was found");
}
// throw new Error("No .ruby-version file was found");
// }

private async discoverVersionManager() {
// For shadowenv, it wouldn't be enough to check for the executable's existence. We need to check if the project has
Expand Down
122 changes: 122 additions & 0 deletions src/test/suite/client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import * as assert from "assert";
import * as fs from "fs";
import * as path from "path";
import * as os from "os";

import { beforeEach, afterEach } from "mocha";
import * as vscode from "vscode";

import { Ruby } from "../../ruby";
import { Telemetry, TelemetryApi, TelemetryEvent } from "../../telemetry";
import { TestController } from "../../testController";
import { ServerState } from "../../status";
import Client from "../../client";

class FakeApi implements TelemetryApi {
public sentEvents: TelemetryEvent[];

constructor() {
this.sentEvents = [];
}

async sendEvent(event: TelemetryEvent): Promise<void> {
this.sentEvents.push(event);
}
}

suite("Client", () => {
let client: Client;
let testController: TestController;
const managerConfig = vscode.workspace.getConfiguration("rubyLsp");
const currentManager = managerConfig.get("rubyVersionManager");
const tmpPath = fs.mkdtempSync(path.join(os.tmpdir(), "ruby-lsp-test-"));

beforeEach(async () => {
fs.writeFileSync(
`${tmpPath}/Gemfile`,
'source "https://rubygems.org"\ngem "ruby-lsp"\ngem "debug", platforms: :mri',
);
fs.writeFileSync(
`${tmpPath}/Gemfile.lock`,
`
GEM
remote: https://rubygems.org/
specs:
debug (1.8.0)
irb (>= 1.5.0)
reline (>= 0.3.1)
io-console (0.6.0)
irb (1.7.4)
reline (>= 0.3.6)
language_server-protocol (3.17.0.3)
prettier_print (1.2.1)
reline (0.3.6)
io-console (~> 0.5)
ruby-lsp (0.4.3)
language_server-protocol (~> 3.17.0)
sorbet-runtime
syntax_tree (>= 6.1.1, < 7)
sorbet-runtime (0.5.10741)
syntax_tree (6.1.1)
prettier_print (>= 1.2.0)
PLATFORMS
arm64-darwin-22
DEPENDENCIES
debug
ruby-lsp
BUNDLED WITH
2.4.10
`,
);
});

afterEach(async () => {
if (client) {
await client.stop();
}

if (testController) {
testController.dispose();
}

managerConfig.update("rubyVersionManager", currentManager, true, true);
fs.rmSync(tmpPath, { recursive: true, force: true });
});

test("Starting up the server succeeds", async () => {
// await managerConfig.update("rubyVersionManager", "none", true, true);
const context = {
extensionMode: vscode.ExtensionMode.Test,
subscriptions: [],
workspaceState: {
get: (_name: string) => undefined,
update: (_name: string, _value: any) => Promise.resolve(),
},
} as unknown as vscode.ExtensionContext;

const ruby = new Ruby(context, tmpPath);
await ruby.activateRuby();

const telemetry = new Telemetry(context, new FakeApi());

const testController = new TestController(
context,
tmpPath,
ruby,
telemetry,
);

const client = new Client(
context,
telemetry,
ruby,
testController,
tmpPath,
);
await client.start(false);
assert.strictEqual(client.state, ServerState.Running);
}).timeout(10000);
});

0 comments on commit 1a861f7

Please sign in to comment.