Skip to content

Commit

Permalink
Improve client integration tests (#2033)
Browse files Browse the repository at this point in the history
* Ensure RubyInstaller is retrieving the right PATH

* Improve integration tests to activate the current Ruby
  • Loading branch information
vinistock authored May 29, 2024
1 parent 3266647 commit d993c5e
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 18 deletions.
12 changes: 10 additions & 2 deletions vscode/src/ruby/chruby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export class Chruby extends VersionManager {
async activate(): Promise<ActivationResult> {
const versionInfo = await this.discoverRubyVersion();
const rubyUri = await this.findRubyUri(versionInfo);
this.outputChannel.info(
`Discovered Ruby installation at ${rubyUri.fsPath}`,
);

const { defaultGems, gemHome, yjit, version } =
await this.runActivationScript(rubyUri);

Expand All @@ -56,7 +60,7 @@ export class Chruby extends VersionManager {
PATH: `${path.join(gemHome, "bin")}${path.delimiter}${path.join(
defaultGems,
"bin",
)}${path.delimiter}${path.dirname(rubyUri.fsPath)}${path.delimiter}${process.env.PATH}`,
)}${path.delimiter}${path.dirname(rubyUri.fsPath)}${path.delimiter}${this.getProcessPath()}`,
};

return {
Expand All @@ -66,6 +70,10 @@ export class Chruby extends VersionManager {
};
}

protected getProcessPath() {
return process.env.PATH;
}

// Returns the full URI to the Ruby executable
protected async findRubyUri(rubyVersion: RubyVersion): Promise<vscode.Uri> {
if (/\d+\.\d+\.\d+/.exec(rubyVersion.version)) {
Expand Down Expand Up @@ -168,7 +176,7 @@ export class Chruby extends VersionManager {
}

this.outputChannel.info(
`Discovered Ruby version ${version} from ${rubyVersionUri.toString()}`,
`Discovered Ruby version ${version} from ${rubyVersionUri.fsPath}`,
);
return { engine: match.groups.engine, version: match.groups.version };
}
Expand Down
7 changes: 7 additions & 0 deletions vscode/src/ruby/rubyInstaller.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-process-env */
import os from "os";

import * as vscode from "vscode";
Expand All @@ -16,6 +17,12 @@ interface RubyVersion {
//
// If we can't find it there, then we throw an error and rely on the user to manually select where Ruby is installed.
export class RubyInstaller extends Chruby {
// Environment variables are case sensitive on Windows when we access them through NodeJS. We need to ensure that
// we're searching through common variations, so that we don't accidentally miss the path we should inherit
protected getProcessPath() {
return process.env.Path ?? process.env.PATH ?? process.env.path;
}

// Returns the full URI to the Ruby executable
protected async findRubyUri(rubyVersion: RubyVersion): Promise<vscode.Uri> {
const [major, minor, _patch] = rubyVersion.version.split(".").map(Number);
Expand Down
130 changes: 114 additions & 16 deletions vscode/src/test/suite/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as assert from "assert";
import * as path from "path";
/* eslint-disable no-process-env */
import assert from "assert";
import path from "path";
import os from "os";
import fs from "fs";

import * as vscode from "vscode";
import {
Expand All @@ -25,8 +27,42 @@ import { after, afterEach, before } from "mocha";
import { Ruby, ManagerIdentifier } from "../../ruby";
import { Telemetry, TelemetryApi, TelemetryEvent } from "../../telemetry";
import Client from "../../client";
import { LOG_CHANNEL } from "../../common";
import { WorkspaceChannel } from "../../workspaceChannel";
import { RUBY_VERSION } from "../rubyVersion";

const [major, minor, _patch] = RUBY_VERSION.split(".");

class FakeLogger {
receivedMessages = "";

trace(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

debug(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

info(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

warn(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

error(error: string | Error, ..._args: any[]): void {
this.receivedMessages += error.toString();
}

append(value: string): void {
this.receivedMessages += value;
}

appendLine(value: string): void {
this.receivedMessages += value;
}
}

class FakeApi implements TelemetryApi {
public sentEvents: TelemetryEvent[];
Expand Down Expand Up @@ -56,7 +92,61 @@ async function launchClient(workspaceUri: vscode.Uri) {
update: (_name: string, _value: any) => Promise.resolve(),
},
} as unknown as vscode.ExtensionContext;
const outputChannel = new WorkspaceChannel("fake", LOG_CHANNEL);
const fakeLogger = new FakeLogger();
const outputChannel = new WorkspaceChannel("fake", fakeLogger as any);

// Ensure that we're activating the correct Ruby version on CI
if (process.env.CI) {
if (os.platform() === "linux") {
await vscode.workspace
.getConfiguration("rubyLsp")
.update(
"rubyVersionManager",
{ identifier: ManagerIdentifier.Chruby },
true,
);

fs.mkdirSync(path.join(os.homedir(), ".rubies"), { recursive: true });
fs.symlinkSync(
`/opt/hostedtoolcache/Ruby/${RUBY_VERSION}/x64`,
path.join(os.homedir(), ".rubies", RUBY_VERSION),
);
} else if (os.platform() === "darwin") {
await vscode.workspace
.getConfiguration("rubyLsp")
.update(
"rubyVersionManager",
{ identifier: ManagerIdentifier.Chruby },
true,
);

fs.mkdirSync(path.join(os.homedir(), ".rubies"), { recursive: true });
fs.symlinkSync(
`/Users/runner/hostedtoolcache/Ruby/${RUBY_VERSION}/arm64`,
path.join(os.homedir(), ".rubies", RUBY_VERSION),
);
} else {
await vscode.workspace
.getConfiguration("rubyLsp")
.update(
"rubyVersionManager",
{ identifier: ManagerIdentifier.RubyInstaller },
true,
);

fs.symlinkSync(
path.join(
"C:",
"hostedtoolcache",
"windows",
"Ruby",
RUBY_VERSION,
"x64",
),
path.join("C:", `Ruby${major}${minor}-${os.arch()}`),
);
}
}

const ruby = new Ruby(context, workspaceFolder, outputChannel);
await ruby.activateRuby();
Expand All @@ -72,6 +162,12 @@ async function launchClient(workspaceUri: vscode.Uri) {
outputChannel,
);

client.clientOptions.initializationFailedHandler = (error) => {
assert.fail(
`Failed to start server ${error.message}\n${fakeLogger.receivedMessages}`,
);
};

try {
await client.start();
} catch (error: any) {
Expand Down Expand Up @@ -113,18 +209,6 @@ suite("Client", () => {

// eslint-disable-next-line no-invalid-this
this.timeout(90000);

// eslint-disable-next-line no-process-env
if (process.env.CI) {
await vscode.workspace
.getConfiguration("rubyLsp")
.update(
"rubyVersionManager",
{ identifier: ManagerIdentifier.None },
true,
true,
);
}
client = await launchClient(workspaceUri);
});

Expand All @@ -138,6 +222,20 @@ suite("Client", () => {
} catch (error: any) {
assert.fail(`Failed to stop server: ${error.message}`);
}

if (process.env.CI) {
if (os.platform() === "linux" || os.platform() === "darwin") {
fs.rmSync(path.join(os.homedir(), ".rubies"), {
recursive: true,
force: true,
});
} else {
fs.rmSync(path.join("C:", `Ruby${major}${minor}-${os.arch()}`), {
recursive: true,
force: true,
});
}
}
});

afterEach(async () => {
Expand Down

0 comments on commit d993c5e

Please sign in to comment.