@@ -155,6 +155,33 @@ def test_cli_overrides_defaults(self):
155155 self .assertEqual (args .top_traj_file , ["/cli/path" ])
156156 self .assertEqual (args .selection_string , "cli_value" )
157157
158+ def test_cli_overrides_yaml (self ):
159+ """
160+ Test if CLI parameters override YAML parameters correctly.
161+ """
162+ arg_config = ConfigManager ()
163+ parser = arg_config .setup_argparse ()
164+ args = parser .parse_args (
165+ ["--top_traj_file" , "/cli/path" , "--selection_string" , "cli_value" ]
166+ )
167+ run_config = {"top_traj_file" : ["/yaml/path" ], "selection_string" : "yaml_value" }
168+ merged_args = arg_config .merge_configs (args , run_config )
169+ self .assertEqual (merged_args .top_traj_file , ["/cli/path" ])
170+ self .assertEqual (merged_args .selection_string , "cli_value" )
171+
172+ def test_cli_overrides_yaml_with_multiple_values (self ):
173+ """
174+ Ensures that CLI arguments override YAML when multiple values are provided in
175+ YAML.
176+ """
177+ arg_config = ConfigManager ()
178+ yaml_config = {"top_traj_file" : ["/yaml/path1" , "/yaml/path2" ]}
179+ args = argparse .Namespace (top_traj_file = ["/cli/path" ])
180+
181+ merged_args = arg_config .merge_configs (args , yaml_config )
182+
183+ self .assertEqual (merged_args .top_traj_file , ["/cli/path" ])
184+
158185 def test_yaml_overrides_defaults (self ):
159186 """
160187 Test if YAML parameters override default values.
@@ -166,19 +193,68 @@ def test_yaml_overrides_defaults(self):
166193 self .assertEqual (merged_args .top_traj_file , ["/yaml/path" ])
167194 self .assertEqual (merged_args .selection_string , "yaml_value" )
168195
169- def test_cli_overrides_yaml (self ):
196+ def test_yaml_does_not_override_cli_if_set (self ):
170197 """
171- Test if CLI parameters override YAML parameters correctly .
198+ Ensure YAML does not override CLI arguments that are set .
172199 """
173200 arg_config = ConfigManager ()
174- parser = arg_config .setup_argparse ()
175- args = parser .parse_args (
176- ["--top_traj_file" , "/cli/path" , "--selection_string" , "cli_value" ]
201+
202+ yaml_config = {"bin_width" : 50 }
203+ args = argparse .Namespace (bin_width = 100 )
204+
205+ merged_args = arg_config .merge_configs (args , yaml_config )
206+
207+ self .assertEqual (merged_args .bin_width , 100 )
208+
209+ def test_yaml_overrides_defaults_when_no_cli (self ):
210+ """
211+ Test if YAML parameters override default values when no CLI input is given.
212+ """
213+ arg_config = ConfigManager ()
214+
215+ yaml_config = {
216+ "top_traj_file" : ["/yaml/path" ],
217+ "bin_width" : 50 ,
218+ }
219+
220+ args = argparse .Namespace ()
221+
222+ merged_args = arg_config .merge_configs (args , yaml_config )
223+
224+ self .assertEqual (merged_args .top_traj_file , ["/yaml/path" ])
225+ self .assertEqual (merged_args .bin_width , 50 )
226+
227+ def test_yaml_none_does_not_override_defaults (self ):
228+ """
229+ Ensures that YAML values set to `None` do not override existing CLI values.
230+ """
231+ arg_config = ConfigManager ()
232+ yaml_config = {"bin_width" : None }
233+ args = argparse .Namespace (bin_width = 100 )
234+
235+ merged_args = arg_config .merge_configs (args , yaml_config )
236+
237+ self .assertEqual (merged_args .bin_width , 100 )
238+
239+ def test_hierarchy_cli_yaml_defaults (self ):
240+ """
241+ Test if CLI arguments override YAML, and YAML overrides defaults.
242+ """
243+ arg_config = ConfigManager ()
244+
245+ yaml_config = {
246+ "top_traj_file" : ["/yaml/path" , "/yaml/path" ],
247+ "bin_width" : "50" ,
248+ }
249+
250+ args = argparse .Namespace (
251+ top_traj_file = ["/cli/path" , "/cli/path" ], bin_width = 100
177252 )
178- run_config = {"top_traj_file" : ["/yaml/path" ], "selection_string" : "yaml_value" }
179- merged_args = arg_config .merge_configs (args , run_config )
180- self .assertEqual (merged_args .top_traj_file , ["/cli/path" ])
181- self .assertEqual (merged_args .selection_string , "cli_value" )
253+
254+ merged_args = arg_config .merge_configs (args , yaml_config )
255+
256+ self .assertEqual (merged_args .top_traj_file , ["/cli/path" , "/cli/path" ])
257+ self .assertEqual (merged_args .bin_width , 100 )
182258
183259 def test_merge_configs (self ):
184260 """
@@ -221,6 +297,19 @@ def test_merge_configs(self):
221297 self .assertEqual (merged_args .top_traj_file , ["/path/to/tpr" , "/path/to/trr" ])
222298 self .assertEqual (merged_args .selection_string , "all" )
223299
300+ def test_merge_with_none_yaml (self ):
301+ """
302+ Ensure merging still works if no YAML config is provided.
303+ """
304+ arg_config = ConfigManager ()
305+
306+ args = argparse .Namespace (top_traj_file = ["/cli/path" ])
307+ yaml_config = None
308+
309+ merged_args = arg_config .merge_configs (args , yaml_config )
310+
311+ self .assertEqual (merged_args .top_traj_file , ["/cli/path" ])
312+
224313 @patch ("argparse.ArgumentParser.parse_args" )
225314 def test_default_values (self , mock_parse_args ):
226315 """
@@ -234,6 +323,20 @@ def test_default_values(self, mock_parse_args):
234323 args = parser .parse_args ()
235324 self .assertEqual (args .top_traj_file , ["example.top" , "example.traj" ])
236325
326+ def test_fallback_to_defaults (self ):
327+ """
328+ Ensure arguments fall back to defaults if neither YAML nor CLI provides them.
329+ """
330+ arg_config = ConfigManager ()
331+
332+ yaml_config = {}
333+ args = argparse .Namespace ()
334+
335+ merged_args = arg_config .merge_configs (args , yaml_config )
336+
337+ self .assertEqual (merged_args .step , 1 )
338+ self .assertEqual (merged_args .end , - 1 )
339+
237340 @patch (
238341 "argparse.ArgumentParser.parse_args" , return_value = MagicMock (top_traj_file = None )
239342 )
0 commit comments