@@ -104,4 +104,163 @@ describe('server_job', function()
104104 assert .same (fake , second ._value or second )
105105 assert .equal (1 , spawn_count )
106106 end )
107+
108+ describe (' ensure_server with config.server.url set' , function ()
109+ local config
110+ local state
111+ local port_mapping
112+ local original_port
113+ local original_url
114+ local original_spawn_command
115+ local original_opencode_server
116+ local original_find_any_existing_port
117+ local original_find_port_for_directory
118+ local original_started_by_nvim
119+ local original_register
120+
121+ before_each (function ()
122+ config = require (' opencode.config' )
123+ state = require (' opencode.state' )
124+ port_mapping = require (' opencode.port_mapping' )
125+
126+ original_port = config .values .server .port
127+ original_url = config .values .server .url
128+ original_spawn_command = config .values .server .spawn_command
129+ original_opencode_server = state .opencode_server
130+
131+ original_find_any_existing_port = port_mapping .find_any_existing_port
132+ original_find_port_for_directory = port_mapping .find_port_for_directory
133+ original_started_by_nvim = port_mapping .started_by_nvim
134+ original_register = port_mapping .register
135+
136+ port_mapping .register = function () end
137+ port_mapping .started_by_nvim = function ()
138+ return false
139+ end
140+
141+ state .opencode_server = nil
142+ end )
143+
144+ after_each (function ()
145+ config .values .server .port = original_port
146+ config .values .server .url = original_url
147+ config .values .server .spawn_command = original_spawn_command
148+ state .opencode_server = original_opencode_server
149+
150+ port_mapping .find_any_existing_port = original_find_any_existing_port
151+ port_mapping .find_port_for_directory = original_find_port_for_directory
152+ port_mapping .started_by_nvim = original_started_by_nvim
153+ port_mapping .register = original_register
154+ end )
155+
156+ it (' attaches to custom server when health check succeeds' , function ()
157+ config .values .server .url = ' http://192.168.1.100'
158+ config .values .server .port = 4321
159+ config .values .server .spawn_command = nil
160+
161+ curl .request = function (opts )
162+ vim .schedule (function ()
163+ opts .callback ({ status = 200 , body = ' {"ok":true}' })
164+ end )
165+ end
166+
167+ local result = server_job .ensure_server ():wait ()
168+ assert .is_not_nil (result )
169+ assert .equal (' http://192.168.1.100:4321' , result .url )
170+ assert .equal (4321 , result .port )
171+ end )
172+
173+ it (' resolves url with default port from find_any_existing_port when port is nil' , function ()
174+ config .values .server .url = ' http://127.0.0.1'
175+ config .values .server .port = nil
176+ config .values .server .spawn_command = nil
177+
178+ port_mapping .find_any_existing_port = function ()
179+ return 9999
180+ end
181+
182+ curl .request = function (opts )
183+ vim .schedule (function ()
184+ opts .callback ({ status = 200 , body = ' {"ok":true}' })
185+ end )
186+ end
187+
188+ local result = server_job .ensure_server ():wait ()
189+ assert .is_not_nil (result )
190+ assert .equal (' http://127.0.0.1:9999' , result .url )
191+ end )
192+
193+ it (' falls back to local spawn when resolve_port returns nil' , function ()
194+ config .values .server .url = ' http://127.0.0.1'
195+ config .values .server .port = nil
196+ config .values .server .spawn_command = nil
197+
198+ -- no existing port → resolve_port() returns nil
199+ port_mapping .find_any_existing_port = function ()
200+ return nil
201+ end
202+
203+ local spawn_count = 0
204+ local fake_local = {
205+ url = ' http://127.0.0.1:5000' ,
206+ port = nil ,
207+ is_running = function (self )
208+ return spawn_count > 0
209+ end ,
210+ spawn = function (self , opts )
211+ spawn_count = spawn_count + 1
212+ vim .schedule (function ()
213+ opts .on_ready ({}, self .url )
214+ end )
215+ end ,
216+ shutdown = function () end ,
217+ }
218+ opencode_server .new = function ()
219+ return fake_local
220+ end
221+
222+ local result = server_job .ensure_server ():wait ()
223+ assert .equal (1 , spawn_count )
224+ assert .same (fake_local , result ._value or result )
225+ end )
226+
227+ it (' falls back to local spawn when health check fails and no spawn_command' , function ()
228+ config .values .server .url = ' http://192.168.1.100'
229+ config .values .server .port = 7777
230+ config .values .server .spawn_command = nil
231+
232+ curl .request = function (opts )
233+ vim .schedule (function ()
234+ if opts .callback then
235+ opts .callback ({ status = 503 , body = ' {}' })
236+ elseif opts .on_error then
237+ opts .on_error ({ message = ' connection refused' })
238+ end
239+ end )
240+ end
241+
242+ local spawn_count = 0
243+ local fake_local = {
244+ url = ' http://127.0.0.1:8080' ,
245+ port = nil ,
246+ is_running = function (self )
247+ return spawn_count > 0
248+ end ,
249+ spawn = function (self , opts )
250+ spawn_count = spawn_count + 1
251+ vim .schedule (function ()
252+ opts .on_ready ({}, self .url )
253+ end )
254+ end ,
255+ shutdown = function () end ,
256+ }
257+ opencode_server .new = function ()
258+ return fake_local
259+ end
260+
261+ local result = server_job .ensure_server ():wait ()
262+ assert .equal (1 , spawn_count )
263+ assert .same (fake_local , result ._value or result )
264+ end )
265+ end )
107266end )
0 commit comments