@@ -241,3 +241,62 @@ def test_blank_lines_not_validated_in_strict_mode(self):
241241 # Should not raise error for blank line with invalid indentation
242242 assert len (blanks ) == 1
243243 assert blanks [0 ].line_num == 2
244+
245+
246+ class TestCRLFHandling :
247+ """Tests for CRLF and CR normalization."""
248+
249+ def test_crlf_normalization (self ):
250+ """Test Windows CRLF line endings are normalized to LF."""
251+ source = "name: Alice\r \n age: 30\r \n "
252+ lines , blanks = to_parsed_lines (source , 2 , False )
253+ # Verify no \r remains in content
254+ assert "\r " not in lines [0 ].content
255+ assert "\r " not in lines [1 ].content
256+ assert lines [0 ].content == "name: Alice"
257+ assert lines [1 ].content == "age: 30"
258+ assert len (lines ) == 3 # name, age, and trailing empty line
259+
260+ def test_standalone_cr_normalization (self ):
261+ """Test old Mac CR line endings are normalized to LF."""
262+ source = "name: Alice\r age: 30\r "
263+ lines , blanks = to_parsed_lines (source , 2 , False )
264+ # Verify no \r remains in content
265+ assert "\r " not in lines [0 ].content
266+ assert "\r " not in lines [1 ].content
267+ assert lines [0 ].content == "name: Alice"
268+ assert lines [1 ].content == "age: 30"
269+ assert len (lines ) == 3 # name, age, and trailing empty line
270+
271+ def test_mixed_line_endings (self ):
272+ """Test mixed line endings are all normalized."""
273+ source = "line1\r \n line2\n line3\r line4"
274+ lines , blanks = to_parsed_lines (source , 2 , False )
275+ assert len (lines ) == 4
276+ for line in lines :
277+ assert "\r " not in line .content
278+ assert lines [0 ].content == "line1"
279+ assert lines [1 ].content == "line2"
280+ assert lines [2 ].content == "line3"
281+ assert lines [3 ].content == "line4"
282+
283+ def test_crlf_with_indentation (self ):
284+ """Test CRLF handling preserves indentation."""
285+ source = "parent:\r \n child: value\r \n "
286+ lines , blanks = to_parsed_lines (source , 2 , False )
287+ assert lines [0 ].content == "parent:"
288+ assert lines [0 ].depth == 0
289+ assert lines [1 ].content == "child: value"
290+ assert lines [1 ].depth == 1
291+ assert lines [1 ].indent == 2
292+
293+ def test_crlf_in_strict_mode (self ):
294+ """Test CRLF normalization works in strict mode."""
295+ source = "name: Alice\r \n age: 30\r \n "
296+ lines , blanks = to_parsed_lines (source , 2 , True )
297+ # Should not raise error and should properly normalize
298+ assert len (lines ) == 3
299+ assert "\r " not in lines [0 ].content
300+ assert "\r " not in lines [1 ].content
301+ assert lines [1 ].depth == 1
302+
0 commit comments