@@ -21,6 +21,170 @@ unsigned_test() ->
2121 ? assertEqual (<<2#10101100 , 2#00000010 >>,
2222 bin (kpro_varint :encode_unsigned (300 ))).
2323
24+ % % Comprehensive varint encoding tests
25+ encode_test_ () ->
26+ [
27+ {" encode zero" , fun () ->
28+ ? assertEqual (<<0 >>, bin (kpro_varint :encode (0 )))
29+ end },
30+ {" encode small positive" , fun () ->
31+ ? assertEqual (<<254 , 1 >>, bin (kpro_varint :encode (127 ))),
32+ ? assertEqual (<<200 , 1 >>, bin (kpro_varint :encode (100 )))
33+ end },
34+ {" encode small negative" , fun () ->
35+ ? assertEqual (<<1 >>, bin (kpro_varint :encode (- 1 ))),
36+ ? assertEqual (<<3 >>, bin (kpro_varint :encode (- 2 ))),
37+ ? assertEqual (<<255 , 1 >>, bin (kpro_varint :encode (- 128 )))
38+ end },
39+ {" encode medium values" , fun () ->
40+ ? assertEqual (<<128 , 2 >>, bin (kpro_varint :encode (128 ))),
41+ ? assertEqual (<<130 , 2 >>, bin (kpro_varint :encode (129 ))),
42+ ? assertEqual (<<254 , 3 >>, bin (kpro_varint :encode (255 )))
43+ end },
44+ {" encode large values" , fun () ->
45+ ? assertEqual (<<128 , 128 , 2 >>, bin (kpro_varint :encode (16384 ))),
46+ ? assertEqual (<<254 , 255 , 255 , 1 >>, bin (kpro_varint :encode (2097151 ))),
47+ ? assertEqual (<<128 , 128 , 128 , 2 >>, bin (kpro_varint :encode (2097152 )))
48+ end },
49+ {" encode edge cases" , fun () ->
50+ ? assertEqual (<<254 , 255 , 255 , 255 , 1 >>, bin (kpro_varint :encode (268435455 )))
51+ end }
52+ ].
53+
54+ % % Comprehensive varint decoding tests
55+ decode_test_ () ->
56+ [
57+ {" decode zero" , fun () ->
58+ ? assertEqual ({0 , <<>>}, kpro_varint :decode (<<0 >>))
59+ end },
60+ {" decode small positive" , fun () ->
61+ ? assertEqual ({127 , <<>>}, kpro_varint :decode (<<254 , 1 >>)),
62+ ? assertEqual ({100 , <<>>}, kpro_varint :decode (<<200 , 1 >>))
63+ end },
64+ {" decode small negative" , fun () ->
65+ ? assertEqual ({- 1 , <<>>}, kpro_varint :decode (<<1 >>)),
66+ ? assertEqual ({- 2 , <<>>}, kpro_varint :decode (<<3 >>)),
67+ ? assertEqual ({- 128 , <<>>}, kpro_varint :decode (<<255 , 1 >>))
68+ end },
69+ {" decode medium values" , fun () ->
70+ ? assertEqual ({128 , <<>>}, kpro_varint :decode (<<128 , 2 >>)),
71+ ? assertEqual ({129 , <<>>}, kpro_varint :decode (<<130 , 2 >>)),
72+ ? assertEqual ({255 , <<>>}, kpro_varint :decode (<<254 , 3 >>))
73+ end },
74+ {" decode large values" , fun () ->
75+ ? assertEqual ({16384 , <<>>}, kpro_varint :decode (<<128 , 128 , 2 >>)),
76+ ? assertEqual ({2097151 , <<>>}, kpro_varint :decode (<<254 , 255 , 255 , 1 >>)),
77+ ? assertEqual ({2097152 , <<>>}, kpro_varint :decode (<<128 , 128 , 128 , 2 >>))
78+ end },
79+ {" decode with trailing data" , fun () ->
80+ ? assertEqual ({0 , <<" hello" >>}, kpro_varint :decode (<<0 , " hello" >>)),
81+ ? assertEqual ({127 , <<" world" >>}, kpro_varint :decode (<<254 , 1 , " world" >>))
82+ end }
83+ ].
84+
85+ % % Round-trip encoding/decoding tests
86+ roundtrip_test_ () ->
87+ TestValues = [
88+ 0 , 1 , - 1 , 127 , - 127 , 128 , - 128 , 255 , - 255 ,
89+ 1000 , - 1000 , 16383 , - 16383 , 16384 , - 16384 ,
90+ 2097151 , - 2097151 , 2097152 , - 2097152 ,
91+ 268435455 , - 268435455
92+ ],
93+ [{" roundtrip " ++ integer_to_list (Val ), fun () ->
94+ Encoded = kpro_varint :encode (Val ),
95+ {Decoded , <<>>} = kpro_varint :decode (bin (Encoded )),
96+ ? assertEqual (Val , Decoded )
97+ end } || Val <- TestValues ].
98+
99+ % % Unsigned varint tests
100+ unsigned_comprehensive_test_ () ->
101+ [
102+ {" unsigned encode zero" , fun () ->
103+ ? assertEqual (<<0 >>, bin (kpro_varint :encode_unsigned (0 )))
104+ end },
105+ {" unsigned encode small" , fun () ->
106+ ? assertEqual (<<1 >>, bin (kpro_varint :encode_unsigned (1 ))),
107+ ? assertEqual (<<127 >>, bin (kpro_varint :encode_unsigned (127 ))),
108+ ? assertEqual (<<128 , 1 >>, bin (kpro_varint :encode_unsigned (128 )))
109+ end },
110+ {" unsigned encode large" , fun () ->
111+ ? assertEqual (<<255 , 255 , 255 , 255 , 127 >>, bin (kpro_varint :encode_unsigned (34359738367 )))
112+ end },
113+ {" unsigned decode" , fun () ->
114+ ? assertEqual ({0 , <<>>}, kpro_varint :decode_unsigned (<<0 >>)),
115+ ? assertEqual ({1 , <<>>}, kpro_varint :decode_unsigned (<<1 >>)),
116+ ? assertEqual ({127 , <<>>}, kpro_varint :decode_unsigned (<<127 >>)),
117+ ? assertEqual ({128 , <<>>}, kpro_varint :decode_unsigned (<<128 , 1 >>)),
118+ ? assertEqual ({300 , <<>>}, kpro_varint :decode_unsigned (<<172 , 2 >>))
119+ end },
120+ {" unsigned roundtrip" , fun () ->
121+ TestValues = [0 , 1 , 127 , 128 , 255 , 1000 , 16383 , 16384 , 2097151 , 2097152 , 268435455 , 268435456 , 34359738367 ],
122+ lists :foreach (fun (Val ) ->
123+ Encoded = kpro_varint :encode_unsigned (Val ),
124+ {Decoded , <<>>} = kpro_varint :decode_unsigned (bin (Encoded )),
125+ ? assertEqual (Val , Decoded )
126+ end , TestValues )
127+ end }
128+ ].
129+
130+ % % Zigzag encoding tests (internal functions, test through public API)
131+ zigzag_roundtrip_test_ () ->
132+ TestValues = [0 , 1 , - 1 , 127 , - 127 , 128 , - 128 , 1000 , - 1000 , 16383 , - 16383 , 16384 , - 16384 ],
133+ [{" zigzag roundtrip " ++ integer_to_list (Val ), fun () ->
134+ Encoded = kpro_varint :encode (Val ),
135+ {Decoded , <<>>} = kpro_varint :decode (bin (Encoded )),
136+ ? assertEqual (Val , Decoded )
137+ end } || Val <- TestValues ].
138+
139+ % % Performance tests
140+ performance_test_ () ->
141+ [
142+ {" encode performance" , fun () ->
143+ TestValues = lists :seq (1 , 1000 ),
144+ StartTime = erlang :system_time (microsecond ),
145+ lists :foreach (fun (Val ) ->
146+ _ = kpro_varint :encode (Val )
147+ end , TestValues ),
148+ EndTime = erlang :system_time (microsecond ),
149+ EncodingTime = EndTime - StartTime ,
150+ ? assert (EncodingTime < 10000 ) % % Should complete in <10ms
151+ end },
152+ {" decode performance" , fun () ->
153+ TestValues = lists :seq (1 , 1000 ),
154+ EncodedValues = [bin (kpro_varint :encode (Val )) || Val <- TestValues ],
155+ StartTime = erlang :system_time (microsecond ),
156+ lists :foreach (fun (Encoded ) ->
157+ {_Decoded , _ } = kpro_varint :decode (Encoded )
158+ end , EncodedValues ),
159+ EndTime = erlang :system_time (microsecond ),
160+ DecodingTime = EndTime - StartTime ,
161+ ? assert (DecodingTime < 10000 ) % % Should complete in <10ms
162+ end }
163+ ].
164+
165+ % % Edge case tests
166+ edge_cases_test_ () ->
167+ [
168+ {" max supported signed integer" , fun () ->
169+ MaxInt = 268435455 ,
170+ Encoded = kpro_varint :encode (MaxInt ),
171+ {Decoded , <<>>} = kpro_varint :decode (bin (Encoded )),
172+ ? assertEqual (MaxInt , Decoded )
173+ end },
174+ {" min supported signed integer" , fun () ->
175+ MinInt = - 268435455 ,
176+ Encoded = kpro_varint :encode (MinInt ),
177+ {Decoded , <<>>} = kpro_varint :decode (bin (Encoded )),
178+ ? assertEqual (MinInt , Decoded )
179+ end },
180+ {" max supported unsigned" , fun () ->
181+ LargeUnsigned = 268435455 ,
182+ Encoded = kpro_varint :encode_unsigned (LargeUnsigned ),
183+ {Decoded , <<>>} = kpro_varint :decode_unsigned (bin (Encoded )),
184+ ? assertEqual (LargeUnsigned , Decoded )
185+ end }
186+ ].
187+
24188bin (IoData ) -> iolist_to_binary (IoData ).
25189
26190% %%_* Emacs ====================================================================
0 commit comments