@@ -40,12 +40,160 @@ def greet(self):
40
40
yield codebase
41
41
42
42
43
+ @pytest .fixture
44
+ def large_codebase (tmpdir ):
45
+ """Create a codebase with a large file for pagination testing."""
46
+ # Create a large file with predictable content
47
+ large_file_lines = []
48
+ # Add imports at the top
49
+ large_file_lines .extend (
50
+ [
51
+ "from __future__ import annotations" ,
52
+ "import sys" ,
53
+ "import os" ,
54
+ "from typing import List, Optional, Dict" ,
55
+ "" ,
56
+ "# Constants" ,
57
+ "MAX_ITEMS = 100" ,
58
+ "DEBUG = False" ,
59
+ "" ,
60
+ "# Main class definition" ,
61
+ "class LargeClass:" ,
62
+ ]
63
+ )
64
+
65
+ # Add methods with incrementing numbers
66
+ for i in range (1 , 401 ): # This will create a 400+ line file
67
+ if i % 20 == 0 :
68
+ # Add some class methods periodically
69
+ large_file_lines .extend ([" @classmethod" , f" def class_method_{ i } (cls) -> None:" , f" print('Class method { i } ')" , " return None" , "" ])
70
+ else :
71
+ # Add regular methods
72
+ large_file_lines .extend (
73
+ [
74
+ f" def method_{ i } (self, param_{ i } : int) -> str:" ,
75
+ f" # Method { i } does something interesting" ,
76
+ f" value = param_{ i } * { i } " ,
77
+ f" return f'Method { i } computed: {{value}}'" ,
78
+ "" ,
79
+ ]
80
+ )
81
+
82
+ large_file_content = "\n " .join (large_file_lines )
83
+
84
+ files = {
85
+ "src/main.py" : """
86
+ def hello():
87
+ print("Hello, world!")
88
+ """ ,
89
+ "src/large_file.py" : large_file_content ,
90
+ }
91
+
92
+ with get_codebase_session (tmpdir = tmpdir , files = files ) as codebase :
93
+ yield codebase
94
+
95
+
43
96
def test_view_file (codebase ):
44
97
"""Test viewing a file."""
98
+ # Test basic file viewing
45
99
result = view_file (codebase , "src/main.py" )
46
100
assert result .status == "success"
47
101
assert result .filepath == "src/main.py"
48
102
assert "hello()" in result .content
103
+ # For small files, pagination fields should not be present
104
+ assert result .start_line is None
105
+ assert result .end_line is None
106
+ assert result .has_more is None
107
+ assert result .max_lines_per_page is None
108
+
109
+
110
+ def test_view_file_pagination (large_codebase ):
111
+ """Test viewing a file with pagination."""
112
+ # Test default pagination (should show first max_lines lines)
113
+ result = view_file (large_codebase , "src/large_file.py" )
114
+ assert result .status == "success"
115
+ assert result .start_line == 1
116
+ assert result .end_line == 250 # Default max_lines
117
+ assert result .has_more is True
118
+ assert result .max_lines_per_page == 250
119
+ assert "from __future__ import annotations" in result .content # First line
120
+ assert "def method_1" in result .content # Early method
121
+ assert "def method_251" not in result .content # Method after page 1
122
+
123
+ # Test custom pagination range
124
+ result = view_file (large_codebase , "src/large_file.py" , start_line = 200 , end_line = 250 )
125
+ assert result .status == "success"
126
+ assert result .start_line == 200
127
+ assert result .end_line == 250
128
+ assert result .has_more is True
129
+ assert "def method_39" in result .content # Regular method before class method
130
+ assert "def class_method_40" in result .content # Class method at 40
131
+ assert "def method_41" in result .content # Regular method after class method
132
+ assert "from __future__ import annotations" not in result .content # Before range
133
+ assert "def method_251" not in result .content # After range
134
+
135
+ # Test viewing end of file
136
+ result = view_file (large_codebase , "src/large_file.py" , start_line = 350 )
137
+ assert result .status == "success"
138
+ assert result .start_line == 350
139
+ assert result .has_more is True # File has 2010 lines, so there should be more content
140
+ assert "def method_69" in result .content # Regular method
141
+ assert "def class_method_80" in result .content # Class method at 80
142
+ assert result .end_line == 599 # Should show 250 lines from start (350 to 599)
143
+
144
+ # Test custom max_lines
145
+ result = view_file (large_codebase , "src/large_file.py" , max_lines = 100 )
146
+ assert result .status == "success"
147
+ assert result .start_line == 1
148
+ assert result .end_line == 100
149
+ assert result .has_more is True
150
+ assert result .max_lines_per_page == 100
151
+ assert "from __future__ import annotations" in result .content
152
+ assert len (result .content .splitlines ()) <= 100
153
+
154
+ # Test line numbers display
155
+ result = view_file (large_codebase , "src/large_file.py" , start_line = 198 , end_line = 202 , line_numbers = True )
156
+ assert result .status == "success"
157
+ assert "198|" in result .content
158
+ assert "199|" in result .content
159
+ assert "200|" in result .content
160
+ assert "201|" in result .content
161
+ assert "202|" in result .content
162
+
163
+ # Test without line numbers
164
+ result = view_file (large_codebase , "src/large_file.py" , start_line = 198 , end_line = 202 , line_numbers = False )
165
+ assert result .status == "success"
166
+ assert "198|" not in result .content
167
+ assert "199|" not in result .content
168
+
169
+
170
+ def test_view_file_pagination_edge_cases (large_codebase ):
171
+ """Test edge cases for file pagination."""
172
+ # Test start_line > end_line (should respect provided end_line)
173
+ result = view_file (large_codebase , "src/large_file.py" , start_line = 200 , end_line = 100 )
174
+ assert result .status == "success"
175
+ assert result .start_line == 200
176
+ assert result .end_line == 100 # Should respect provided end_line
177
+ assert result .content == "" # No content since end_line < start_line
178
+
179
+ # Test start_line > file length (should adjust to valid range)
180
+ result = view_file (large_codebase , "src/large_file.py" , start_line = 2000 )
181
+ assert result .status == "success"
182
+ assert result .start_line == 2000 # Should use provided start_line
183
+ assert result .end_line == 2010 # Should adjust to total lines
184
+ assert result .has_more is False
185
+
186
+ # Test end_line > file length (should truncate to file length)
187
+ result = view_file (large_codebase , "src/large_file.py" , start_line = 200 , end_line = 2000 )
188
+ assert result .status == "success"
189
+ assert result .start_line == 200
190
+ assert result .end_line == min (200 + 250 - 1 , 2010 ) # Should respect max_lines and file length
191
+
192
+ # Test negative start_line (should default to 1)
193
+ result = view_file (large_codebase , "src/large_file.py" , start_line = - 10 )
194
+ assert result .status == "success"
195
+ assert result .start_line == 1
196
+ assert result .end_line == 250
49
197
50
198
51
199
def test_list_directory (codebase ):
0 commit comments