1+ /*
2+ * Copyright 2017-2025 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+ */
4+
5+ package kotlinx.serialization.cbor
6+
7+ import kotlin.test.*
8+
9+ class CborElementEqualityTest {
10+
11+ @Test
12+ fun testCborPositiveIntEquality () {
13+ val int1 = CborPositiveInt (42u )
14+ val int2 = CborPositiveInt (42u )
15+ val int3 = CborPositiveInt (43u )
16+ val int4 = CborPositiveInt (42u , ulongArrayOf(1u ))
17+
18+ // Same values should be equal
19+ assertEquals(int1, int2)
20+ assertEquals(int1.hashCode(), int2.hashCode())
21+
22+ // Different values should not be equal
23+ assertNotEquals(int1, int3)
24+
25+ // Different tags should not be equal
26+ assertNotEquals(int1, int4)
27+
28+ // Null comparison
29+ assertNotEquals(int1, null as CborElement ? )
30+
31+ // Different type comparison
32+ assertNotEquals(int1 as CborElement , CborString (" 42" ))
33+ assertNotEquals(int1, CborString (" 42" ) as CborElement )
34+ }
35+
36+ @Test
37+ fun testCborNegativeIntEquality () {
38+ val int1 = CborNegativeInt (- 42 )
39+ val int2 = CborNegativeInt (- 42 )
40+ val int3 = CborNegativeInt (- 43 )
41+ val int4 = CborNegativeInt (- 42 , ulongArrayOf(1u ))
42+
43+ assertEquals(int1, int2)
44+ assertEquals(int1.hashCode(), int2.hashCode())
45+ assertNotEquals(int1, int3)
46+ assertNotEquals(int1, int4)
47+ assertNotEquals(int1, null as CborElement ? )
48+ assertNotEquals(int1, CborPositiveInt (42u ) as CborElement )
49+ assertNotEquals(int1 as CborElement , CborPositiveInt (42u ))
50+ }
51+
52+ @Test
53+ fun testCborDoubleEquality () {
54+ val double1 = CborDouble (3.14 )
55+ val double2 = CborDouble (3.14 )
56+ val double3 = CborDouble (2.71 )
57+ val double4 = CborDouble (3.14 , ulongArrayOf(1u ))
58+
59+ assertEquals(double1, double2)
60+ assertEquals(double1.hashCode(), double2.hashCode())
61+ assertNotEquals(double1, double3)
62+ assertNotEquals(double1, double4)
63+ assertNotEquals(double1, null as CborElement ? )
64+ assertNotEquals(double1 as CborElement , CborString (" 3.14" ))
65+ assertNotEquals(double1, CborString (" 3.14" ) as CborElement )
66+ }
67+
68+ @Test
69+ fun testCborStringEquality () {
70+ val string1 = CborString (" hello" )
71+ val string2 = CborString (" hello" )
72+ val string3 = CborString (" world" )
73+ val string4 = CborString (" hello" , ulongArrayOf(1u ))
74+
75+ assertEquals(string1, string2)
76+ assertEquals(string1.hashCode(), string2.hashCode())
77+ assertNotEquals(string1, string3)
78+ assertNotEquals(string1, string4)
79+ assertNotEquals(string1, null as CborElement ? )
80+ assertNotEquals(string1 as CborElement , CborPositiveInt (123u ))
81+ assertNotEquals(string1, CborPositiveInt (123u ) as CborElement )
82+ }
83+
84+ @Test
85+ fun testCborBooleanEquality () {
86+ val bool1 = CborBoolean (true )
87+ val bool2 = CborBoolean (true )
88+ val bool3 = CborBoolean (false )
89+ val bool4 = CborBoolean (true , ulongArrayOf(1u ))
90+
91+ assertEquals(bool1, bool2)
92+ assertEquals(bool1.hashCode(), bool2.hashCode())
93+ assertNotEquals(bool1, bool3)
94+ assertNotEquals(bool1, bool4)
95+ assertNotEquals(bool1, null as CborElement ? )
96+ assertNotEquals(bool1 as CborElement , CborString (" true" ))
97+ assertNotEquals(bool1, CborString (" true" ) as CborElement )
98+ }
99+
100+ @Test
101+ fun testCborByteStringEquality () {
102+ val bytes1 = byteArrayOf(1 , 2 , 3 )
103+ val bytes2 = byteArrayOf(1 , 2 , 3 )
104+ val bytes3 = byteArrayOf(4 , 5 , 6 )
105+
106+ val byteString1 = CborByteString (bytes1)
107+ val byteString2 = CborByteString (bytes2)
108+ val byteString3 = CborByteString (bytes3)
109+ val byteString4 = CborByteString (bytes1, ulongArrayOf(1u ))
110+
111+ assertEquals(byteString1, byteString2)
112+ assertEquals(byteString1.hashCode(), byteString2.hashCode())
113+ assertNotEquals(byteString1, byteString3)
114+ assertNotEquals(byteString1, byteString4)
115+ assertNotEquals(byteString1, null as CborElement ? )
116+ assertNotEquals(byteString1 as CborElement , CborString (" 123" ))
117+ assertNotEquals(byteString1, CborString (" 123" ) as CborElement )
118+ }
119+
120+ @Test
121+ fun testCborNullEquality () {
122+ val null1 = CborNull ()
123+ val null2 = CborNull ()
124+ val null3 = CborNull (ulongArrayOf(1u ))
125+
126+ assertEquals(null1, null2)
127+ assertEquals(null1.hashCode(), null2.hashCode())
128+ assertNotEquals(null1, null3)
129+ assertNotEquals(null1, null as CborElement ? )
130+ assertNotEquals(null1 as CborElement , CborString (" null" ))
131+ assertNotEquals(null1, CborString (" null" ) as CborElement )
132+ }
133+
134+ @Test
135+ fun testCborListEquality () {
136+ val list1 = CborList (listOf (CborPositiveInt (1u ), CborString (" test" )))
137+ val list2 = CborList (listOf (CborPositiveInt (1u ), CborString (" test" )))
138+ val list3 = CborList (listOf (CborPositiveInt (2u ), CborString (" test" )))
139+ val list4 = CborList (listOf (CborPositiveInt (1u ), CborString (" test" )), ulongArrayOf(1u ))
140+ val list5 = CborList (listOf (CborPositiveInt (1u )))
141+
142+ assertEquals(list1, list2)
143+ assertEquals(list1.hashCode(), list2.hashCode())
144+ assertNotEquals(list1, list3)
145+ assertNotEquals(list1, list4)
146+ assertNotEquals(list1, list5)
147+ assertNotEquals(list1, null as CborElement ? )
148+ assertNotEquals(list1 as CborElement , CborString (" list" ))
149+ assertNotEquals(list1, CborString (" list" ) as CborElement )
150+ }
151+
152+ @Test
153+ fun testCborMapEquality () {
154+ val map1 = CborMap (mapOf (
155+ CborString (" key1" ) to CborPositiveInt (1u ),
156+ CborString (" key2" ) to CborString (" value" )
157+ ))
158+ val map2 = CborMap (mapOf (
159+ CborString (" key1" ) to CborPositiveInt (1u ),
160+ CborString (" key2" ) to CborString (" value" )
161+ ))
162+ val map3 = CborMap (mapOf (
163+ CborString (" key1" ) to CborPositiveInt (2u ),
164+ CborString (" key2" ) to CborString (" value" )
165+ ))
166+ val map4 = CborMap (mapOf (
167+ CborString (" key1" ) to CborPositiveInt (1u ),
168+ CborString (" key2" ) to CborString (" value" )
169+ ), ulongArrayOf(1u ))
170+ val map5 = CborMap (mapOf (
171+ CborString (" key1" ) to CborPositiveInt (1u )
172+ ))
173+
174+ assertEquals(map1, map2)
175+ assertEquals(map1.hashCode(), map2.hashCode())
176+ assertNotEquals(map1, map3)
177+ assertNotEquals(map1, map4)
178+ assertNotEquals(map1, map5)
179+ assertNotEquals(map1, null as CborElement ? )
180+ assertNotEquals(map1 as CborElement , CborString (" map" ))
181+ assertNotEquals(map1, CborString (" map" ) as CborElement )
182+ }
183+
184+ @Test
185+ fun testTagsEquality () {
186+ val tags1 = ulongArrayOf(1u , 2u , 3u )
187+ val tags2 = ulongArrayOf(1u , 2u , 3u )
188+ val tags3 = ulongArrayOf(1u , 2u , 4u )
189+
190+ val string1 = CborString (" test" , tags1)
191+ val string2 = CborString (" test" , tags2)
192+ val string3 = CborString (" test" , tags3)
193+
194+ assertEquals(string1, string2)
195+ assertEquals(string1.hashCode(), string2.hashCode())
196+ assertNotEquals(string1, string3)
197+ }
198+
199+ @Test
200+ fun testEmptyCollectionsEquality () {
201+ val emptyList1 = CborList (emptyList())
202+ val emptyList2 = CborList (emptyList())
203+ val emptyMap1 = CborMap (emptyMap())
204+ val emptyMap2 = CborMap (emptyMap())
205+
206+ assertEquals(emptyList1, emptyList2)
207+ assertEquals(emptyList1.hashCode(), emptyList2.hashCode())
208+ assertEquals(emptyMap1, emptyMap2)
209+ assertEquals(emptyMap1.hashCode(), emptyMap2.hashCode())
210+ assertNotEquals(emptyList1 as CborElement , emptyMap1)
211+ assertNotEquals(emptyList1, emptyMap1 as CborElement )
212+ }
213+
214+ @Test
215+ fun testNestedStructureEquality () {
216+ val nested1 = CborMap (mapOf (
217+ CborString (" list" ) to CborList (listOf (
218+ CborPositiveInt (1u ),
219+ CborMap (mapOf (CborString (" inner" ) to CborNull ()))
220+ ))
221+ ))
222+ val nested2 = CborMap (mapOf (
223+ CborString (" list" ) to CborList (listOf (
224+ CborPositiveInt (1u ),
225+ CborMap (mapOf (CborString (" inner" ) to CborNull ()))
226+ ))
227+ ))
228+ val nested3 = CborMap (mapOf (
229+ CborString (" list" ) to CborList (listOf (
230+ CborPositiveInt (2u ),
231+ CborMap (mapOf (CborString (" inner" ) to CborNull ()))
232+ ))
233+ ))
234+
235+ assertEquals(nested1, nested2)
236+ assertEquals(nested1.hashCode(), nested2.hashCode())
237+ assertNotEquals(nested1, nested3)
238+ }
239+
240+ @Test
241+ fun testReflexiveEquality () {
242+ val elements = listOf (
243+ CborPositiveInt (42u ),
244+ CborNegativeInt (- 42 ),
245+ CborDouble (3.14 ),
246+ CborString (" test" ),
247+ CborBoolean (true ),
248+ CborByteString (byteArrayOf(1 , 2 , 3 )),
249+ CborNull (),
250+ CborList (listOf (CborPositiveInt (1u ))),
251+ CborMap (mapOf (CborString (" key" ) to CborPositiveInt (1u )))
252+ )
253+
254+ elements.forEach { element ->
255+ assertEquals(element, element, " Element should be equal to itself" )
256+ assertEquals(element.hashCode(), element.hashCode(), " Hash code should be consistent" )
257+ }
258+ }
259+
260+ @Test
261+ fun testSymmetricEquality () {
262+ val pairs = listOf (
263+ CborPositiveInt (42u ) to CborPositiveInt (42u ),
264+ CborNegativeInt (- 42 ) to CborNegativeInt (- 42 ),
265+ CborDouble (3.14 ) to CborDouble (3.14 ),
266+ CborString (" test" ) to CborString (" test" ),
267+ CborBoolean (true ) to CborBoolean (true ),
268+ CborByteString (byteArrayOf(1 , 2 , 3 )) to CborByteString (byteArrayOf(1 , 2 , 3 )),
269+ CborNull () to CborNull (),
270+ CborList (listOf (CborPositiveInt (1u ))) to CborList (listOf (CborPositiveInt (1u ))),
271+ CborMap (mapOf (CborString (" key" ) to CborPositiveInt (1u ))) to CborMap (mapOf (CborString (" key" ) to CborPositiveInt (1u )))
272+ )
273+
274+ pairs.forEach { (a, b) ->
275+ assertEquals(a, b, " a should equal b" )
276+ assertEquals(b, a, " b should equal a (symmetry)" )
277+ assertEquals(a.hashCode(), b.hashCode(), " Hash codes should be equal" )
278+ }
279+ }
280+
281+ @Test
282+ fun testTransitiveEquality () {
283+ val a = CborString (" test" )
284+ val b = CborString (" test" )
285+ val c = CborString (" test" )
286+
287+ assertEquals(a, b)
288+ assertEquals(b, c)
289+ assertEquals(a, c, " Transitivity: if a==b and b==c, then a==c" )
290+ }
291+ }
0 commit comments