@@ -35,7 +35,7 @@ struct SemanticTokenStorageTests {
3535 @Test
3636 func initialState( ) async throws {
3737 #expect( storage. state == nil )
38- #expect( storage. hasTokens == false )
38+ #expect( storage. hasReceivedData == false )
3939 #expect( storage. lastResultId == nil )
4040 }
4141
@@ -53,36 +53,147 @@ struct SemanticTokenStorageTests {
5353 #expect( state. resultId == " 1234 " )
5454
5555 #expect( storage. lastResultId == " 1234 " )
56- #expect( storage. hasTokens == true )
56+ #expect( storage. hasReceivedData == true )
57+ }
58+
59+ @Test
60+ func overwriteDataRepeatedly( ) async throws {
61+ let dataToApply : [ ( String ? , [ SemanticToken ] ) ] = [
62+ ( nil , semanticTokens) ,
63+ ( " 1 " , [ ] ) ,
64+ ( " 2 " , semanticTokens. dropLast ( ) ) ,
65+ ( " 3 " , semanticTokens)
66+ ]
67+ for (resultId, tokens) in dataToApply {
68+ storage. setData ( SemanticTokens ( resultId: resultId, tokens: tokens) )
69+ let state = try #require( storage. state)
70+ #expect( state. tokens == tokens)
71+ #expect( state. resultId == resultId)
72+ #expect( storage. lastResultId == resultId)
73+ #expect( storage. hasReceivedData == true )
74+ }
5775 }
5876
5977 @Suite ( " ApplyDeltas " )
6078 struct TokensDeltasTests {
61- let storage = SemanticTokenStorage ( )
79+ struct DeltaEdit {
80+ let start : Int
81+ let deleteCount : Int
82+ let data : [ Int ]
83+
84+ func makeString( ) -> String {
85+ let dataString = data. map { String ( $0) } . joined ( separator: " , " )
86+ return " { \" start \" : \( start) , \" deleteCount \" : \( deleteCount) , \" data \" : [ \( dataString) ] } "
87+ }
88+ }
89+
90+ func makeDelta( resultId: String , edits: [ DeltaEdit ] ) throws -> SemanticTokensDelta {
91+ // This is unfortunate, but there's no public initializer for these structs.
92+ // So we have to decode them from JSON strings
93+ let editsString = edits. map { $0. makeString ( ) } . joined ( separator: " , " )
94+ let deltasJSON = " { \" resultId \" : \" \( resultId) \" , \" edits \" : [ \( editsString) ] } "
95+ let decoder = JSONDecoder ( )
96+ let deltas = try decoder. decode ( SemanticTokensDelta . self, from: Data ( deltasJSON. utf8) )
97+ return deltas
98+ }
99+
100+ let storage : SemanticTokenStorage
62101
63102 let semanticTokens = [
64103 SemanticToken ( line: 0 , char: 0 , length: 10 , type: 0 , modifiers: 0 ) ,
65104 SemanticToken ( line: 1 , char: 2 , length: 5 , type: 2 , modifiers: 3 ) ,
66105 SemanticToken ( line: 3 , char: 8 , length: 10 , type: 1 , modifiers: 0 )
67106 ]
68107
69- @Test (
70- arguments: [
71- #"{ "resultId": "1", "edits": [{"start": 0, "deleteCount": 0, "data": [0, 2, 3, 0, 1] }] }"#
72- ]
73- )
74- func applyDeltas( deltasJSON: String ) async throws {
75- // This is unfortunate, but there's no public initializer for these structs.
76- // So we have to decode them from JSON strings
77- let decoder = JSONDecoder ( )
78- let deltas = try decoder. decode ( SemanticTokensDelta . self, from: Data ( deltasJSON. utf8) )
108+ init ( ) {
109+ storage = SemanticTokenStorage ( )
110+ storage. setData ( SemanticTokens ( tokens: semanticTokens) )
111+ #expect( storage. state? . tokens == semanticTokens)
112+ }
113+
114+ @Test
115+ func applyEmptyDeltasNoChange( ) throws {
116+ let deltas = try makeDelta ( resultId: " 1 " , edits: [ ] )
117+
118+ _ = storage. applyDelta ( deltas)
119+
120+ let state = try #require( storage. state)
121+ #expect( state. tokens. count == 3 )
122+ #expect( state. resultId == " 1 " )
123+ #expect( state. tokens == semanticTokens)
124+ }
125+
126+ @Test
127+ func applyInsertDeltas( ) throws {
128+ let deltas = try makeDelta ( resultId: " 1 " , edits: [ . init( start: 0 , deleteCount: 0 , data: [ 0 , 2 , 3 , 0 , 1 ] ) ] )
129+
130+ _ = storage. applyDelta ( deltas)
131+
132+ let state = try #require( storage. state)
133+ #expect( state. tokens. count == 4 )
134+ #expect( storage. lastResultId == " 1 " )
135+
136+ // Should have inserted one at the beginning
137+ #expect( state. tokens [ 0 ] . line == 0 )
138+ #expect( state. tokens [ 0 ] . char == 2 )
139+ #expect( state. tokens [ 0 ] . length == 3 )
140+ #expect( state. tokens [ 0 ] . modifiers == 1 )
141+
142+ // We inserted a delta into the space before this one (at char 2) so this one starts at the same spot
143+ #expect( state. tokens [ 1 ] == SemanticToken ( line: 0 , char: 2 , length: 10 , type: 0 , modifiers: 0 ) )
144+ #expect( state. tokens [ 2 ] == semanticTokens [ 1 ] )
145+ #expect( state. tokens [ 3 ] == semanticTokens [ 2 ] )
146+ }
147+
148+ @Test
149+ func applyDeleteOneDeltas( ) throws {
150+ // Delete the second token (semanticTokens[1]) from the initial state.
151+ // Each token is represented by 5 numbers, so token[1] starts at raw data index 5.
152+ let deltas = try makeDelta ( resultId: " 2 " , edits: [ . init( start: 5 , deleteCount: 5 , data: [ ] ) ] )
153+ _ = storage. applyDelta ( deltas)
154+
155+ let state = try #require( storage. state)
156+ #expect( state. tokens. count == 2 )
157+ #expect( state. resultId == " 2 " )
158+ // The remaining tokens should be the first and third tokens, except we deleted one line between them
159+ // so the third token's line is less one
160+ #expect( state. tokens [ 0 ] == semanticTokens [ 0 ] )
161+ #expect( state. tokens [ 1 ] == SemanticToken ( line: 2 , char: 8 , length: 10 , type: 1 , modifiers: 0 ) )
162+ }
163+
164+ @Test
165+ func applyDeleteManyDeltas( ) throws {
166+ // Delete the first two tokens from the initial state.
167+ // Token[0] and token[1] together use 10 integers.
168+ let deltas = try makeDelta ( resultId: " 3 " , edits: [ . init( start: 0 , deleteCount: 10 , data: [ ] ) ] )
169+ _ = storage. applyDelta ( deltas)
79170
80-
171+ let state = try #require( storage. state)
172+ #expect( state. tokens. count == 1 )
173+ #expect( state. resultId == " 3 " )
174+ // The only remaining token should be the original third token.
175+ #expect( state. tokens [ 0 ] == SemanticToken ( line: 2 , char: 8 , length: 10 , type: 1 , modifiers: 0 ) )
81176 }
82177
83178 @Test
84- func invalidatedRanges( ) {
179+ func applyInsertAndDeleteDeltas( ) throws {
180+ // Combined test: insert a token at the beginning and delete the last token.
181+ // Edit 1: Insert a new token at the beginning.
182+ let insertion = DeltaEdit ( start: 0 , deleteCount: 0 , data: [ 0 , 2 , 3 , 0 , 1 ] )
183+ // Edit 2: Delete the token that starts at raw data index 10 (the third token in the original state).
184+ let deletion = DeltaEdit ( start: 10 , deleteCount: 5 , data: [ ] )
185+ let deltas = try makeDelta ( resultId: " 4 " , edits: [ insertion, deletion] )
186+ _ = storage. applyDelta ( deltas)
85187
188+ let state = try #require( storage. state)
189+ #expect( state. tokens. count == 3 )
190+ #expect( storage. lastResultId == " 4 " )
191+ // The new inserted token becomes the first token.
192+ #expect( state. tokens [ 0 ] == SemanticToken ( line: 0 , char: 2 , length: 3 , type: 0 , modifiers: 1 ) )
193+ // The original first token is shifted (its character offset increased by 2).
194+ #expect( state. tokens [ 1 ] == SemanticToken ( line: 0 , char: 2 , length: 10 , type: 0 , modifiers: 0 ) )
195+ // The second token from the original state remains unchanged.
196+ #expect( state. tokens [ 2 ] == semanticTokens [ 1 ] )
86197 }
87198 }
88199}
0 commit comments