@@ -185,3 +185,85 @@ fn i256_to_i64_opt(bytes: &[u8]) -> Option<i64> {
185185 }
186186 }
187187}
188+
189+ // -------------------- Unit tests (Rust) --------------------
190+ #[ cfg( test) ]
191+ mod tests {
192+ use super :: * ;
193+ use ruint:: aliases:: U256 ;
194+
195+ fn be32_from_u64 ( v : u64 ) -> [ u8 ; 32 ] {
196+ let mut out = [ 0u8 ; 32 ] ;
197+ out[ 24 ..] . copy_from_slice ( & v. to_be_bytes ( ) ) ;
198+ out
199+ }
200+
201+ fn be32_from_i64 ( v : i64 ) -> [ u8 ; 32 ] {
202+ if v >= 0 {
203+ be32_from_u64 ( v as u64 )
204+ } else {
205+ let mag = ( -v) as u64 ;
206+ let inv = U256 :: from ( 0u8 ) . overflowing_sub ( U256 :: from ( mag) ) . 0 ;
207+ inv. to_be_bytes ( )
208+ }
209+ }
210+
211+ fn series_from_be32 ( name : & str , vals : Vec < Option < [ u8 ; 32 ] > > ) -> Series {
212+ BinaryChunked :: from_iter_options ( name. into ( ) , vals. into_iter ( ) ) . into_series ( )
213+ }
214+
215+ #[ test]
216+ fn test_broadcast_mismatch_err ( ) {
217+ let a = series_from_be32 (
218+ "a" ,
219+ vec ! [ Some ( be32_from_u64( 1 ) ) , Some ( be32_from_u64( 2 ) ) ] ,
220+ ) ;
221+ let b = series_from_be32 (
222+ "b" ,
223+ vec ! [ Some ( be32_from_u64( 3 ) ) , Some ( be32_from_u64( 4 ) ) , Some ( be32_from_u64( 5 ) ) ] ,
224+ ) ;
225+ let a_bin = a. binary ( ) . unwrap ( ) ;
226+ let b_bin = b. binary ( ) . unwrap ( ) ;
227+ let err = broadcast_binary_pair ( a_bin, b_bin) . unwrap_err ( ) ;
228+ let msg = format ! ( "{err}" ) ;
229+ assert ! ( msg. contains( "cannot do a binary operation on columns of different lengths" ) ) ;
230+ }
231+
232+ #[ test]
233+ fn test_map_pair_add_overflow_to_null ( ) {
234+ let a = series_from_be32 ( "a" , vec ! [ Some ( U256 :: MAX . to_be_bytes( ) ) ] ) ;
235+ let b = series_from_be32 ( "b" , vec ! [ Some ( be32_from_u64( 1 ) ) ] ) ;
236+ let out = map_pair_binary_to_binary_series (
237+ & PlSmallStr :: from_static ( "out" ) ,
238+ a. binary ( ) . unwrap ( ) ,
239+ b. binary ( ) . unwrap ( ) ,
240+ |la, rb| {
241+ let ua = u256_from_be32 ( la) . ok ( ) ?;
242+ let ub = u256_from_be32 ( rb) . ok ( ) ?;
243+ let ( sum, overflow) = ua. overflowing_add ( ub) ;
244+ if overflow { None } else { Some ( u256_to_be32 ( & sum) ) }
245+ } ,
246+ )
247+ . unwrap ( ) ;
248+ let first = out. binary ( ) . unwrap ( ) . into_iter ( ) . next ( ) . unwrap ( ) ;
249+ assert ! ( first. is_none( ) ) ;
250+ }
251+
252+ #[ test]
253+ fn test_i256_twos_complement_roundtrip_small ( ) {
254+ // For a small magnitude negative, tc(tc(x)) = x
255+ let x = be32_from_i64 ( -123 ) ;
256+ let tc = i256_twos_complement ( & x) ;
257+ let back = i256_twos_complement ( & tc) ;
258+ assert_eq ! ( back, x) ;
259+ }
260+
261+ #[ test]
262+ fn test_i256_cmp_bytes_sign_ordering ( ) {
263+ let neg = be32_from_i64 ( -1 ) ;
264+ let pos = be32_from_i64 ( 1 ) ;
265+ assert ! ( i256_cmp_bytes( & neg, & pos) . unwrap( ) . is_lt( ) ) ;
266+ assert ! ( i256_cmp_bytes( & pos, & neg) . unwrap( ) . is_gt( ) ) ;
267+ assert ! ( i256_cmp_bytes( & neg, & neg) . unwrap( ) . is_eq( ) ) ;
268+ }
269+ }
0 commit comments