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