@@ -8,11 +8,13 @@ import (
88
99// mockProvider implements runtime.Provider for testing
1010type mockProvider struct {
11- name string
12- displayName string
13- globalVersion string
14- globalSetError error
15- setGlobalCalls []string
11+ name string
12+ displayName string
13+ globalVersion string
14+ globalSetError error
15+ setGlobalCalls []string
16+ availableVersions []runtime.AvailableVersion
17+ listAvailableErr error
1618}
1719
1820func (m * mockProvider ) Name () string { return m .name }
@@ -27,7 +29,7 @@ func (m *mockProvider) ListInstalled() ([]runtime.InstalledVersion, error) {
2729 return nil , nil
2830}
2931func (m * mockProvider ) ListAvailable () ([]runtime.AvailableVersion , error ) {
30- return nil , nil
32+ return m . availableVersions , m . listAvailableErr
3133}
3234func (m * mockProvider ) InstallPath (version string ) (string , error ) { return "" , nil }
3335func (m * mockProvider ) LocalVersion () (string , error ) { return "" , nil }
@@ -114,3 +116,147 @@ func TestAutoSetGlobalIfNeeded_MultipleInstalls(t *testing.T) {
114116 t .Errorf ("Expected second install to not change global, got %d calls total" , len (provider .setGlobalCalls ))
115117 }
116118}
119+
120+ // Helper to create AvailableVersion from a version string
121+ func makeAvailableVersion (v string ) runtime.AvailableVersion {
122+ return runtime.AvailableVersion {
123+ Version : runtime .NewVersion (v ),
124+ }
125+ }
126+
127+ func TestResolveVersionForProvider_FullVersion (t * testing.T ) {
128+ provider := & mockProvider {
129+ name : "node" ,
130+ displayName : "Node.js" ,
131+ availableVersions : []runtime.AvailableVersion {
132+ makeAvailableVersion ("22.15.0" ),
133+ makeAvailableVersion ("22.0.0" ),
134+ },
135+ }
136+
137+ // Full version should pass through unchanged
138+ result , err := resolveVersionForProvider (provider , "22.15.0" )
139+ if err != nil {
140+ t .Errorf ("resolveVersionForProvider returned error: %v" , err )
141+ }
142+ if result != "22.15.0" {
143+ t .Errorf ("Expected 22.15.0, got %q" , result )
144+ }
145+ }
146+
147+ func TestResolveVersionForProvider_FullVersionWithVPrefix (t * testing.T ) {
148+ provider := & mockProvider {
149+ name : "node" ,
150+ displayName : "Node.js" ,
151+ availableVersions : []runtime.AvailableVersion {
152+ makeAvailableVersion ("22.15.0" ),
153+ },
154+ }
155+
156+ // Full version with v prefix should have prefix stripped
157+ result , err := resolveVersionForProvider (provider , "v22.15.0" )
158+ if err != nil {
159+ t .Errorf ("resolveVersionForProvider returned error: %v" , err )
160+ }
161+ if result != "22.15.0" {
162+ t .Errorf ("Expected 22.15.0, got %q" , result )
163+ }
164+ }
165+
166+ func TestResolveVersionForProvider_MajorOnly (t * testing.T ) {
167+ provider := & mockProvider {
168+ name : "node" ,
169+ displayName : "Node.js" ,
170+ availableVersions : []runtime.AvailableVersion {
171+ makeAvailableVersion ("22.0.0" ),
172+ makeAvailableVersion ("22.5.0" ),
173+ makeAvailableVersion ("22.15.0" ),
174+ makeAvailableVersion ("22.15.1" ),
175+ makeAvailableVersion ("21.0.0" ),
176+ },
177+ }
178+
179+ // Major-only should resolve to highest 22.x.x
180+ result , err := resolveVersionForProvider (provider , "22" )
181+ if err != nil {
182+ t .Errorf ("resolveVersionForProvider returned error: %v" , err )
183+ }
184+ if result != "22.15.1" {
185+ t .Errorf ("Expected 22.15.1 (highest 22.x.x), got %q" , result )
186+ }
187+ }
188+
189+ func TestResolveVersionForProvider_MajorMinor (t * testing.T ) {
190+ provider := & mockProvider {
191+ name : "node" ,
192+ displayName : "Node.js" ,
193+ availableVersions : []runtime.AvailableVersion {
194+ makeAvailableVersion ("14.21.0" ),
195+ makeAvailableVersion ("14.21.3" ),
196+ makeAvailableVersion ("14.20.0" ),
197+ makeAvailableVersion ("14.20.1" ),
198+ },
199+ }
200+
201+ // Major.minor should resolve to highest 14.21.x
202+ result , err := resolveVersionForProvider (provider , "14.21" )
203+ if err != nil {
204+ t .Errorf ("resolveVersionForProvider returned error: %v" , err )
205+ }
206+ if result != "14.21.3" {
207+ t .Errorf ("Expected 14.21.3 (highest 14.21.x), got %q" , result )
208+ }
209+ }
210+
211+ func TestResolveVersionForProvider_NoMatch (t * testing.T ) {
212+ provider := & mockProvider {
213+ name : "node" ,
214+ displayName : "Node.js" ,
215+ availableVersions : []runtime.AvailableVersion {
216+ makeAvailableVersion ("22.0.0" ),
217+ makeAvailableVersion ("21.0.0" ),
218+ },
219+ }
220+
221+ // No matching version should return error
222+ _ , err := resolveVersionForProvider (provider , "99" )
223+ if err == nil {
224+ t .Error ("Expected error for non-matching version, got nil" )
225+ }
226+ }
227+
228+ func TestResolveVersionForProvider_PythonVersions (t * testing.T ) {
229+ provider := & mockProvider {
230+ name : "python" ,
231+ displayName : "Python" ,
232+ availableVersions : []runtime.AvailableVersion {
233+ makeAvailableVersion ("3.9.18" ),
234+ makeAvailableVersion ("3.10.13" ),
235+ makeAvailableVersion ("3.11.7" ),
236+ makeAvailableVersion ("3.12.0" ),
237+ makeAvailableVersion ("3.12.1" ),
238+ },
239+ }
240+
241+ tests := []struct {
242+ input string
243+ expected string
244+ }{
245+ {"3" , "3.12.1" }, // Latest 3.x.x
246+ {"3.11" , "3.11.7" }, // Latest 3.11.x
247+ {"3.12" , "3.12.1" }, // Latest 3.12.x
248+ }
249+
250+ for _ , tt := range tests {
251+ t .Run (tt .input , func (t * testing.T ) {
252+ result , err := resolveVersionForProvider (provider , tt .input )
253+ if err != nil {
254+ t .Errorf ("resolveVersionForProvider(%q) returned error: %v" , tt .input , err )
255+ return
256+ }
257+ if result != tt .expected {
258+ t .Errorf ("resolveVersionForProvider(%q) = %q, want %q" , tt .input , result , tt .expected )
259+ }
260+ })
261+ }
262+ }
0 commit comments