@@ -183,3 +183,163 @@ def test_perf_cmd_json():
183183 data = __import__ ("json" ).loads (result .output )
184184 assert "chip_model" in data
185185 assert "openmp" in data
186+
187+
188+ # ---------------------------------------------------------------------------
189+ # helicon scan
190+ # ---------------------------------------------------------------------------
191+
192+
193+ def test_scan_dry_run (tmp_path ):
194+ runner = CliRunner ()
195+ with tempfile .TemporaryDirectory () as tmpdir :
196+ config_path = _write_config (tmpdir )
197+ out = str (tmp_path / "scan_out" )
198+ result = runner .invoke (
199+ main ,
200+ [
201+ "scan" ,
202+ "--config" , config_path ,
203+ "--vary" , "coils.0.I:5000:15000:2" ,
204+ "--output" , out ,
205+ "--dry-run" ,
206+ ],
207+ )
208+ assert result .exit_code == 0 , result .output
209+ assert "Done:" in result .output
210+ assert "CSV:" in result .output
211+ assert "JSON:" in result .output
212+
213+
214+ def test_scan_writes_csv_and_json (tmp_path ):
215+ import json
216+
217+ runner = CliRunner ()
218+ with tempfile .TemporaryDirectory () as tmpdir :
219+ config_path = _write_config (tmpdir )
220+ out = tmp_path / "scan_out"
221+ runner .invoke (
222+ main ,
223+ [
224+ "scan" ,
225+ "--config" , config_path ,
226+ "--vary" , "coils.0.I:5000:15000:2" ,
227+ "--output" , str (out ),
228+ "--dry-run" ,
229+ ],
230+ )
231+ assert (out / "scan_results.csv" ).exists ()
232+ assert (out / "scan_summary.json" ).exists ()
233+ data = json .loads ((out / "scan_summary.json" ).read_text ())
234+ assert data ["n_points" ] == 2
235+
236+
237+ def test_scan_bad_vary (tmp_path ):
238+ runner = CliRunner ()
239+ with tempfile .TemporaryDirectory () as tmpdir :
240+ config_path = _write_config (tmpdir )
241+ result = runner .invoke (
242+ main ,
243+ ["scan" , "--config" , config_path , "--vary" , "badspec" , "--output" , str (tmp_path )],
244+ )
245+ assert result .exit_code != 0
246+
247+
248+ # ---------------------------------------------------------------------------
249+ # helicon doctor, init, schema
250+ # ---------------------------------------------------------------------------
251+
252+
253+ def test_doctor_cmd ():
254+ runner = CliRunner ()
255+ result = runner .invoke (main , ["doctor" ])
256+ assert result .exit_code == 0
257+ assert "Python" in result .output or "python" in result .output .lower ()
258+
259+
260+ def test_init_cmd (tmp_path ):
261+ runner = CliRunner ()
262+ out = str (tmp_path / "my_nozzle.yaml" )
263+ result = runner .invoke (main , ["init" , "test_nozzle" , "--output" , out ])
264+ assert result .exit_code == 0 , result .output
265+ assert (tmp_path / "my_nozzle.yaml" ).exists ()
266+
267+
268+ def test_schema_cmd ():
269+ runner = CliRunner ()
270+ result = runner .invoke (main , ["schema" ])
271+ assert result .exit_code == 0
272+ data = __import__ ("json" ).loads (result .output )
273+ assert "properties" in data or "title" in data
274+
275+
276+ # ---------------------------------------------------------------------------
277+ # helicon benchmark
278+ # ---------------------------------------------------------------------------
279+
280+
281+ def test_benchmark_cmd (tmp_path ):
282+ runner = CliRunner ()
283+ result = runner .invoke (main , ["benchmark" , "--repeat" , "1" ])
284+ assert result .exit_code == 0
285+ assert "Biot" in result .output or "benchmark" in result .output .lower ()
286+
287+
288+ # ---------------------------------------------------------------------------
289+ # helicon detach assess
290+ # ---------------------------------------------------------------------------
291+
292+
293+ def test_detach_assess_json ():
294+ runner = CliRunner ()
295+ result = runner .invoke (
296+ main ,
297+ [
298+ "detach" , "assess" ,
299+ "--n" , "1e18" ,
300+ "--Te" , "100" ,
301+ "--Ti" , "100" ,
302+ "--B" , "0.05" ,
303+ "--vz" , "50000" ,
304+ "--json" ,
305+ ],
306+ )
307+ assert result .exit_code in (0 , 1 , 2 ), result .output
308+ data = __import__ ("json" ).loads (result .output )
309+ assert "is_detached" in data or "detached" in str (data )
310+
311+
312+ def test_detach_assess_text ():
313+ runner = CliRunner ()
314+ result = runner .invoke (
315+ main ,
316+ [
317+ "detach" , "assess" ,
318+ "--n" , "1e18" ,
319+ "--Te" , "100" ,
320+ "--Ti" , "100" ,
321+ "--B" , "0.1" ,
322+ "--vz" , "20000" ,
323+ ],
324+ )
325+ assert result .exit_code in (0 , 1 , 2 )
326+
327+
328+ # ---------------------------------------------------------------------------
329+ # helicon sensitivity (dry-run via analytical only)
330+ # ---------------------------------------------------------------------------
331+
332+
333+ def test_sensitivity_cmd (tmp_path ):
334+ runner = CliRunner ()
335+ result = runner .invoke (
336+ main ,
337+ [
338+ "sensitivity" ,
339+ "--preset" , "sunbird" ,
340+ "--n-samples" , "8" ,
341+ "--output" , str (tmp_path / "sobol.json" ),
342+ ],
343+ )
344+ assert result .exit_code == 0 , result .output
345+ assert "Sobol" in result .output or "S1" in result .output or "coil" in result .output .lower ()
0 commit comments