1+ """
2+ --- AUTO-GENERATED DOCSTRING ---
3+ Table of content is automatically generated by Agent Docstrings v1.3.2
4+
5+ Classes/Functions:
6+ - test_no_docstring_duplication_on_repeated_runs(source_processor) -> None (line 15)
7+ - test_manual_docstring_preservation_with_auto_generation(source_processor) -> None (line 56)
8+ - test_existing_auto_docstring_replacement(source_processor) -> None (line 100)
9+ - test_multiple_auto_docstring_removal(source_processor) -> None (line 135)
10+ --- END AUTO-GENERATED DOCSTRING ---
11+ """
12+ import pytest
13+ import re
14+ from textwrap import dedent
15+
16+ def test_no_docstring_duplication_on_repeated_runs (source_processor ) -> None :
17+ """
18+ Test that running the docstring generator multiple times on the same file
19+ does not create duplicate auto-generated docstrings.
20+ This test simulates the scenario where a file with manual docstring
21+ gets processed multiple times, ensuring no double docstrings are created.
22+ """
23+ # * Initial file with manual docstring
24+ initial_content = dedent ('''
25+ """
26+ Human comments
27+ This is a manual docstring that should be preserved.
28+ """
29+ def test_function():
30+ """This is a function docstring."""
31+ return "test"
32+ class TestClass:
33+ def method(self):
34+ return "method"
35+ ''' ).strip ()
36+ # * First run - should generate auto docstring and merge with manual
37+ result_content_1 , lines_1 , _ = source_processor ("test_duplication.py" , initial_content )
38+ # * Verify that auto-generated docstring was added
39+ assert "--- AUTO-GENERATED DOCSTRING ---" in result_content_1
40+ assert "Human comments" in result_content_1 # Manual content preserved
41+ assert "test_function()" in result_content_1 # Auto-generated content added
42+ # * Count auto-generated docstring markers
43+ auto_markers_1 = result_content_1 .count ("--- AUTO-GENERATED DOCSTRING ---" )
44+ assert auto_markers_1 == 1 , f"Expected 1 auto docstring marker, found { auto_markers_1 } "
45+ # * Second run - should not create duplicate auto docstrings
46+ result_content_2 , lines_2 , _ = source_processor ("test_duplication.py" , result_content_1 )
47+ # * Verify no duplication occurred
48+ auto_markers_2 = result_content_2 .count ("--- AUTO-GENERATED DOCSTRING ---" )
49+ assert auto_markers_2 == 1 , f"Expected 1 auto docstring marker after second run, found { auto_markers_2 } "
50+ # * Verify manual content is still preserved
51+ assert "Human comments" in result_content_2
52+ assert "This is a manual docstring that should be preserved." in result_content_2
53+ # * Verify auto-generated content is still present
54+ assert "test_function()" in result_content_2
55+ assert "TestClass" in result_content_2
56+ assert "method()" in result_content_2
57+
58+ def test_manual_docstring_preservation_with_auto_generation (source_processor ) -> None :
59+ """
60+ Test that manual docstrings are properly preserved when auto-generating
61+ docstrings, and that the structure is correct.
62+ """
63+ # * File with manual docstring only
64+ initial_content = dedent ('''
65+ """
66+ This is a manual module docstring.
67+ It should be preserved and merged with auto-generated content.
68+ """
69+ def function_one():
70+ pass
71+ def function_two():
72+ pass
73+ ''' ).strip ()
74+ result_content , lines , _ = source_processor ("test_manual_preservation.py" , initial_content )
75+ # * Verify structure: manual content should come after auto-generated content
76+ lines_list = result_content .split ('\n ' )
77+ # * Find the docstring boundaries
78+ docstring_start = None
79+ docstring_end = None
80+ manual_content_found = False
81+ for i , line in enumerate (lines_list ):
82+ if line .strip () == '"""' and docstring_start is None :
83+ docstring_start = i
84+ elif line .strip () == '"""' and docstring_start is not None :
85+ docstring_end = i
86+ break
87+ assert docstring_start is not None , "Docstring start not found"
88+ assert docstring_end is not None , "Docstring end not found"
89+ # * Extract docstring content
90+ docstring_content = lines_list [docstring_start :docstring_end + 1 ]
91+ docstring_text = '\n ' .join (docstring_content )
92+ # * Verify auto-generated content is first
93+ assert "--- AUTO-GENERATED DOCSTRING ---" in docstring_text
94+ assert "function_one()" in docstring_text
95+ assert "function_two()" in docstring_text
96+ # * Verify manual content is preserved
97+ assert "This is a manual module docstring." in docstring_text
98+ assert "It should be preserved and merged with auto-generated content." in docstring_text
99+ # * Verify only one docstring block exists
100+ docstring_blocks = result_content .count ('"""' )
101+ assert docstring_blocks == 2 , f"Expected 2 triple quotes (start and end), found { docstring_blocks } "
102+
103+ def test_existing_auto_docstring_replacement (source_processor ) -> None :
104+ """
105+ Test that existing auto-generated docstrings are properly replaced
106+ when the file is processed again.
107+ """
108+ # * File with existing auto-generated docstring
109+ initial_content = dedent ('''
110+ """
111+ --- AUTO-GENERATED DOCSTRING ---
112+ Table of content is automatically generated by Agent Docstrings v1.3.1
113+ Classes/Functions:
114+ - old_function() (line 8)
115+ --- END AUTO-GENERATED DOCSTRING ---
116+ """
117+ def old_function():
118+ pass
119+ def new_function():
120+ pass
121+ ''' ).strip ()
122+ result_content , lines , _ = source_processor ("test_replacement.py" , initial_content )
123+ # * Find the docstring in the result
124+ docstring_match = re .search (r'"""[\s\S]*?"""' , result_content )
125+ assert docstring_match , "Could not find docstring in processed file"
126+ docstring_text = docstring_match .group (0 )
127+ # * Verify new content is in the docstring
128+ assert "old_function()" in docstring_text
129+ assert "new_function()" in docstring_text
130+ # * Verify only one auto-generated docstring exists in the whole file
131+ auto_markers = result_content .count ("--- AUTO-GENERATED DOCSTRING ---" )
132+ assert auto_markers == 1 , f"Expected 1 auto docstring marker, found { auto_markers } "
133+ # * Verify the version is updated in the docstring
134+ assert "Agent Docstrings v1.3.2" in docstring_text
135+ # * Verify that old_function is mentioned only once *within the docstring*
136+ assert docstring_text .count ("old_function()" ) == 1 , "Function should appear only once in docstring"
137+ assert docstring_text .count ("new_function()" ) == 1 , "Function should appear only once in docstring"
138+
139+ def test_multiple_auto_docstring_removal (source_processor ) -> None :
140+ """
141+ Test that multiple auto-generated docstrings are properly removed
142+ and replaced with a single one.
143+ """
144+ # * File with multiple auto-generated docstrings (simulating a bug)
145+ initial_content = dedent ('''
146+ """
147+ --- AUTO-GENERATED DOCSTRING ---
148+ Table of content is automatically generated by Agent Docstrings v1.3.1
149+ --- END AUTO-GENERATED DOCSTRING ---
150+ """
151+ """
152+ --- AUTO-GENERATED DOCSTRING ---
153+ Table of content is automatically generated by Agent Docstrings v1.3.2
154+ --- END AUTO-GENERATED DOCSTRING ---
155+ Human comments
156+ """
157+ def test_function():
158+ return "test"
159+ ''' ).strip ()
160+ result_content , lines , _ = source_processor ("test_multiple_removal.py" , initial_content )
161+ # * Verify only one auto-generated docstring exists
162+ auto_markers = result_content .count ("--- AUTO-GENERATED DOCSTRING ---" )
163+ assert auto_markers == 1 , f"Expected 1 auto docstring marker, found { auto_markers } "
164+ # * Verify manual content is preserved
165+ assert "Human comments" in result_content
166+ # * Verify function is documented
167+ assert "test_function()" in result_content
168+ # * Verify that there is only one docstring block in the final output
169+ docstring_blocks = re .findall (r'"""[\s\S]*?"""' , result_content )
170+ assert len (docstring_blocks ) == 1 , f"Expected 1 docstring block, found { len (docstring_blocks )} "
0 commit comments