@@ -948,3 +948,220 @@ pub trait ForeignDataWrapper<E: Into<ErrorReport>> {
948948 Ok ( ( ) )
949949 }
950950}
951+
952+ #[ cfg( test) ]
953+ mod tests {
954+ use super :: * ;
955+
956+ fn assert_cell_clone ( cell : Cell ) {
957+ let cell_clone = cell. clone ( ) ;
958+
959+ match ( cell, cell_clone) {
960+ ( Cell :: Bool ( left) , Cell :: Bool ( right) ) => assert_eq ! ( left, right) ,
961+ ( Cell :: I8 ( left) , Cell :: I8 ( right) ) => assert_eq ! ( left, right) ,
962+ ( Cell :: I16 ( left) , Cell :: I16 ( right) ) => assert_eq ! ( left, right) ,
963+ ( Cell :: F32 ( left) , Cell :: F32 ( right) ) => assert_eq ! ( left, right) ,
964+ ( Cell :: I32 ( left) , Cell :: I32 ( right) ) => assert_eq ! ( left, right) ,
965+ ( Cell :: F64 ( left) , Cell :: F64 ( right) ) => assert_eq ! ( left, right) ,
966+ ( Cell :: I64 ( left) , Cell :: I64 ( right) ) => assert_eq ! ( left, right) ,
967+ ( Cell :: String ( left) , Cell :: String ( right) ) => assert_eq ! ( left, right) ,
968+ ( Cell :: BoolArray ( left) , Cell :: BoolArray ( right) ) => assert_eq ! ( left, right) ,
969+ ( Cell :: I16Array ( left) , Cell :: I16Array ( right) ) => assert_eq ! ( left, right) ,
970+ ( Cell :: I32Array ( left) , Cell :: I32Array ( right) ) => assert_eq ! ( left, right) ,
971+ ( Cell :: I64Array ( left) , Cell :: I64Array ( right) ) => assert_eq ! ( left, right) ,
972+ ( Cell :: F32Array ( left) , Cell :: F32Array ( right) ) => assert_eq ! ( left, right) ,
973+ ( Cell :: F64Array ( left) , Cell :: F64Array ( right) ) => assert_eq ! ( left, right) ,
974+ ( Cell :: StringArray ( left) , Cell :: StringArray ( right) ) => assert_eq ! ( left, right) ,
975+ ( left, right) => panic ! ( "cell clone variant mismatch: left={left:?}, right={right:?}" , ) ,
976+ }
977+ }
978+
979+ // ==========================================================================
980+ // Tests for Cell
981+ // ==========================================================================
982+ #[ test]
983+ fn test_cell_clone ( ) {
984+ let cell = Cell :: String ( "hello" . to_string ( ) ) ;
985+ assert_cell_clone ( cell) ;
986+ }
987+
988+ #[ test]
989+ fn test_cell_clone_primitives ( ) {
990+ let cases = vec ! [
991+ Cell :: Bool ( true ) ,
992+ Cell :: I8 ( -8 ) ,
993+ Cell :: I16 ( -16 ) ,
994+ Cell :: F32 ( 123.456f32 ) ,
995+ Cell :: I32 ( 32 ) ,
996+ Cell :: F64 ( 654.321f64 ) ,
997+ Cell :: I64 ( 64 ) ,
998+ Cell :: String ( "supabase" . to_string( ) ) ,
999+ ] ;
1000+
1001+ for cell in cases {
1002+ assert_cell_clone ( cell) ;
1003+ }
1004+ }
1005+
1006+ #[ test]
1007+ fn test_cell_clone_array_variants ( ) {
1008+ let cases = vec ! [
1009+ Cell :: BoolArray ( vec![ Some ( true ) , None , Some ( false ) ] ) ,
1010+ Cell :: I16Array ( vec![ Some ( -1 ) , None , Some ( 2 ) ] ) ,
1011+ Cell :: I32Array ( vec![ Some ( -10 ) , None , Some ( 20 ) ] ) ,
1012+ Cell :: I64Array ( vec![ Some ( -100 ) , None , Some ( 200 ) ] ) ,
1013+ Cell :: F32Array ( vec![ Some ( 1.5 ) , None , Some ( 2.5 ) ] ) ,
1014+ Cell :: F64Array ( vec![ Some ( 10.5 ) , None , Some ( 20.5 ) ] ) ,
1015+ Cell :: StringArray ( vec![ Some ( "a" . to_string( ) ) , None , Some ( "b" . to_string( ) ) ] ) ,
1016+ ] ;
1017+
1018+ for cell in cases {
1019+ let cell_clone = cell. clone ( ) ;
1020+ assert_cell_clone ( cell) ;
1021+ assert ! ( cell_clone. is_array( ) ) ;
1022+ }
1023+ }
1024+
1025+ #[ test]
1026+ fn test_cell_clone_deep_copy_for_owned_types ( ) {
1027+ let mut string_cell = Cell :: String ( "hello" . to_string ( ) ) ;
1028+ let string_cell_clone = string_cell. clone ( ) ;
1029+ if let Cell :: String ( value) = & mut string_cell {
1030+ value. push_str ( " world" ) ;
1031+ }
1032+ match string_cell_clone {
1033+ Cell :: String ( value) => assert_eq ! ( value, "hello" ) ,
1034+ other => panic ! ( "expected Cell::String clone, got {other:?}" ) ,
1035+ }
1036+ match string_cell {
1037+ Cell :: String ( value) => assert_eq ! ( value, "hello world" ) ,
1038+ other => panic ! ( "expected mutated Cell::String, got {other:?}" ) ,
1039+ }
1040+
1041+ let mut string_array_cell =
1042+ Cell :: StringArray ( vec ! [ Some ( "foo" . to_string( ) ) , None , Some ( "bar" . to_string( ) ) ] ) ;
1043+ let string_array_cell_clone = string_array_cell. clone ( ) ;
1044+ if let Cell :: StringArray ( values) = & mut string_array_cell {
1045+ values[ 0 ] = Some ( "baz" . to_string ( ) ) ;
1046+ }
1047+ match string_array_cell_clone {
1048+ Cell :: StringArray ( values) => {
1049+ assert_eq ! (
1050+ values,
1051+ vec![ Some ( "foo" . to_string( ) ) , None , Some ( "bar" . to_string( ) ) ]
1052+ )
1053+ }
1054+ other => panic ! ( "expected Cell::StringArray clone, got {other:?}" ) ,
1055+ }
1056+ match string_array_cell {
1057+ Cell :: StringArray ( values) => {
1058+ assert_eq ! (
1059+ values,
1060+ vec![ Some ( "baz" . to_string( ) ) , None , Some ( "bar" . to_string( ) ) ]
1061+ )
1062+ }
1063+ other => panic ! ( "expected mutated Cell::StringArray, got {other:?}" ) ,
1064+ }
1065+ }
1066+
1067+ #[ test]
1068+ fn test_cell_display_primitives_and_string ( ) {
1069+ assert_eq ! ( format!( "{}" , Cell :: Bool ( true ) ) , "true" ) ;
1070+ assert_eq ! ( format!( "{}" , Cell :: I8 ( -8 ) ) , "-8" ) ;
1071+ assert_eq ! ( format!( "{}" , Cell :: I16 ( 16 ) ) , "16" ) ;
1072+ assert_eq ! ( format!( "{}" , Cell :: I32 ( 32 ) ) , "32" ) ;
1073+ assert_eq ! ( format!( "{}" , Cell :: I64 ( 64 ) ) , "64" ) ;
1074+ assert_eq ! ( format!( "{}" , Cell :: F32 ( 3.5 ) ) , "3.5" ) ;
1075+ assert_eq ! ( format!( "{}" , Cell :: F64 ( 7.25 ) ) , "7.25" ) ;
1076+ assert_eq ! ( format!( "{}" , Cell :: String ( "hello" . to_string( ) ) ) , "'hello'" ) ;
1077+ }
1078+
1079+ #[ test]
1080+ fn test_cell_display_arrays_with_nulls ( ) {
1081+ assert_eq ! (
1082+ format!( "{}" , Cell :: BoolArray ( vec![ Some ( true ) , None , Some ( false ) ] ) ) ,
1083+ "[true,null,false]"
1084+ ) ;
1085+ assert_eq ! (
1086+ format!( "{}" , Cell :: I32Array ( vec![ Some ( 1 ) , None , Some ( 3 ) ] ) ) ,
1087+ "[1,null,3]"
1088+ ) ;
1089+ assert_eq ! (
1090+ format!(
1091+ "{}" ,
1092+ Cell :: StringArray ( vec![ Some ( "foo" . to_string( ) ) , None , Some ( "bar" . to_string( ) ) ] )
1093+ ) ,
1094+ "[foo,null,bar]"
1095+ ) ;
1096+ }
1097+
1098+ #[ test]
1099+ fn test_cell_display_empty_arrays ( ) {
1100+ assert_eq ! ( format!( "{}" , Cell :: BoolArray ( vec![ ] ) ) , "[]" ) ;
1101+ assert_eq ! ( format!( "{}" , Cell :: I16Array ( vec![ ] ) ) , "[]" ) ;
1102+ assert_eq ! ( format!( "{}" , Cell :: I32Array ( vec![ ] ) ) , "[]" ) ;
1103+ assert_eq ! ( format!( "{}" , Cell :: I64Array ( vec![ ] ) ) , "[]" ) ;
1104+ assert_eq ! ( format!( "{}" , Cell :: F32Array ( vec![ ] ) ) , "[]" ) ;
1105+ assert_eq ! ( format!( "{}" , Cell :: F64Array ( vec![ ] ) ) , "[]" ) ;
1106+ assert_eq ! ( format!( "{}" , Cell :: StringArray ( vec![ ] ) ) , "[]" ) ;
1107+ }
1108+
1109+ #[ cfg( all( feature = "pg_test" , pgrx_embed) ) ]
1110+ #[ test]
1111+ fn test_cell_into_datum_scalars_round_trip ( ) {
1112+ let bool_datum = Cell :: Bool ( true ) . into_datum ( ) . expect ( "bool should convert" ) ;
1113+ let bool_value =
1114+ unsafe { bool:: from_datum ( bool_datum, false ) } . expect ( "bool should decode" ) ;
1115+ assert ! ( bool_value) ;
1116+
1117+ let i32_datum = Cell :: I32 ( 42 ) . into_datum ( ) . expect ( "i32 should convert" ) ;
1118+ let i32_value = unsafe { i32:: from_datum ( i32_datum, false ) } . expect ( "i32 should decode" ) ;
1119+ assert_eq ! ( i32_value, 42 ) ;
1120+
1121+ let f64_datum = Cell :: F64 ( 12.5 ) . into_datum ( ) . expect ( "f64 should convert" ) ;
1122+ let f64_value = unsafe { f64:: from_datum ( f64_datum, false ) } . expect ( "f64 should decode" ) ;
1123+ assert_eq ! ( f64_value, 12.5 ) ;
1124+
1125+ let string_datum = Cell :: String ( "hello" . to_string ( ) )
1126+ . into_datum ( )
1127+ . expect ( "string should convert" ) ;
1128+ let string_value =
1129+ unsafe { String :: from_datum ( string_datum, false ) } . expect ( "string should decode" ) ;
1130+ assert_eq ! ( string_value, "hello" ) ;
1131+ }
1132+
1133+ #[ cfg( all( feature = "pg_test" , pgrx_embed) ) ]
1134+ #[ test]
1135+ fn test_cell_into_datum_arrays_round_trip ( ) {
1136+ let bool_array_datum = Cell :: BoolArray ( vec ! [ Some ( true ) , None , Some ( false ) ] )
1137+ . into_datum ( )
1138+ . expect ( "bool array should convert" ) ;
1139+ let bool_array_value = unsafe { Vec :: < Option < bool > > :: from_datum ( bool_array_datum, false ) }
1140+ . expect ( "bool array should decode" ) ;
1141+ assert_eq ! ( bool_array_value, vec![ Some ( true ) , None , Some ( false ) ] ) ;
1142+
1143+ let i64_array_datum = Cell :: I64Array ( vec ! [ Some ( 1 ) , None , Some ( 3 ) ] )
1144+ . into_datum ( )
1145+ . expect ( "i64 array should convert" ) ;
1146+ let i64_array_value = unsafe { Vec :: < Option < i64 > > :: from_datum ( i64_array_datum, false ) }
1147+ . expect ( "i64 array should decode" ) ;
1148+ assert_eq ! ( i64_array_value, vec![ Some ( 1 ) , None , Some ( 3 ) ] ) ;
1149+
1150+ let string_array_datum =
1151+ Cell :: StringArray ( vec ! [ Some ( "foo" . to_string( ) ) , None , Some ( "bar" . to_string( ) ) ] )
1152+ . into_datum ( )
1153+ . expect ( "string array should convert" ) ;
1154+ let string_array_value =
1155+ unsafe { Vec :: < Option < String > > :: from_datum ( string_array_datum, false ) }
1156+ . expect ( "string array should decode" ) ;
1157+ assert_eq ! (
1158+ string_array_value,
1159+ vec![ Some ( "foo" . to_string( ) ) , None , Some ( "bar" . to_string( ) ) ]
1160+ ) ;
1161+ }
1162+
1163+ #[ test]
1164+ fn test_cell_into_datum_type_oid_is_invalid ( ) {
1165+ assert_eq ! ( Cell :: type_oid( ) , Oid :: INVALID ) ;
1166+ }
1167+ }
0 commit comments