|
1 | 1 | #Coder Extension Development Guidelines
|
2 | 2 |
|
3 |
| -General instructions: |
| 3 | +##Core Philosophy |
4 | 4 |
|
5 |
| -Your goal is to help me arrive at the most elegant and effective solution by combining two modes of thinking: 1.First-PrinciplesDeconstruction: Act like a physicist. Break down my ideas, plans, or questions to their most fundamental truths. Aggressively questionevery assumptionuntil only the core, undeniable components remain. Do not accept my premises at face value. 2. Pragmatic Reconstruction (KISS): Act like an engineer. From those fundamental truths,build the simplest, most direct solution possible. If there's a straight line,point to it. Reject any complexity that doesn't directly serve a core requirement. Always present your counter-arguments and alternative solutions through this lens. |
| 5 | +**First-Principles+ KISS**: Questionevery assumptionaggressively, thenbuild the simplest solution from fundamental truths. If there's a straight line,take it, otherwise ask questions and gather any information necessary to determine the right path forward. |
6 | 6 |
|
7 |
| -##Build and TestCommands |
| 7 | +##Commands |
8 | 8 |
|
9 |
| -- Build:`yarn build` |
10 |
| -- Watch mode:`yarn watch` |
11 |
| -- Package:`yarn package` |
12 |
| -- Lint with auto-fix:`yarn lint:fix` (always use this instead of regular lint) |
13 |
| --**Run all unit tests with coverage:`yarn test:ci --coverage`** (ALWAYS use this, not individual file testing) |
14 |
| -- Integration tests:`yarn pretest; yarn test:integration` |
15 |
| -- Full test suite:`yarn test:ci --coverage && yarn pretest && yarn test:integration` |
16 |
| - |
17 |
| -##Code Style Guidelines |
18 |
| - |
19 |
| -- TypeScript with strict typing |
20 |
| -- No semicolons (see`.prettierrc`) |
21 |
| -- Trailing commas for all multi-line lists |
22 |
| -- 120 character line width |
23 |
| -- Use ES6 features (arrow functions, destructuring, etc.) |
24 |
| -- Use`const` by default;`let` only when necessary |
25 |
| -- Prefix unused variables with underscore (e.g.,`_unused`) |
26 |
| -- Sort imports alphabetically in groups: external → parent → sibling |
27 |
| -- Error handling: wrap and type errors appropriately |
28 |
| -- Use async/await for promises, avoid explicit Promise construction where possible |
29 |
| -- Unit test files must be named`*.test.ts` and use Vitest |
30 |
| -- Integration test files must be named`*.test.ts` and be located in the`src/test` directory |
31 |
| -- Avoid eslint-disable comments where at all possible - it's better to make a custom type than disable linting |
32 |
| - |
33 |
| -##Test Coverage Guidelines |
34 |
| - |
35 |
| -Current status:**78.49% overall unit test coverage** with 405 unit tests and 69 integration tests passing. |
36 |
| - |
37 |
| -###TDD Approach for New Features |
38 |
| - |
39 |
| -1.**Write failing test first** - define expected behavior |
40 |
| -2.**Implement minimal code** to make test pass |
41 |
| -3.**Run full test suite** with`yarn test:ci --coverage` |
42 |
| -4.**Refactor if needed** while keeping tests green |
43 |
| -5.**Ensure backward compatibility** when modifying existing interfaces |
44 |
| - |
45 |
| -###Testing Priority Framework |
46 |
| - |
47 |
| -1.**Files with <50% coverage** need immediate attention (remote.ts: 49.51%) |
48 |
| -2.**Add incremental tests** - focus on measurable progress each session |
49 |
| -3.**Target coverage improvements** of 5-15 percentage points per file |
50 |
| -4.**ALWAYS use`yarn test:ci --coverage`** - never test individual files |
51 |
| -5.**Ignore coverage for test-helpers.ts** - this is a test utility file containing mock factories and helper functions |
52 |
| - |
53 |
| -###Testing Patterns to Follow |
54 |
| - |
55 |
| --**Use mock factories from test-helpers.ts** - 30+ factory functions available for all common types |
56 |
| --**No inline mock definitions** - always use factory functions for consistency |
57 |
| --**Minimal`as any` usage** - reduced from 95 to 4 instances (96% reduction) |
58 |
| --**Use createMockOutputChannelWithLogger()** for consistent Logger testing |
59 |
| --**Mock external dependencies** properly using vi.mock() with TypeScript types |
60 |
| --**Test core functionality first** - constructor, main methods, error paths |
61 |
| --**Ensure backward compatibility** by adding compatibility methods during refactoring |
62 |
| --**Group related tests** in describe blocks for better organization |
63 |
| - |
64 |
| -###Test Helper Patterns |
65 |
| - |
66 |
| -```typescript |
67 |
| -// Example factory functions from test-helpers.ts |
68 |
| - |
69 |
| -// Storage variants |
70 |
| -exportfunction createMockStorageWithAuth():Storage |
71 |
| -exportfunction createMockStorageMinimal():Storage |
72 |
| - |
73 |
| -// Workspace variants |
74 |
| -exportfunction createMockWorkspaceRunning():Workspace |
75 |
| -exportfunction createMockWorkspaceStopped():Workspace |
76 |
| -exportfunction createMockWorkspaceFailed():Workspace |
77 |
| - |
78 |
| -// VSCode components |
79 |
| -exportfunction createMockExtensionContext():vscode.ExtensionContext |
80 |
| -exportfunction createMockRemoteSSHExtension():vscode.Extension<unknown> |
81 |
| -exportfunction createMockTreeView<T>():vscode.TreeView<T> |
82 |
| -exportfunction createMockStatusBarItem():vscode.StatusBarItem |
83 |
| -exportfunction createMockQuickPick<T>():vscode.QuickPick<T> |
84 |
| -exportfunction createMockTerminal():vscode.Terminal |
85 |
| -exportfunction createMockOutputChannel():vscode.OutputChannel |
86 |
| - |
87 |
| -// Other utilities |
88 |
| -exportfunction createMockWorkspaceProvider():WorkspaceProvider |
89 |
| -exportfunction createMockRemote():Remote |
90 |
| -exportfunction createMockCommands():Commands |
91 |
| -exportfunction createMockEventEmitter<T>():vscode.EventEmitter<T> |
92 |
| -exportfunction createMockAxiosInstance():AxiosInstance |
93 |
| -exportfunction createMockProxyAgent():ProxyAgent |
94 |
| -exportfunction createMockUri(path:string,scheme?:string):vscode.Uri |
| 9 | +```bash |
| 10 | +yarn lint:fix# Lint with auto-fix |
| 11 | +yarn test:ci --coverage# Run ALL unit tests (ALWAYS use this) |
| 12 | +yarn pretest&& yarn test:integration# Integration tests |
95 | 13 | ```
|
96 | 14 |
|
97 |
| -###FileswithExcellentCoverage (>90%)-UseasExamples: |
98 |
| - |
99 |
| --featureSet.ts:100% |
100 |
| --proxy.ts:100% |
101 |
| --logger.ts:98.44% (goodTDDexample) |
102 |
| --sshSupport.ts:98.13% |
103 |
| --util.ts:97.31% |
104 |
| --headers.ts:96.49% |
105 |
| --api-helper.ts:96.36% |
106 |
| --sshConfig.ts:96.21% |
107 |
| --api.ts:95.52% |
108 |
| --extension.ts:93.07% (refactoredfrom39.71%usingTDD) |
109 |
| --workspaceMonitor.ts:92.37% |
110 |
| --error.ts:90.44% |
111 |
| --cliManager.ts:90.05% |
112 |
| - |
113 |
| -###CurrentDevelopmentApproach |
114 |
| - |
115 |
| --**TDDfornewfeatures**-testfirst,implementsecond |
116 |
| --**Incrementalrefactoring**-small,measurableimprovements |
117 |
| --**Backwardcompatibility**-addcompatibilitymethodswhenchanginginterfaces |
118 |
| --**Comprehensivemockfactories**-30+factoryfunctionsintest-helpers.ts |
119 |
| --**Noinlinemocks**-alltestmocksusefactoryfunctions |
120 |
| --**Type-safetesting**-minimal`as any`usage (only4instancesremain) |
121 |
| --**Measureprogressconstantly**-run`yarn test:ci --coverage`aftereverychange |
| 15 | +##Key Rules |
122 | 16 |
|
123 |
| -###RefactoringStrategy |
| 17 | +-**TypeScript strict mode**, no semicolons, 120 char lines |
| 18 | +-**Test files**:`*.test.ts` (Vitest for unit, VS Code API for integration) |
| 19 | +-**Use test-helpers.ts**: 30+ mock factories available - NEVER create inline mocks, instead create a new factory in that file and import it |
| 20 | +-**TDD always**: Write test → implement → refactor |
| 21 | +-**Never use any**: Always try to use at least a decently close Partial type or equivalent |
| 22 | +-**Never delete tests**: Only delete or skip tests if directly asked, otherwise ask the user for help if fixing the tests does not work. |
124 | 23 |
|
125 |
| -Whenreplacinglegacypatterns (e.g.,writeToCoderOutputChannel): |
| 24 | +##Testing Approach |
126 | 25 |
|
127 |
| -1.Addbackwardcompatibilitymethodtonewimplementation |
128 |
| -2.Writetestsverifyingcompatibility |
129 |
| -3.Incrementallyreplaceusagestartingwithhighest-impactfiles |
130 |
| -4.Maintainfulltestsuitepassingthroughout |
131 |
| - |
132 |
| -###Example:TDDRefactoringPattern (extension.tssuccessstory) |
133 |
| - |
134 |
| -```typescript |
135 |
| -// 1. Write test for extracted function FIRST |
136 |
| -describe("setupRemoteSSHExtension", () => { |
137 |
| - it("should configure remote SSH when available", () => { |
138 |
| - const mockExtension = createMockRemoteSSHExtension(); |
139 |
| - const mockRemote = createMockRemote(); |
140 |
| -
|
141 |
| - const result = setupRemoteSSHExtension(mockExtension); |
142 |
| -
|
143 |
| - expect(result).toBe(mockRemote); |
144 |
| - }); |
145 |
| -}); |
146 |
| -
|
147 |
| -// 2. Extract function to make test pass |
148 |
| -export function setupRemoteSSHExtension( |
149 |
| - remoteSSHExtension: vscode.Extension<unknown> | undefined, |
150 |
| -): Remote | undefined { |
151 |
| - if (!remoteSSHExtension) { |
152 |
| - return undefined; |
153 |
| - } |
154 |
| - // Implementation here |
155 |
| -} |
156 |
| -
|
157 |
| -// 3. Replace in original code |
158 |
| -const remoteSSHExtension = vscode.extensions.getExtension("ms-vscode-remote.remote-ssh"); |
159 |
| -const remote = setupRemoteSSHExtension(remoteSSHExtension); |
160 |
| -
|
161 |
| -// Result: extension.ts coverage improved from 39.71% to 93.07% |
162 |
| -``` |
| 26 | +1. Use`yarn test:ci --coverage` before and after EVERY change |
| 27 | +2. Import factories and mocks from test-helpers.ts (createMock* and*Factory) |
| 28 | +3. Write a test, make sure it fails, and only then make it pass |
| 29 | +4. Use proper types, NEVER use eslint-disable to make mocks work |
| 30 | +5. If mocking is too complicated, consider whether the function under test needs a minor refactoring that passes existing tests first, to make it easier to test. |