Skip to content

Commit 67e85e6

Browse files
authored
Refactor test structure, improve linting, and enhance code organization (#594)
This refactor reorganizes the test layout, strengthens linting configuration, and introduces path aliases in tests to improve code maintainability. Test Structure Changes: - Move tests from /src to top-level /test directory - /test/unit: unit tests with mocks - /test/integration: end-to-end tests with real VS Code API - /test/mocks: shared mocks - /test/fixtures: relocated from /fixtures - /test/utils: various test utils - Prevent test file imports in src - Unify fixture path resolution Development Tooling: - Configure ESLint and TypeScript "fix on save" in VS Code - Update ESLint-related dependencies - Address multiple ESLint rule violations (imports, typing) Code Organization: - Add path aliases for tests (@ → /src) - Introduce ServiceContainer to initialize and track services in src/core - Improve .vscodeignore to ship only necessary files
1 parent 9232981 commit 67e85e6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1584
-595
lines changed

.eslintrc.json

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"parserOptions": {
55
"ecmaVersion": 6,
66
"sourceType": "module",
7-
"project": "./tsconfig.json"
7+
"project": true
88
},
9-
"plugins": ["@typescript-eslint", "prettier"],
9+
"plugins": ["@typescript-eslint", "prettier", "import"],
1010
"extends": [
1111
"eslint:recommended",
1212
"plugin:@typescript-eslint/recommended",
@@ -15,12 +15,38 @@
1515
"plugin:md/prettier",
1616
"prettier"
1717
],
18+
"ignorePatterns": ["out", "dist", "**/*.d.ts"],
19+
"settings": {
20+
"import/resolver": {
21+
"typescript": { "project": "./tsconfig.json" }
22+
},
23+
"import/internal-regex": "^@/"
24+
},
1825
"overrides": [
26+
{
27+
"files": ["test/**/*.{ts,tsx}", "**/*.{test,spec}.ts?(x)"],
28+
"settings": {
29+
"import/resolver": {
30+
"typescript": {
31+
// In tests, resolve using the test tsconfig
32+
"project": "test/tsconfig.json"
33+
}
34+
}
35+
}
36+
},
1937
{
2038
"files": ["*.ts"],
2139
"rules": {
2240
"require-await": "off",
23-
"@typescript-eslint/require-await": "error"
41+
"@typescript-eslint/require-await": "error",
42+
"@typescript-eslint/consistent-type-imports": [
43+
"error",
44+
{
45+
"disallowTypeAnnotations": false, // Used in tests
46+
"prefer": "type-imports",
47+
"fixStyle": "inline-type-imports"
48+
}
49+
]
2450
}
2551
},
2652
{
@@ -42,12 +68,25 @@
4268
"import/order": [
4369
"error",
4470
{
45-
"alphabetize": {
46-
"order": "asc"
47-
},
48-
"groups": [["builtin", "external", "internal"], "parent", "sibling"]
71+
"groups": [
72+
["builtin", "external"],
73+
"internal",
74+
"parent",
75+
["sibling", "index"],
76+
"type"
77+
],
78+
"pathGroups": [
79+
{ "pattern": "@/**", "group": "internal", "position": "before" }
80+
],
81+
"pathGroupsExcludedImportTypes": ["builtin", "external"],
82+
"newlines-between": "always",
83+
"alphabetize": { "order": "asc", "caseInsensitive": true },
84+
"sortTypesGroup": true
4985
}
5086
],
87+
// Prevent duplicates and prefer merging into a single import
88+
"no-duplicate-imports": "off",
89+
"import/no-duplicates": ["error", { "prefer-inline": true }],
5190
"import/no-unresolved": [
5291
"error",
5392
{
@@ -68,6 +107,5 @@
68107
}
69108
}
70109
]
71-
},
72-
"ignorePatterns": ["out", "dist", "**/*.d.ts"]
110+
}
73111
}

.vscode-test.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig } from "@vscode/test-cli";
22

33
export default defineConfig({
4-
files: "out/test/**/*.test.js",
4+
files: "out/test/integration/**/*.test.js",
55
extensionDevelopmentPath: ".",
66
extensionTestsPath: "./out/test",
77
launchArgs: ["--enable-proposed-api", "coder.coder-remote"],

.vscode/settings.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"editor.formatOnSave": true,
3+
"editor.codeActionsOnSave": {
4+
"source.fixAll.ts": "explicit",
5+
"source.fixAll.eslint": "explicit"
6+
},
7+
"editor.defaultFormatter": "esbenp.prettier-vscode",
8+
"[json]": {
9+
"editor.defaultFormatter": "esbenp.prettier-vscode"
10+
},
11+
"[jsonc]": {
12+
"editor.defaultFormatter": "esbenp.prettier-vscode"
13+
}
14+
}

.vscodeignore

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,42 @@
1-
.vscode/**
2-
.vscode-test/**
3-
.nyc_output/**
4-
coverage/**
1+
# Test and coverage output
52
out/**
3+
coverage/**
4+
.nyc_output/**
5+
6+
# Development files
67
src/**
7-
usage.md
8-
.gitignore
9-
node_modules/**
10-
**/tsconfig.json
11-
**/.eslintrc.json
12-
**/.editorconfig
13-
**/*.map
8+
test/**
149
**/*.ts
10+
**/*.map
11+
12+
# Configuration files
13+
.vscode/**
14+
.vscode-test/**
15+
.vscode-test.mjs
16+
tsconfig.json
17+
.eslintrc.json
18+
.editorconfig
19+
.prettierignore
20+
.eslintignore
21+
**/.gitignore
22+
**/.git-blame-ignore-revs
23+
24+
# Package manager files
25+
yarn.lock
26+
27+
# Nix/flake files
28+
flake.nix
29+
flake.lock
30+
*.nix
31+
32+
# Dependencies
33+
node_modules/**
34+
35+
# Development tools and CI
36+
.github/**
37+
.claude/**
38+
39+
# Documentation and media
40+
usage.md
41+
CLAUDE.md
1542
*.gif
16-
fixtures/**

package.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,11 +330,12 @@
330330
"@types/glob": "^7.1.3",
331331
"@types/node": "^22.14.1",
332332
"@types/node-forge": "^1.3.14",
333+
"@types/semver": "^7.7.1",
333334
"@types/ua-parser-js": "0.7.36",
334335
"@types/vscode": "^1.73.0",
335336
"@types/ws": "^8.18.1",
336-
"@typescript-eslint/eslint-plugin": "^7.0.0",
337-
"@typescript-eslint/parser": "^6.21.0",
337+
"@typescript-eslint/eslint-plugin": "^8.44.0",
338+
"@typescript-eslint/parser": "^8.44.0",
338339
"@vitest/coverage-v8": "^3.2.4",
339340
"@vscode/test-cli": "^0.0.11",
340341
"@vscode/test-electron": "^2.5.2",
@@ -343,13 +344,15 @@
343344
"coder": "https://github.com/coder/coder#main",
344345
"dayjs": "^1.11.13",
345346
"eslint": "^8.57.1",
346-
"eslint-config-prettier": "^9.1.0",
347-
"eslint-plugin-import": "^2.31.0",
347+
"eslint-config-prettier": "^10.1.8",
348+
"eslint-import-resolver-typescript": "^4.4.4",
349+
"eslint-plugin-import": "^2.32.0",
348350
"eslint-plugin-md": "^1.0.19",
349351
"eslint-plugin-package-json": "^0.56.3",
350352
"eslint-plugin-prettier": "^5.5.4",
351353
"glob": "^10.4.2",
352354
"jsonc-eslint-parser": "^2.4.0",
355+
"markdown-eslint-parser": "^1.2.1",
353356
"memfs": "^4.47.0",
354357
"nyc": "^17.1.0",
355358
"prettier": "^3.5.3",

src/agentMetadataHelper.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { WorkspaceAgent } from "coder/site/src/api/typesGenerated";
1+
import { type WorkspaceAgent } from "coder/site/src/api/typesGenerated";
22
import * as vscode from "vscode";
3+
34
import {
4-
AgentMetadataEvent,
5+
type AgentMetadataEvent,
56
AgentMetadataEventSchemaArray,
67
errToStr,
78
} from "./api/api-helper";
8-
import { CoderApi } from "./api/coderApi";
9+
import { type CoderApi } from "./api/coderApi";
910

1011
export type AgentMetadataWatcher = {
1112
onChange: vscode.EventEmitter<null>["event"];

src/api/api-helper.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { isApiError, isApiErrorResponse } from "coder/site/src/api/errors";
22
import {
3-
Workspace,
4-
WorkspaceAgent,
5-
WorkspaceResource,
3+
type Workspace,
4+
type WorkspaceAgent,
5+
type WorkspaceResource,
66
} from "coder/site/src/api/typesGenerated";
77
import { ErrorEvent } from "eventsource";
88
import { z } from "zod";

src/api/coderApi.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import { AxiosInstance } from "axios";
1+
import { type AxiosInstance } from "axios";
22
import { Api } from "coder/site/src/api/api";
33
import {
4-
GetInboxNotificationResponse,
5-
ProvisionerJobLog,
6-
ServerSentEvent,
7-
Workspace,
8-
WorkspaceAgent,
4+
type GetInboxNotificationResponse,
5+
type ProvisionerJobLog,
6+
type ServerSentEvent,
7+
type Workspace,
8+
type WorkspaceAgent,
99
} from "coder/site/src/api/typesGenerated";
1010
import { type WorkspaceConfiguration } from "vscode";
11-
import { ClientOptions } from "ws";
11+
import { type ClientOptions } from "ws";
12+
1213
import { CertificateError } from "../error";
1314
import { getHeaderCommand, getHeaders } from "../headers";
1415
import {
@@ -17,13 +18,17 @@ import {
1718
logError,
1819
logResponse,
1920
} from "../logging/httpLogger";
20-
import { Logger } from "../logging/logger";
21-
import { RequestConfigWithMeta, HttpClientLogLevel } from "../logging/types";
21+
import { type Logger } from "../logging/logger";
22+
import {
23+
type RequestConfigWithMeta,
24+
HttpClientLogLevel,
25+
} from "../logging/types";
2226
import { WsLogger } from "../logging/wsLogger";
2327
import {
2428
OneWayWebSocket,
25-
OneWayWebSocketInit,
29+
type OneWayWebSocketInit,
2630
} from "../websocket/oneWayWebSocket";
31+
2732
import { createHttpAgent } from "./utils";
2833

2934
const coderSessionTokenHeader = "Coder-Session-Token";
File renamed without changes.

src/api/utils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import fs from "fs";
22
import { ProxyAgent } from "proxy-agent";
33
import { type WorkspaceConfiguration } from "vscode";
4-
import { getProxyForUrl } from "../proxy";
4+
55
import { expandPath } from "../util";
66

7+
import { getProxyForUrl } from "./proxy";
8+
79
/**
810
* Return whether the API will need a token for authorization.
911
* If mTLS is in use (as specified by the cert or key files being set) then

0 commit comments

Comments
 (0)