@@ -35,7 +35,7 @@ struct SemanticTokenStorageTests {
35
35
@Test
36
36
func initialState( ) async throws {
37
37
#expect( storage. state == nil )
38
- #expect( storage. hasTokens == false )
38
+ #expect( storage. hasReceivedData == false )
39
39
#expect( storage. lastResultId == nil )
40
40
}
41
41
@@ -53,36 +53,147 @@ struct SemanticTokenStorageTests {
53
53
#expect( state. resultId == " 1234 " )
54
54
55
55
#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
+ }
57
75
}
58
76
59
77
@Suite ( " ApplyDeltas " )
60
78
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
62
101
63
102
let semanticTokens = [
64
103
SemanticToken ( line: 0 , char: 0 , length: 10 , type: 0 , modifiers: 0 ) ,
65
104
SemanticToken ( line: 1 , char: 2 , length: 5 , type: 2 , modifiers: 3 ) ,
66
105
SemanticToken ( line: 3 , char: 8 , length: 10 , type: 1 , modifiers: 0 )
67
106
]
68
107
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)
79
170
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 ) )
81
176
}
82
177
83
178
@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)
85
187
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 ] )
86
197
}
87
198
}
88
199
}
0 commit comments