@@ -203,14 +203,11 @@ def test_parse_simple_yaml_handles_comments_quotes_and_whitespace(self):
203203
204204 with tempfile .NamedTemporaryFile ("w" , suffix = ".yml" , delete = False ) as handle :
205205 handle .write (
206- """
207- # leading comment
208-
209- key1: value1 # trailing comment
210- key2: \" spaced value \"
211- key3: 'another value'
212- key4: value-with-#-hash
213- """
206+ "# leading comment\n \n "
207+ "key1: value1 # trailing comment\n "
208+ 'key2: " spaced value "\n '
209+ "key3: 'another value'\n "
210+ "key4: value-with-#-hash\n "
214211 )
215212 metadata_path = Path (handle .name )
216213
@@ -224,6 +221,45 @@ def test_parse_simple_yaml_handles_comments_quotes_and_whitespace(self):
224221 self .assertEqual (parsed ["key3" ], "another value" )
225222 self .assertEqual (parsed ["key4" ], "value-with-#-hash" )
226223
224+ def test_parse_simple_yaml_rejects_indented_lines (self ):
225+ module = load_validator_module ()
226+
227+ with tempfile .NamedTemporaryFile ("w" , suffix = ".yml" , delete = False ) as handle :
228+ handle .write ("name: demo\n nested: nope\n " )
229+ metadata_path = Path (handle .name )
230+
231+ try :
232+ with self .assertRaisesRegex (ValueError , "Unsupported YAML indentation" ):
233+ module ._parse_simple_yaml (metadata_path )
234+ finally :
235+ os .remove (metadata_path )
236+
237+ def test_parse_simple_yaml_rejects_list_syntax (self ):
238+ module = load_validator_module ()
239+
240+ with tempfile .NamedTemporaryFile ("w" , suffix = ".yml" , delete = False ) as handle :
241+ handle .write ("- item\n " )
242+ metadata_path = Path (handle .name )
243+
244+ try :
245+ with self .assertRaisesRegex (ValueError , "Unsupported YAML list syntax" ):
246+ module ._parse_simple_yaml (metadata_path )
247+ finally :
248+ os .remove (metadata_path )
249+
250+ def test_parse_simple_yaml_rejects_duplicate_keys (self ):
251+ module = load_validator_module ()
252+
253+ with tempfile .NamedTemporaryFile ("w" , suffix = ".yml" , delete = False ) as handle :
254+ handle .write ("name: first\n name: second\n " )
255+ metadata_path = Path (handle .name )
256+
257+ try :
258+ with self .assertRaisesRegex (ValueError , "Duplicate key 'name'" ):
259+ module ._parse_simple_yaml (metadata_path )
260+ finally :
261+ os .remove (metadata_path )
262+
227263 def test_load_metadata_uses_yaml_safe_load_when_available (self ):
228264 module = load_validator_module ()
229265
@@ -268,12 +304,7 @@ def test_load_metadata_uses_simple_parser_when_yaml_unavailable(self):
268304 module = load_validator_module ()
269305
270306 with tempfile .NamedTemporaryFile ("w" , suffix = ".yml" , delete = False ) as handle :
271- handle .write (
272- """
273- name: demo-plugin
274- version: \" 0.2.3\"
275- """
276- )
307+ handle .write ('name: demo-plugin\n version: "0.2.3"\n ' )
277308 metadata_path = Path (handle .name )
278309
279310 yaml_backup = getattr (module , "yaml" , None )
@@ -287,6 +318,22 @@ def test_load_metadata_uses_simple_parser_when_yaml_unavailable(self):
287318 self .assertEqual (metadata .get ("name" ), "demo-plugin" )
288319 self .assertEqual (metadata .get ("version" ), "0.2.3" )
289320
321+ def test_load_metadata_wraps_fallback_parse_errors (self ):
322+ module = load_validator_module ()
323+
324+ with tempfile .NamedTemporaryFile ("w" , suffix = ".yml" , delete = False ) as handle :
325+ handle .write ("name: demo\n nested: nope\n " )
326+ metadata_path = Path (handle .name )
327+
328+ yaml_backup = getattr (module , "yaml" , None )
329+ try :
330+ module .yaml = None
331+ with self .assertRaisesRegex (module .MetadataLoadError , "Unsupported YAML indentation" ):
332+ module .load_metadata (metadata_path )
333+ finally :
334+ module .yaml = yaml_backup
335+ os .remove (metadata_path )
336+
290337 def test_load_plugins_index_accepts_valid_object (self ):
291338 module = load_validator_module ()
292339
@@ -332,7 +379,7 @@ def test_load_plugins_index_rejects_non_dict_values(self):
332379 index_path = Path (handle .name )
333380
334381 try :
335- with self .assertRaisesRegex (ValueError , "plugins.json values must be objects/dicts " ):
382+ with self .assertRaisesRegex (ValueError , "plugins.json entry 'not-a-dict'.* must be a JSON object " ):
336383 module .load_plugins_index (index_path )
337384 finally :
338385 os .remove (index_path )
0 commit comments