@@ -17,15 +17,19 @@ describe("mergeOverlappingDecorations", () => {
17
17
} ,
18
18
] ;
19
19
const result = mergeOverlappingDecorations ( input ) ;
20
- // Only the first decoration should be present, as there is no true overlap
21
- expect ( result ) . toEqual ( [
22
- {
23
- start : { line : 0 , character : 0 } ,
24
- end : { line : 0 , character : 1 } ,
25
- properties : { class : "hat default" } ,
26
- alwaysWrap : true ,
27
- } ,
28
- ] ) ;
20
+ // The zero-width selection should be merged into the previous mark as selectionRight
21
+ expect ( result ) . toEqual (
22
+ expect . arrayContaining ( [
23
+ expect . objectContaining ( {
24
+ start : { line : 0 , character : 0 } ,
25
+ end : { line : 0 , character : 1 } ,
26
+ properties : { class : expect . stringContaining ( "hat default selectionRight" ) } ,
27
+ alwaysWrap : true ,
28
+ } ) ,
29
+ ] )
30
+ ) ;
31
+ // Should not include the zero-width selection
32
+ expect ( result . some ( d => d . properties ?. class === "selection" ) ) . toBe ( false ) ;
29
33
} ) ;
30
34
31
35
it ( "returns non-overlapping decorations unchanged" , ( ) => {
@@ -93,4 +97,133 @@ describe("mergeOverlappingDecorations", () => {
93
97
properties : { class : "B" } ,
94
98
} ) ;
95
99
} ) ;
100
+
101
+ it ( "preserves zero-width (selection) decorations alongside others" , ( ) => {
102
+ const input = [
103
+ {
104
+ start : { line : 0 , character : 0 } ,
105
+ end : { line : 0 , character : 1 } ,
106
+ properties : { class : "sourceMark" } ,
107
+ alwaysWrap : true ,
108
+ } ,
109
+ {
110
+ start : { line : 0 , character : 1 } ,
111
+ end : { line : 0 , character : 2 } ,
112
+ properties : { class : "thatMark" } ,
113
+ alwaysWrap : true ,
114
+ } ,
115
+ {
116
+ start : { line : 0 , character : 2 } ,
117
+ end : { line : 0 , character : 2 } , // zero-width selection
118
+ properties : { class : "selection" } ,
119
+ alwaysWrap : true ,
120
+ } ,
121
+ ] ;
122
+ const result = mergeOverlappingDecorations ( input ) ;
123
+ // The zero-width selection should be merged into the previous mark as selectionRight
124
+ expect ( result ) . toEqual (
125
+ expect . arrayContaining ( [
126
+ expect . objectContaining ( {
127
+ start : { line : 0 , character : 0 } ,
128
+ end : { line : 0 , character : 1 } ,
129
+ properties : { class : "sourceMark" } ,
130
+ alwaysWrap : true ,
131
+ } ) ,
132
+ expect . objectContaining ( {
133
+ start : { line : 0 , character : 1 } ,
134
+ end : { line : 0 , character : 2 } ,
135
+ properties : { class : expect . stringContaining ( "thatMark selectionRight" ) } ,
136
+ alwaysWrap : true ,
137
+ } ) ,
138
+ ] )
139
+ ) ;
140
+ // Should not include the zero-width selection
141
+ expect ( result . some ( d => d . properties ?. class === "selection" ) ) . toBe ( false ) ;
142
+ } ) ;
143
+
144
+ it ( "merges zero-width selection at end into previous mark as selectionRight" , ( ) => {
145
+ const input = [
146
+ {
147
+ start : { line : 0 , character : 0 } ,
148
+ end : { line : 0 , character : 1 } ,
149
+ properties : { class : "sourceMark" } ,
150
+ alwaysWrap : true ,
151
+ } ,
152
+ {
153
+ start : { line : 0 , character : 1 } ,
154
+ end : { line : 0 , character : 2 } ,
155
+ properties : { class : "thatMark" } ,
156
+ alwaysWrap : true ,
157
+ } ,
158
+ {
159
+ start : { line : 0 , character : 2 } ,
160
+ end : { line : 0 , character : 2 } , // zero-width selection
161
+ properties : { class : "selection" } ,
162
+ alwaysWrap : true ,
163
+ } ,
164
+ ] ;
165
+ const result = mergeOverlappingDecorations ( input ) ;
166
+ // The zero-width selection should be deleted, and the thatMark should have selectionRight
167
+ expect ( result ) . toEqual (
168
+ expect . arrayContaining ( [
169
+ expect . objectContaining ( {
170
+ start : { line : 0 , character : 0 } ,
171
+ end : { line : 0 , character : 1 } ,
172
+ properties : { class : "sourceMark" } ,
173
+ alwaysWrap : true ,
174
+ } ) ,
175
+ expect . objectContaining ( {
176
+ start : { line : 0 , character : 1 } ,
177
+ end : { line : 0 , character : 2 } ,
178
+ properties : { class : expect . stringContaining ( "thatMark selectionRight" ) } ,
179
+ alwaysWrap : true ,
180
+ } ) ,
181
+ ] )
182
+ ) ;
183
+ // Should not include the zero-width selection
184
+ expect ( result . some ( d => d . properties ?. class === "selection" ) ) . toBe ( false ) ;
185
+ } ) ;
186
+
187
+ it ( "merges zero-width selection at start into next mark as selectionLeft" , ( ) => {
188
+ const input = [
189
+ {
190
+ start : { line : 0 , character : 0 } ,
191
+ end : { line : 0 , character : 1 } ,
192
+ properties : { class : "sourceMark" } ,
193
+ alwaysWrap : true ,
194
+ } ,
195
+ {
196
+ start : { line : 0 , character : 1 } ,
197
+ end : { line : 0 , character : 2 } ,
198
+ properties : { class : "thatMark" } ,
199
+ alwaysWrap : true ,
200
+ } ,
201
+ {
202
+ start : { line : 0 , character : 1 } ,
203
+ end : { line : 0 , character : 1 } , // zero-width selection at start of thatMark
204
+ properties : { class : "selection" } ,
205
+ alwaysWrap : true ,
206
+ } ,
207
+ ] ;
208
+ const result = mergeOverlappingDecorations ( input ) ;
209
+ // The zero-width selection should be merged into the next mark as selectionLeft
210
+ expect ( result ) . toEqual (
211
+ expect . arrayContaining ( [
212
+ expect . objectContaining ( {
213
+ start : { line : 0 , character : 0 } ,
214
+ end : { line : 0 , character : 1 } ,
215
+ properties : { class : "sourceMark" } ,
216
+ alwaysWrap : true ,
217
+ } ) ,
218
+ expect . objectContaining ( {
219
+ start : { line : 0 , character : 1 } ,
220
+ end : { line : 0 , character : 2 } ,
221
+ properties : { class : expect . stringContaining ( "thatMark selectionLeft" ) } ,
222
+ alwaysWrap : true ,
223
+ } ) ,
224
+ ] )
225
+ ) ;
226
+ // Should not include the zero-width selection
227
+ expect ( result . some ( d => d . properties ?. class === "selection" ) ) . toBe ( false ) ;
228
+ } ) ;
96
229
} ) ;
0 commit comments