Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
"vitest.nodeEnv": {
"ELECTRON_RUN_AS_NODE": "1"
},
"vitest.nodeExecutable": "node_modules/.bin/electron"
"vitest.nodeExecutable": "node_modules/electron/dist/electron"
}
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@
"type": "commonjs",
"main": "./dist/extension.js",
"scripts": {
"build": "concurrently -g -n webviews,extension \"pnpm build:webviews\" \"node esbuild.mjs\"",
"build:production": "NODE_ENV=production pnpm build",
"build": "concurrently -g -n webviews,extension,compile-tests:integration \"pnpm build:webviews\" \"node esbuild.mjs\" \"pnpm compile-tests:integration\"",
"build:production": "cross-env NODE_ENV=production pnpm build",
"build:webviews": "pnpm -r --filter \"./packages/*\" --parallel build",
"compile-tests:integration": "tsc -p test/integration --outDir out --noCheck",
"format": "prettier --write --cache --cache-strategy content .",
"format:check": "prettier --check --cache --cache-strategy content .",
"lint": "eslint --cache --cache-strategy content .",
"lint:fix": "pnpm lint --fix",
"package": "pnpm build:production && vsce package --no-dependencies",
"package:prerelease": "pnpm build:production && vsce package --pre-release --no-dependencies",
"test": "CI=true ELECTRON_RUN_AS_NODE=1 electron node_modules/vitest/vitest.mjs",
"test:extension": "ELECTRON_RUN_AS_NODE=1 electron node_modules/vitest/vitest.mjs --project extension",
"test:integration": "tsc -p test/integration --outDir out --noCheck && node esbuild.mjs && vscode-test",
"test:webview": "ELECTRON_RUN_AS_NODE=1 electron node_modules/vitest/vitest.mjs --project webview",
"test": "cross-env CI=true ELECTRON_RUN_AS_NODE=1 electron node_modules/vitest/vitest.mjs",
"test:extension": "cross-env ELECTRON_RUN_AS_NODE=1 electron node_modules/vitest/vitest.mjs --project extension",
"test:integration": "pnpm compile-tests:integration && node esbuild.mjs && vscode-test",
"test:webview": "cross-env ELECTRON_RUN_AS_NODE=1 electron node_modules/vitest/vitest.mjs --project webview",
"typecheck": "concurrently -g -n extension,tests,packages \"tsc --noEmit\" \"tsc --noEmit -p test\" \"pnpm typecheck:packages\"",
"typecheck:packages": "pnpm -r --filter \"./packages/*\" --parallel typecheck",
"watch": "concurrently -g -n extension,webviews \"pnpm watch:extension\" \"pnpm watch:webviews\"",
Expand Down Expand Up @@ -609,8 +610,9 @@
"bufferutil": "^4.1.0",
"coder": "catalog:",
"concurrently": "^9.2.1",
"cross-env": "^10.1.0",
"dayjs": "^1.11.20",
"electron": "39.8.1",
"electron": "39.8.5",
"esbuild": "^0.28.0",
"eslint": "^10.2.0",
"eslint-config-prettier": "^10.1.8",
Expand Down
44 changes: 31 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions test/unit/core/cliExec.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import fs from "fs/promises";
import os from "os";
import path from "path";
import { beforeAll, describe, expect, it } from "vitest";

import * as cliExec from "@/core/cliExec";
import { beforeAll, describe, expect, it, vi } from "vitest";

import { MockConfigurationProvider } from "../../mocks/testHelpers";
import { isWindows, writeExecutable } from "../../utils/platform";

import type { CliEnv } from "@/core/cliExec";

// Shim execFile so .js test scripts are run through node cross-platform.
vi.mock("node:child_process", async (importOriginal) => {
const { shimExecFile } = await import("../../utils/platform");
return shimExecFile(await importOriginal());
});

// Import after mock so the module picks up the shimmed execFile.
const cliExec = await import("@/core/cliExec");

describe("cliExec", () => {
const tmp = path.join(os.tmpdir(), "vscode-coder-tests-cliExec");

Expand Down Expand Up @@ -52,12 +59,12 @@

it("throws on invalid JSON output", async () => {
const bin = await writeExecutable(tmp, "ver-bad-json", echoBin("hello"));
await expect(cliExec.version(bin)).rejects.toThrow("Unexpected token");

Check failure on line 62 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron 37)

[extension] test/unit/core/cliExec.test.ts > cliExec > version > throws on invalid JSON output

AssertionError: expected [Function] to throw error including 'Unexpected token' but got '"undefined" is not valid JSON' Expected: "Unexpected token" Received: ""undefined" is not valid JSON" ❯ test/unit/core/cliExec.test.ts:62:38

Check failure on line 62 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron latest)

[extension] test/unit/core/cliExec.test.ts > cliExec > version > throws on invalid JSON output

AssertionError: expected [Function] to throw error including 'Unexpected token' but got '"undefined" is not valid JSON' Expected: "Unexpected token" Received: ""undefined" is not valid JSON" ❯ test/unit/core/cliExec.test.ts:62:38
});

it("throws when JSON has no version field", async () => {
const bin = await writeExecutable(tmp, "ver-no-field", echoBin("{}"));
await expect(cliExec.version(bin)).rejects.toThrow(

Check failure on line 67 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron 37)

[extension] test/unit/core/cliExec.test.ts > cliExec > version > throws when JSON has no version field

AssertionError: expected [Function] to throw error including 'No version found in output' but got '"undefined" is not valid JSON' Expected: "No version found in output" Received: ""undefined" is not valid JSON" ❯ test/unit/core/cliExec.test.ts:67:38

Check failure on line 67 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron latest)

[extension] test/unit/core/cliExec.test.ts > cliExec > version > throws when JSON has no version field

AssertionError: expected [Function] to throw error including 'No version found in output' but got '"undefined" is not valid JSON' Expected: "No version found in output" Received: ""undefined" is not valid JSON" ❯ test/unit/core/cliExec.test.ts:67:38
"No version found in output",
);
});
Expand Down Expand Up @@ -113,7 +120,7 @@
"ver-old-noversion",
oldCliBin("unknown flag: --output", "Coder"),
);
await expect(cliExec.version(bin)).rejects.toThrow("No version found");

Check failure on line 123 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron 37)

[extension] test/unit/core/cliExec.test.ts > cliExec > version > throws when old CLI has no version after Coder prefix

AssertionError: expected [Function] to throw error including 'No version found' but got 'Command failed: /home/runner/.npm/_np…' - Expected + Received - No version found + Command failed: /home/runner/.npm/_npx/af6988d8083aeab2/node_modules/electron/dist/electron /tmp/vscode-coder-tests-cliExec/ver-old-noversion.js version --output json + unknown flag: --output ❯ test/unit/core/cliExec.test.ts:123:38

Check failure on line 123 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron latest)

[extension] test/unit/core/cliExec.test.ts > cliExec > version > throws when old CLI has no version after Coder prefix

AssertionError: expected [Function] to throw error including 'No version found' but got 'Command failed: /home/runner/.npm/_np…' - Expected + Received - No version found + Command failed: /home/runner/.npm/_npx/facb15251ed1dd39/node_modules/electron/dist/electron /tmp/vscode-coder-tests-cliExec/ver-old-noversion.js version --output json + unknown flag: --output ❯ test/unit/core/cliExec.test.ts:123:38
});
});

Expand All @@ -137,7 +144,7 @@
configDir: "/tmp/test-config",
});
const result = await cliExec.speedtest(env, "owner/workspace");
const args = result.trim().split("\n");

Check failure on line 147 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron 37)

[extension] test/unit/core/cliExec.test.ts > cliExec > speedtest > passes global-config auth flags

TypeError: Cannot read properties of undefined (reading 'trim') ❯ test/unit/core/cliExec.test.ts:147:24

Check failure on line 147 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron latest)

[extension] test/unit/core/cliExec.test.ts > cliExec > speedtest > passes global-config auth flags

TypeError: Cannot read properties of undefined (reading 'trim') ❯ test/unit/core/cliExec.test.ts:147:24
expect(args).toEqual([
"--global-config",
"/tmp/test-config",
Expand All @@ -154,7 +161,7 @@
url: "http://localhost:3000",
});
const result = await cliExec.speedtest(env, "owner/workspace");
const args = result.trim().split("\n");

Check failure on line 164 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron 37)

[extension] test/unit/core/cliExec.test.ts > cliExec > speedtest > passes url auth flags

TypeError: Cannot read properties of undefined (reading 'trim') ❯ test/unit/core/cliExec.test.ts:164:24

Check failure on line 164 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron latest)

[extension] test/unit/core/cliExec.test.ts > cliExec > speedtest > passes url auth flags

TypeError: Cannot read properties of undefined (reading 'trim') ❯ test/unit/core/cliExec.test.ts:164:24
expect(args).toEqual([
"--url",
"http://localhost:3000",
Expand All @@ -171,7 +178,7 @@
url: "http://localhost:3000",
});
const result = await cliExec.speedtest(env, "owner/workspace", "10s");
const args = result.trim().split("\n");

Check failure on line 181 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron 37)

[extension] test/unit/core/cliExec.test.ts > cliExec > speedtest > passes duration flag

TypeError: Cannot read properties of undefined (reading 'trim') ❯ test/unit/core/cliExec.test.ts:181:24

Check failure on line 181 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron latest)

[extension] test/unit/core/cliExec.test.ts > cliExec > speedtest > passes duration flag

TypeError: Cannot read properties of undefined (reading 'trim') ❯ test/unit/core/cliExec.test.ts:181:24
expect(args).toEqual([
"--url",
"http://localhost:3000",
Expand All @@ -191,7 +198,7 @@
});
configs.set("coder.headerCommand", "my-header-cmd");
const result = await cliExec.speedtest(env, "owner/workspace");
const args = result.trim().split("\n");

Check failure on line 201 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron 37)

[extension] test/unit/core/cliExec.test.ts > cliExec > speedtest > passes header command

TypeError: Cannot read properties of undefined (reading 'trim') ❯ test/unit/core/cliExec.test.ts:201:24

Check failure on line 201 in test/unit/core/cliExec.test.ts

View workflow job for this annotation

GitHub Actions / Unit Test (Electron latest)

[extension] test/unit/core/cliExec.test.ts > cliExec > speedtest > passes header command

TypeError: Cannot read properties of undefined (reading 'trim') ❯ test/unit/core/cliExec.test.ts:201:24
expect(args).toContain("--header-command");
});

Expand Down
13 changes: 8 additions & 5 deletions test/unit/remote/sshProcess.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import find from "find-process";
import { vol } from "memfs";
import * as fsPromises from "node:fs/promises";
import path from "node:path";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

import {
Expand Down Expand Up @@ -313,8 +314,10 @@ describe("SshProcessMonitor", () => {
});
const logPath = await waitForEvent(monitor.onLogFilePathChange);

expect(logPath).toBe("/proxy-logs/999.log");
expect(monitor.getLogFilePath()).toBe("/proxy-logs/999.log");
expect(logPath).toBe(path.join("/proxy-logs", "999.log"));
expect(monitor.getLogFilePath()).toBe(
path.join("/proxy-logs", "999.log"),
);
});

it("finds log file with prefix pattern", async () => {
Expand All @@ -330,7 +333,7 @@ describe("SshProcessMonitor", () => {
});
const logPath = await waitForEvent(monitor.onLogFilePathChange);

expect(logPath).toBe("/proxy-logs/coder-ssh-999.log");
expect(logPath).toBe(path.join("/proxy-logs", "coder-ssh-999.log"));
});

it("returns undefined when no proxyLogDir set", async () => {
Expand Down Expand Up @@ -373,7 +376,7 @@ describe("SshProcessMonitor", () => {
});
const logPath = await waitForEvent(monitor.onLogFilePathChange);

expect(logPath).toBe("/proxy-logs/2024-01-03-999.log");
expect(logPath).toBe(path.join("/proxy-logs", "2024-01-03-999.log"));
});

it("sorts log files using localeCompare for consistent cross-platform ordering", async () => {
Expand All @@ -395,7 +398,7 @@ describe("SshProcessMonitor", () => {

// With localeCompare: ["a", "Z"] -> reversed -> "Z" first
// With plain sort(): ["Z", "a"] -> reversed -> "a" first (WRONG)
expect(logPath).toBe("/proxy-logs/Z-999.log");
expect(logPath).toBe(path.join("/proxy-logs", "Z-999.log"));
});
});

Expand Down
Loading
Loading