1
+ /*
2
+ * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3
+ */
4
+
5
+ package kotlinx.rpc.grpc.internal
6
+
7
+ import kotlinx.rpc.grpc.utils.BitSet
8
+ import kotlin.test.*
9
+
10
+ class BitSetTest {
11
+
12
+ @Test
13
+ fun testConstructor () {
14
+ // Test with size 0
15
+ val bitSet0 = BitSet (0 )
16
+ assertEquals(0 , bitSet0.size)
17
+ assertEquals(0 , bitSet0.cardinality())
18
+
19
+ // Test with small size
20
+ val bitSet10 = BitSet (10 )
21
+ assertEquals(10 , bitSet10.size)
22
+ assertEquals(0 , bitSet10.cardinality())
23
+
24
+ // Test with size that spans multiple words
25
+ val bitSet100 = BitSet (100 )
26
+ assertEquals(100 , bitSet100.size)
27
+ assertEquals(0 , bitSet100.cardinality())
28
+
29
+ // Test with size at word boundary
30
+ val bitSet64 = BitSet (64 )
31
+ assertEquals(64 , bitSet64.size)
32
+ assertEquals(0 , bitSet64.cardinality())
33
+
34
+ // Test with size just over word boundary
35
+ val bitSet65 = BitSet (65 )
36
+ assertEquals(65 , bitSet65.size)
37
+ assertEquals(0 , bitSet65.cardinality())
38
+ }
39
+
40
+ @Test
41
+ fun testSetAndGet () {
42
+ val bitSet = BitSet (100 )
43
+
44
+ // Initially all bits should be unset
45
+ for (i in 0 until 100 ) {
46
+ assertFalse(bitSet[i], " Bit $i should be initially unset" )
47
+ }
48
+
49
+ // Set some bits
50
+ bitSet[0 ] = true
51
+ bitSet[1 ] = true
52
+ bitSet[63 ] = true
53
+ bitSet[64 ] = true
54
+ bitSet[99 ] = true
55
+
56
+ // Verify the bits are set
57
+ assertTrue(bitSet[0 ], " Bit 0 should be set" )
58
+ assertTrue(bitSet[1 ], " Bit 1 should be set" )
59
+ assertTrue(bitSet[63 ], " Bit 63 should be set" )
60
+ assertTrue(bitSet[64 ], " Bit 64 should be set" )
61
+ assertTrue(bitSet[99 ], " Bit 99 should be set" )
62
+
63
+ // Verify other bits are still unset
64
+ assertFalse(bitSet[2 ], " Bit 2 should be unset" )
65
+ assertFalse(bitSet[62 ], " Bit 62 should be unset" )
66
+ assertFalse(bitSet[65 ], " Bit 65 should be unset" )
67
+ assertFalse(bitSet[98 ], " Bit 98 should be unset" )
68
+ }
69
+
70
+ @Test
71
+ fun testClear () {
72
+ val bitSet = BitSet (100 )
73
+
74
+ // Set all bits
75
+ for (i in 0 until 100 ) {
76
+ bitSet[i] = true
77
+ }
78
+
79
+ // Verify all bits are set
80
+ for (i in 0 until 100 ) {
81
+ assertTrue(bitSet[i], " Bit $i should be set" )
82
+ }
83
+
84
+ // Clear some bits
85
+ bitSet[0 ] = false
86
+ bitSet[1 ] = false
87
+ bitSet[63 ] = false
88
+ bitSet[64 ] = false
89
+ bitSet[99 ] = false
90
+
91
+ // Verify the bits are cleared
92
+ assertFalse(bitSet[0 ], " Bit 0 should be cleared" )
93
+ assertFalse(bitSet[1 ], " Bit 1 should be cleared" )
94
+ assertFalse(bitSet[63 ], " Bit 63 should be cleared" )
95
+ assertFalse(bitSet[64 ], " Bit 64 should be cleared" )
96
+ assertFalse(bitSet[99 ], " Bit 99 should be cleared" )
97
+
98
+ // Verify other bits are still set
99
+ assertTrue(bitSet[2 ], " Bit 2 should still be set" )
100
+ assertTrue(bitSet[62 ], " Bit 62 should still be set" )
101
+ assertTrue(bitSet[65 ], " Bit 65 should still be set" )
102
+ assertTrue(bitSet[98 ], " Bit 98 should still be set" )
103
+ }
104
+
105
+ @Test
106
+ fun testClearAll () {
107
+ val bitSet = BitSet (100 )
108
+
109
+ // Set all bits
110
+ for (i in 0 until 100 ) {
111
+ bitSet[i] = true
112
+ }
113
+
114
+ // Verify all bits are set
115
+ for (i in 0 until 100 ) {
116
+ assertTrue(bitSet[i], " Bit $i should be set" )
117
+ }
118
+
119
+ // Clear all bits
120
+ bitSet.clearAll()
121
+
122
+ // Verify all bits are cleared
123
+ for (i in 0 until 100 ) {
124
+ assertFalse(bitSet[i], " Bit $i should be cleared after clearAll" )
125
+ }
126
+ }
127
+
128
+ @Test
129
+ fun testCardinality () {
130
+ val bitSet = BitSet (100 )
131
+ assertEquals(0 , bitSet.cardinality(), " Initial cardinality should be 0" )
132
+
133
+ // Set some bits
134
+ bitSet[0 ] = true
135
+ assertEquals(1 , bitSet.cardinality(), " Cardinality should be 1 after setting 1 bit" )
136
+
137
+ bitSet[63 ] = true
138
+ assertEquals(2 , bitSet.cardinality(), " Cardinality should be 2 after setting 2 bits" )
139
+
140
+ bitSet[64 ] = true
141
+ assertEquals(3 , bitSet.cardinality(), " Cardinality should be 3 after setting 3 bits" )
142
+
143
+ bitSet[99 ] = true
144
+ assertEquals(4 , bitSet.cardinality(), " Cardinality should be 4 after setting 4 bits" )
145
+
146
+ // Clear a bit
147
+ bitSet.clear(0 )
148
+ assertEquals(3 , bitSet.cardinality(), " Cardinality should be 3 after clearing 1 bit" )
149
+
150
+ // Set a bit that's already set
151
+ bitSet[63 ] = true
152
+ assertEquals(3 , bitSet.cardinality(), " Cardinality should still be 3 after setting an already set bit" )
153
+
154
+ // Clear all bits
155
+ bitSet.clearAll()
156
+ assertEquals(0 , bitSet.cardinality(), " Cardinality should be 0 after clearAll" )
157
+ }
158
+
159
+ @Test
160
+ fun testAllSet () {
161
+ // Test with empty BitSet
162
+ val emptyBitSet = BitSet (0 )
163
+ assertTrue(emptyBitSet.allSet(), " Empty BitSet should return true for allSet" )
164
+
165
+ // Test with small BitSet
166
+ val smallBitSet = BitSet (5 )
167
+ assertFalse(smallBitSet.allSet(), " New BitSet should return false for allSet" )
168
+
169
+ smallBitSet[0 ] = true
170
+ smallBitSet[1 ] = true
171
+ smallBitSet[2 ] = true
172
+ smallBitSet[3 ] = true
173
+ smallBitSet[4 ] = true
174
+ assertTrue(smallBitSet.allSet(), " BitSet with all bits set should return true for allSet" )
175
+
176
+ smallBitSet.clear(2 )
177
+ assertFalse(smallBitSet.allSet(), " BitSet with one bit cleared should return false for allSet" )
178
+
179
+ // Test with BitSet that spans multiple words
180
+ val largeBitSet = BitSet (100 )
181
+ assertFalse(largeBitSet.allSet(), " New large BitSet should return false for allSet" )
182
+
183
+ for (i in 0 until 100 ) {
184
+ largeBitSet[i] = true
185
+ }
186
+ assertTrue(largeBitSet.allSet(), " Large BitSet with all bits set should return true for allSet" )
187
+
188
+ largeBitSet.clear(63 )
189
+ assertFalse(largeBitSet.allSet(), " Large BitSet with one bit cleared should return false for allSet" )
190
+
191
+ // Test with BitSet at word boundary
192
+ val wordBoundaryBitSet = BitSet (64 )
193
+ assertFalse(wordBoundaryBitSet.allSet(), " New word boundary BitSet should return false for allSet" )
194
+
195
+ for (i in 0 until 64 ) {
196
+ wordBoundaryBitSet[i] = true
197
+ }
198
+ assertTrue(wordBoundaryBitSet.allSet(), " Word boundary BitSet with all bits set should return true for allSet" )
199
+ }
200
+
201
+ @Test
202
+ fun testEdgeCases () {
203
+ val bitSet = BitSet (100 )
204
+
205
+ // Test setting and getting at boundaries
206
+ bitSet[0 ] = true
207
+ assertTrue(bitSet[0 ], " Should be able to set and get bit 0" )
208
+
209
+ bitSet[99 ] = true
210
+ assertTrue(bitSet[99 ], " Should be able to set and get bit at size-1" )
211
+
212
+ // Test clearing at boundaries
213
+ bitSet.clear(0 )
214
+ assertFalse(bitSet[0 ], " Should be able to clear bit 0" )
215
+
216
+ bitSet.clear(99 )
217
+ assertFalse(bitSet[99 ], " Should be able to clear bit at size-1" )
218
+
219
+ // Test out of bounds access
220
+ assertFailsWith<IllegalArgumentException > {
221
+ bitSet[100 ] = true
222
+ }
223
+
224
+ assertFailsWith<IllegalArgumentException > {
225
+ bitSet.clear(100 )
226
+ }
227
+
228
+ assertFailsWith<IllegalArgumentException > {
229
+ bitSet[100 ]
230
+ }
231
+
232
+ assertFailsWith<IllegalArgumentException > {
233
+ bitSet[- 1 ] = true
234
+ }
235
+
236
+ assertFailsWith<IllegalArgumentException > {
237
+ bitSet.clear(- 1 )
238
+ }
239
+
240
+ assertFailsWith<IllegalArgumentException > {
241
+ bitSet[- 1 ]
242
+ }
243
+ }
244
+
245
+ @Test
246
+ fun testWordBoundaries () {
247
+ // Test BitSet with size at word boundaries
248
+ for (size in listOf (63 , 64 , 65 , 127 , 128 , 129 )) {
249
+ val bitSet = BitSet (size)
250
+
251
+ // Set all bits
252
+ for (i in 0 until size) {
253
+ bitSet[i] = true
254
+ }
255
+
256
+ // Verify all bits are set
257
+ for (i in 0 until size) {
258
+ assertTrue(bitSet[i], " Bit $i should be set in BitSet of size $size " )
259
+ }
260
+
261
+ // Verify cardinality
262
+ assertEquals(size, bitSet.cardinality(), " Cardinality should equal size for fully set BitSet" )
263
+
264
+ // Verify allSet
265
+ assertTrue(bitSet.allSet(), " allSet should return true for fully set BitSet" )
266
+
267
+ // Clear all bits
268
+ bitSet.clearAll()
269
+
270
+ // Verify all bits are cleared
271
+ for (i in 0 until size) {
272
+ assertFalse(bitSet[i], " Bit $i should be cleared in BitSet of size $size after clearAll" )
273
+ }
274
+
275
+ // Verify cardinality
276
+ assertEquals(0 , bitSet.cardinality(), " Cardinality should be 0 after clearAll" )
277
+
278
+ // Verify allSet
279
+ assertFalse(bitSet.allSet(), " allSet should return false after clearAll" )
280
+ }
281
+ }
282
+
283
+ @Test
284
+ fun testLargeCardinality () {
285
+ // Test with a large BitSet to verify cardinality calculation
286
+ val size = 1000
287
+ val bitSet = BitSet (size)
288
+
289
+ // Set every other bit
290
+ for (i in 0 until size step 2 ) {
291
+ bitSet[i] = true
292
+ }
293
+
294
+ // Verify cardinality
295
+ assertEquals(size / 2 , bitSet.cardinality(), " Cardinality should be half the size when every other bit is set" )
296
+
297
+ // Set all bits
298
+ for (i in 0 until size) {
299
+ bitSet[i] = true
300
+ }
301
+
302
+ // Verify cardinality
303
+ assertEquals(size, bitSet.cardinality(), " Cardinality should equal size when all bits are set" )
304
+ }
305
+ }
0 commit comments