1+ import tempfile
2+ import os
3+
4+ def test_with_endings (line_ending , description ):
5+ print (f"\n === Test with { description } ===" )
6+
7+ # Create test content with specified line endings
8+ content = f'line1{ line_ending } line2{ line_ending } line3{ line_ending } '
9+ print (f"Content to write (repr): { repr (content )} " )
10+
11+ # Create different content to replace with, using LF endings
12+ # This simulates real usage where new code comes with normalized \n endings
13+ replace_content = 'newline1\n newline2\n newline3\n '
14+
15+ with tempfile .NamedTemporaryFile (delete = False ) as f :
16+ test_file = f .name
17+
18+ # Write initial content in binary mode
19+ with open (test_file , 'wb' ) as f :
20+ f .write (content .encode ('utf-8' ))
21+
22+ # Read and verify original content
23+ with open (test_file , 'rb' ) as f :
24+ original = f .read ()
25+ print (f"\n Original file bytes (repr): { repr (original )} " )
26+
27+ # Test save_file_contents with original content
28+ from patchwork .steps .ModifyCode .ModifyCode import save_file_contents , replace_code_in_file
29+ print ("\n Testing save_file_contents..." )
30+ save_file_contents (test_file , content )
31+
32+ with open (test_file , 'rb' ) as f :
33+ modified = f .read ()
34+ print (f"Modified file bytes (repr): { repr (modified )} " )
35+
36+ # Verify save_file_contents preserved endings
37+ if original != modified :
38+ print ("\n FAILURE: save_file_contents modified line endings!" )
39+ print (f"Original length: { len (original )} , Modified length: { len (modified )} " )
40+ return False
41+
42+ # Test replace_code_in_file with different content
43+ print ("\n Testing replace_code_in_file..." )
44+ replace_code_in_file (test_file , 0 , 3 , replace_content )
45+
46+ with open (test_file , 'rb' ) as f :
47+ modified2 = f .read ()
48+ print (f"Modified file bytes after replace (repr): { repr (modified2 )} " )
49+
50+ # Cleanup
51+ os .unlink (test_file )
52+
53+ # For replace_code_in_file, verify:
54+ # 1. The content was actually changed (should NOT equal original)
55+ # 2. The new content uses the original line endings
56+ # 3. The file ends with a line ending only if original did
57+ content_changed = original != modified2
58+ uses_right_endings = line_ending .encode ('utf-8' ) in modified2
59+ ends_correctly = original .endswith (line_ending .encode ('utf-8' )) == modified2 .endswith (line_ending .encode ('utf-8' ))
60+
61+ success = content_changed and uses_right_endings and ends_correctly
62+ print (f"\n { 'SUCCESS' if success else 'FAILURE' } : { 'All checks passed!' if success else 'Checks failed:' } " )
63+ if not success :
64+ print (f"Content changed: { content_changed } " )
65+ print (f"Uses right endings: { uses_right_endings } " )
66+ print (f"Ends correctly: { ends_correctly } " )
67+ print (f"Original length: { len (original )} , Replace length: { len (modified2 )} " )
68+ return success
69+
70+ def test_complex_case ():
71+ print ("\n === Test with complex indentation and empty lines ===" )
72+ # Create content with mixed indentation and empty lines, using CRLF endings
73+ content = ' line1\r \n \r \n line2\r \n line3\r \n '
74+ replace_content = 'newline1\n \n newline2\n ' # Note: less indented
75+
76+ with tempfile .NamedTemporaryFile (delete = False ) as f :
77+ test_file = f .name
78+
79+ # Write initial content
80+ with open (test_file , 'wb' ) as f :
81+ f .write (content .encode ('utf-8' ))
82+
83+ # Read original content
84+ with open (test_file , 'rb' ) as f :
85+ original = f .read ()
86+ print (f"Original file bytes (repr): { repr (original )} " )
87+
88+ # Test replace_code_in_file
89+ from patchwork .steps .ModifyCode .ModifyCode import replace_code_in_file
90+ replace_code_in_file (test_file , 0 , 4 , replace_content )
91+
92+ with open (test_file , 'rb' ) as f :
93+ modified = f .read ()
94+ print (f"Modified file bytes (repr): { repr (modified )} " )
95+
96+ # Cleanup
97+ os .unlink (test_file )
98+
99+ # Verify:
100+ # 1. Content was changed
101+ # 2. Uses original CRLF endings
102+ # 3. Empty lines were handled correctly
103+ # 4. Indentation was adjusted correctly
104+ content_changed = original != modified
105+ uses_crlf = b'\r \n ' in modified
106+ has_empty_line = b'\r \n \r \n ' in modified
107+ proper_indent = b' newline' in modified
108+
109+ success = content_changed and uses_crlf and has_empty_line and proper_indent
110+ print (f"\n { 'SUCCESS' if success else 'FAILURE' } : Complex case { 'passed!' if success else 'failed!' } " )
111+ if not success :
112+ print (f"Content changed: { content_changed } " )
113+ print (f"Uses CRLF: { uses_crlf } " )
114+ print (f"Has empty line: { has_empty_line } " )
115+ print (f"Proper indent: { proper_indent } " )
116+ return success
117+
118+ def test_partial_replacement ():
119+ print ("\n === Test partial file replacement ===" )
120+ # Create content with CRLF endings and indentation
121+ content = 'header1\r \n header2\r \n line1\r \n line2\r \n line3\r \n footer\r \n '
122+ replace_content = 'newline1\n newline2\n ' # Replace middle part only
123+
124+ with tempfile .NamedTemporaryFile (delete = False ) as f :
125+ test_file = f .name
126+
127+ # Write initial content
128+ with open (test_file , 'wb' ) as f :
129+ f .write (content .encode ('utf-8' ))
130+
131+ # Read original content
132+ with open (test_file , 'rb' ) as f :
133+ original = f .read ()
134+ print (f"Original file bytes (repr): { repr (original )} " )
135+
136+ # Test replace_code_in_file on middle section (lines 2-4)
137+ from patchwork .steps .ModifyCode .ModifyCode import replace_code_in_file
138+ replace_code_in_file (test_file , 2 , 5 , replace_content )
139+
140+ with open (test_file , 'rb' ) as f :
141+ modified = f .read ()
142+ print (f"Modified file bytes (repr): { repr (modified )} " )
143+
144+ # Cleanup
145+ os .unlink (test_file )
146+
147+ # Verify:
148+ # 1. Header is unchanged
149+ # 2. Footer is unchanged
150+ # 3. Middle section is replaced with new content
151+ # 4. All line endings are CRLF
152+ # 5. Indentation is preserved
153+
154+ # Split content for easier verification
155+ lines = modified .split (b'\r \n ' )
156+
157+ # Check each aspect
158+ header_preserved = lines [:2 ] == [b'header1' , b'header2' ]
159+ footer_preserved = lines [- 2 ] == b'footer' # -2 because -1 is empty string after last \r\n
160+ has_new_content = lines [2 :4 ] == [b' newline1' , b' newline2' ]
161+ all_crlf = b'\n ' not in modified .replace (b'\r \n ' , b'' ) and b'\r \n ' in modified
162+ proper_indent = all (line .startswith (b' ' ) for line in lines [2 :4 ])
163+
164+ success = header_preserved and footer_preserved and has_new_content and all_crlf and proper_indent
165+ print (f"\n { 'SUCCESS' if success else 'FAILURE' } : Partial replacement { 'passed!' if success else 'failed!' } " )
166+ if not success :
167+ print (f"Header preserved: { header_preserved } " )
168+ print (f"Footer preserved: { footer_preserved } " )
169+ print (f"Has new content: { has_new_content } " )
170+ print (f"All CRLF endings: { all_crlf } " )
171+ print (f"Proper indent: { proper_indent } " )
172+ return success
173+
174+ def test_line_endings ():
175+ results = []
176+
177+ # Test with different line endings
178+ results .append (test_with_endings ('\r \r \n ' , 'double-CR line endings (\\ r\\ r\\ n)' ))
179+ results .append (test_with_endings ('\r \n ' , 'CRLF line endings (\\ r\\ n)' ))
180+ results .append (test_with_endings ('\n ' , 'LF line endings (\\ n)' ))
181+ results .append (test_with_endings ('\r ' , 'CR line endings (\\ r)' ))
182+
183+ # Test complex case with indentation and empty lines
184+ results .append (test_complex_case ())
185+
186+ # Test partial file replacement
187+ results .append (test_partial_replacement ())
188+
189+ # Overall result
190+ print ("\n === Overall Test Results ===" )
191+ if all (results ):
192+ print ("SUCCESS: All line ending tests passed!" )
193+ return True
194+ else :
195+ print ("FAILURE: Some line ending tests failed!" )
196+ return False
197+
198+ if __name__ == '__main__' :
199+ test_line_endings ()
200+
201+ if __name__ == '__main__' :
202+ test_line_endings ()
0 commit comments