@@ -38,12 +38,30 @@ final class HighlighterTests: XCTestCase {
3838 func attributesFor( _ capture: CaptureName ? ) -> [ NSAttributedString . Key : Any ] { [ : ] }
3939 }
4040
41+ class SentryStorageDelegate : NSObject , NSTextStorageDelegate {
42+ var editedIndices : IndexSet = IndexSet ( )
43+
44+ func textStorage(
45+ _ textStorage: NSTextStorage ,
46+ didProcessEditing editedMask: NSTextStorageEditActions ,
47+ range editedRange: NSRange ,
48+ changeInLength delta: Int ) {
49+ editedIndices. insert ( integersIn: editedRange)
50+ }
51+ }
52+
53+ var attributeProvider : MockAttributeProvider !
54+ var textView : TextView !
55+
56+ override func setUp( ) {
57+ attributeProvider = MockAttributeProvider ( )
58+ textView = Mock . textView ( )
59+ textView. frame = NSRect ( x: 0 , y: 0 , width: 1000 , height: 1000 )
60+ }
61+
4162 @MainActor
4263 func test_canceledHighlightsAreInvalidated( ) {
4364 let highlightProvider = MockHighlightProvider ( )
44- let attributeProvider = MockAttributeProvider ( )
45- let textView = Mock . textView ( )
46- textView. frame = NSRect ( x: 0 , y: 0 , width: 1000 , height: 1000 )
4765 textView. setText ( " Hello World! " )
4866 let highlighter = Mock . highlighter (
4967 textView: textView,
@@ -62,23 +80,8 @@ final class HighlighterTests: XCTestCase {
6280
6381 @MainActor
6482 func test_highlightsDoNotInvalidateEntireTextView( ) {
65- class SentryStorageDelegate : NSObject , NSTextStorageDelegate {
66- var editedIndices : IndexSet = IndexSet ( )
67-
68- func textStorage(
69- _ textStorage: NSTextStorage ,
70- didProcessEditing editedMask: NSTextStorageEditActions ,
71- range editedRange: NSRange ,
72- changeInLength delta: Int ) {
73- editedIndices. insert ( integersIn: editedRange)
74- }
75- }
76-
7783 let highlightProvider = TreeSitterClient ( )
7884 highlightProvider. forceSyncOperation = true
79- let attributeProvider = MockAttributeProvider ( )
80- let textView = Mock . textView ( )
81- textView. frame = NSRect ( x: 0 , y: 0 , width: 1000 , height: 1000 )
8285 textView. setText ( " func helloWorld() { \n \t print( \" Hello World! \" ) \n } " )
8386
8487 let highlighter = Mock . highlighter (
@@ -97,4 +100,49 @@ final class HighlighterTests: XCTestCase {
97100
98101 XCTAssertEqual ( sentryStorage. editedIndices, invalidSet) // Should only cause highlights on the first line
99102 }
103+
104+ // This test isn't testing much highlighter functionality. However, we've seen crashes and other errors after normal
105+ // editing that were caused by the highlighter and would only have been caught by an integration test like this.
106+ @MainActor
107+ func test_editFile( ) {
108+ let highlightProvider = TreeSitterClient ( )
109+ highlightProvider. forceSyncOperation = true
110+ textView. setText ( " func helloWorld() { \n \t print( \" Hello World! \" ) \n } " ) // 44 chars
111+
112+ let highlighter = Mock . highlighter (
113+ textView: textView,
114+ highlightProvider: highlightProvider,
115+ attributeProvider: attributeProvider
116+ )
117+ textView. addStorageDelegate ( highlighter)
118+ highlighter. setLanguage ( language: . swift)
119+ highlighter. invalidate ( )
120+
121+ // Delete Characters
122+ textView. replaceCharacters ( in: [ NSRange ( location: 43 , length: 1 ) ] , with: " " )
123+ textView. replaceCharacters ( in: [ NSRange ( location: 0 , length: 4 ) ] , with: " " )
124+ textView. replaceCharacters ( in: [ NSRange ( location: 6 , length: 5 ) ] , with: " " )
125+ textView. replaceCharacters ( in: [ NSRange ( location: 25 , length: 5 ) ] , with: " " )
126+
127+ XCTAssertEqual ( textView. string, " hello() { \n \t print( \" Hello ! \" ) \n " )
128+
129+ // Insert Characters
130+ textView. replaceCharacters ( in: [ NSRange ( location: 29 , length: 0 ) ] , with: " } " )
131+ textView. replaceCharacters (
132+ in: [ NSRange ( location: 25 , length: 0 ) , NSRange ( location: 6 , length: 0 ) ] ,
133+ with: " World "
134+ )
135+ // emulate typing with a cursor
136+ textView. selectionManager. setSelectedRange ( NSRange ( location: 0 , length: 0 ) )
137+ textView. insertText ( " f " )
138+ textView. insertText ( " u " )
139+ textView. insertText ( " n " )
140+ textView. insertText ( " c " )
141+ XCTAssertEqual ( textView. string, " func helloWorld() { \n \t print( \" Hello World! \" ) \n } " )
142+
143+ // Replace contents
144+ textView. replaceCharacters ( in: textView. documentRange, with: " " )
145+ textView. insertText ( " func helloWorld() { \n \t print( \" Hello World! \" ) \n } " )
146+ XCTAssertEqual ( textView. string, " func helloWorld() { \n \t print( \" Hello World! \" ) \n } " )
147+ }
100148}
0 commit comments