|
| 1 | +import pytest |
| 2 | +from cedarscript_ast_parser import RelativeMarker, RelativePositionType, MarkerType |
| 3 | +from text_manipulation import RangeSpec |
| 4 | +from text_manipulation.text_editor_kit import segment_to_search_range |
| 5 | + |
| 6 | + |
| 7 | +def test_basic_segment_search(): |
| 8 | + # Test input |
| 9 | + lines = """ |
| 10 | +# |
| 11 | +# |
| 12 | +# |
| 13 | +# |
| 14 | +# |
| 15 | +# |
| 16 | +def _(): |
| 17 | + pass |
| 18 | +def hello(self): |
| 19 | + print('hello'), |
| 20 | + return None, |
| 21 | + x = 1 |
| 22 | +""".strip().splitlines() |
| 23 | + content = """ |
| 24 | +def hello(self, OK): |
| 25 | + # OK ! |
| 26 | + """.strip().splitlines() |
| 27 | + expected = """ |
| 28 | +# |
| 29 | +# |
| 30 | +# |
| 31 | +# |
| 32 | +# |
| 33 | +# |
| 34 | +def _(): |
| 35 | + pass |
| 36 | +def hello(self, OK): |
| 37 | + # OK ! |
| 38 | + print('hello'), |
| 39 | + return None, |
| 40 | + x = 1 |
| 41 | +""".strip().splitlines() |
| 42 | + |
| 43 | + # To represent a RangeSpec that starts at line 1 and ends at line 1, we must transform from line numbering to indexes. |
| 44 | + # NOTE: in RangeSpec, we use index values, not line numbers. So for the first line (line 1), the index is 0 |
| 45 | + # Also, the end index is EXCLUSIVE, so if you want a range that covers index 0, use RangeSpec(0, 1) |
| 46 | + |
| 47 | + # We want to restrict our search to start at line 9 which is `def hello(self):` in array 'lines' |
| 48 | + # (so it's index 8) and end after the last line |
| 49 | + search_range = RangeSpec(8, len(lines)) |
| 50 | + |
| 51 | + # Point to line 1 in our search_range (which is line 9 overall which is 'def hello():') |
| 52 | + # The relative_start_marker points to AFTER line 0, which is line 1 in our search_range |
| 53 | + relative_start_marker = RelativeMarker( |
| 54 | + RelativePositionType.AFTER, |
| 55 | + type=MarkerType.LINE, |
| 56 | + value=0, # but as this marker is AFTER, it points to line 1 |
| 57 | + marker_subtype='number' |
| 58 | + ) |
| 59 | + # The relative_end_marker should point to BEFORE line 2, which is line 1 in our search_range. |
| 60 | + relative_end_marker = relative_start_marker.with_qualifier(RelativePositionType.BEFORE) |
| 61 | + relative_end_marker.value = 2 # but as this marker is BEFORE, it points to line 1 |
| 62 | + |
| 63 | + # So now, both relative_start_marker and relative_end_marker point to line 1 (relative to the search range) |
| 64 | + # In terms of indexes, both point to index 0. |
| 65 | + # When converting this tuple(relative_start_marker, relative_end_marker) to a single absolute RangeSpec, |
| 66 | + # the expected RangeSpec instance should be RangeSpec(2, 3) which means it corresponds to absolute lines |
| 67 | + # from line 3 up to line 3 (inclusive). |
| 68 | + |
| 69 | + # call the method to search inside the range 'search_range' for the segment |
| 70 | + result: RangeSpec = segment_to_search_range( |
| 71 | + lines, relative_start_marker, relative_end_marker, search_range=search_range |
| 72 | + ) |
| 73 | + |
| 74 | + # Verify results |
| 75 | + assert result.start == 8, 'start: should be absolute line 9 (so absolute index 8)' |
| 76 | + assert result.end == 9, "end: should be absolute line 10 (it's exclusive), so should be absolute index 9" |
| 77 | + assert result.indent == 4, "Indent level should be 4, because line 9 has no indentation" |
| 78 | + |
| 79 | + result.write(content, lines) |
| 80 | + # Check the actual content |
| 81 | + assert lines == expected |
0 commit comments