Skip to content

Commit f56b281

Browse files
burmeciaCopilot
andauthored
chore: [WRA-14] enhance test cases coverage (#583)
* chore: enhance test case coverage * Update wrappers/src/fdw/airtable_fdw/tests.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * chore: update data type references in airtable_fdw tests * chore: enhance mock server metadata and update test cases * chore: add additional test cases for fields and partitioning transforms to bids table schema * chore: update test commands to use pgrx for supabase-wrappers and enhance feature checks * chore: update test commands to use cargo test with specific features for supabase-wrappers * chore: add rustflags for Linux target in Cargo configuration * chore: add RUSTFLAGS to workflows for improved warning handling and unresolved symbol management * chore: enhance test coverage by adding new test cases and updating logflare schema fields * chore: enhance test coverage by adding new foreign table creation tests for ClickHouse * chore: enhance test coverage by adding tests for new table creation and insertion in ClickHouse * chore: enhance test coverage by updating query assertions in ClickHouse tests * chore: enhance test coverage by expanding insert statement in bigquery tests * chore: enhance test coverage by updating Stripe mock tests and preserving future insert/update/delete logic * chore: enhance test coverage by updating endpoint logic and adding new test cases for timestamp fields * chore: enhance test coverage by adding support for additional ClickHouse data types and updating related tests --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 77d4200 commit f56b281

File tree

17 files changed

+748
-81
lines changed

17 files changed

+748
-81
lines changed

.cargo/config.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
[target.'cfg(target_os="macos")']
22
# Postgres symbols won't be available until runtime
33
rustflags = ["-Clink-arg=-Wl,-undefined,dynamic_lookup"]
4+
5+
[target.'cfg(target_os="linux")']
6+
# Postgres symbols won't be available until runtime
7+
rustflags = ["-Clink-arg=-Wl,--unresolved-symbols=ignore-all"]

.github/workflows/coverage.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,12 @@ jobs:
5757
5858
- name: Generate code coverage
5959
id: coverage
60+
env:
61+
RUSTFLAGS: "-D warnings -Clink-arg=-Wl,--unresolved-symbols=ignore-all"
6062
run: |
6163
source <(cargo llvm-cov show-env --export-prefix --no-cfg-coverage)
6264
cargo llvm-cov clean --workspace
63-
cargo test -p supabase-wrappers --lib
65+
cargo test -p supabase-wrappers --no-default-features --features pg15 --lib
6466
cargo pgrx test --features "native_fdws" --manifest-path wrappers/Cargo.toml pg15
6567
cargo llvm-cov report --lcov --output-path lcov.info
6668

.github/workflows/test_supabase_wrappers.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,7 @@ jobs:
5353
run: |
5454
cd supabase-wrappers && RUSTFLAGS="-D warnings" cargo clippy --all --tests --no-deps
5555
56-
- run: cd supabase-wrappers && cargo test
56+
- name: Run tests
57+
env:
58+
RUSTFLAGS: "-D warnings -Clink-arg=-Wl,--unresolved-symbols=ignore-all"
59+
run: cargo test -p supabase-wrappers --no-default-features --features pg15 --lib

supabase-wrappers/src/interface.rs

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

supabase-wrappers/src/qual.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,3 +501,45 @@ pub(crate) unsafe fn extract_quals(
501501
})
502502
}
503503
}
504+
505+
#[cfg(test)]
506+
mod tests {
507+
use super::*;
508+
#[cfg(all(feature = "pg_test", pgrx_embed))]
509+
use pgrx::IntoDatum;
510+
511+
#[cfg(all(feature = "pg_test", pgrx_embed))]
512+
#[test]
513+
fn test_form_array_from_datum_int4_array() {
514+
let values = vec![1_i32, 2_i32, 3_i32];
515+
let datum = values
516+
.into_datum()
517+
.expect("int4 array datum should be created");
518+
519+
let result = unsafe { form_array_from_datum(datum, false, pg_sys::INT4ARRAYOID) };
520+
let result = result.expect("int4 array should be parsed");
521+
522+
assert_eq!(result.len(), 3);
523+
assert!(matches!(result[0], Cell::I32(1)));
524+
assert!(matches!(result[1], Cell::I32(2)));
525+
assert!(matches!(result[2], Cell::I32(3)));
526+
}
527+
528+
#[test]
529+
fn test_form_array_from_datum_null_datum_returns_none() {
530+
let result = unsafe { form_array_from_datum(0.into(), true, pg_sys::INT4ARRAYOID) };
531+
assert!(result.is_none());
532+
}
533+
534+
#[cfg(all(feature = "pg_test", pgrx_embed))]
535+
#[test]
536+
fn test_form_array_from_datum_unsupported_oid_returns_none() {
537+
let values = vec![1_i32, 2_i32];
538+
let datum = values
539+
.into_datum()
540+
.expect("int4 array datum should be created");
541+
542+
let result = unsafe { form_array_from_datum(datum, false, pg_sys::UUIDARRAYOID) };
543+
assert!(result.is_none());
544+
}
545+
}

wrappers/dockerfiles/airtable/server.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,15 @@ def do_GET(self):
4949
"strings_array_field": ["foo", "bar"],
5050
"numerics_array_field": [1, 2],
5151
"bools_array_field": [False],
52-
"objects_array_field": [{"foo": "bar"}, {"foo": "baz"}]
52+
"objects_array_field": [{"foo": "bar"}, {"foo": "baz"}],
53+
"char_field": 1,
54+
"int2_field": 1,
55+
"int4_field": 123,
56+
"int8_field": 123456789012345678,
57+
"float4_field": 1.23,
58+
"float8_field": 1.23456789012345,
59+
"date_field": "2023-07-19",
60+
"timestamptz_field": "2023-07-19T06:39:15.000Z",
5361
},
5462
)
5563
client.create(
@@ -63,7 +71,15 @@ def do_GET(self):
6371
"strings_array_field": ["baz", "qux"],
6472
"numerics_array_field": [3, 4],
6573
"bools_array_field": [True, False, True],
66-
"objects_array_field": [{"foo": "qux"}]
74+
"objects_array_field": [{"foo": "qux"}],
75+
"char_field": 2,
76+
"int2_field": 2,
77+
"int4_field": 456,
78+
"int8_field": 123456789012345678,
79+
"float4_field": 4.56,
80+
"float8_field": 1.23456789012345,
81+
"date_field": "2023-07-20",
82+
"timestamptz_field": "2023-07-20T06:39:15.000Z",
6783
},
6884
)
6985

wrappers/dockerfiles/logflare/data.json

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,18 @@
5454
"tenant_params": []
5555
}
5656
],
57-
"timestamp": 1739866449830000
57+
"timestamp": 1739866449830000,
58+
"bool_field": false,
59+
"char_field": 12,
60+
"int2_field": 123,
61+
"int4_field": 1234,
62+
"int8_field": 12345678,
63+
"float4_field": 12.34,
64+
"float8_field": 1.23456789012345,
65+
"numeric_field": 1234.5678,
66+
"date_field": "2023-07-19",
67+
"ts_field": "2023-07-19T06:39:15",
68+
"tstz_field": "2023-07-19T06:39:15.000Z"
5869
},
5970
{
6071
"event_message": "GET /",
@@ -110,7 +121,18 @@
110121
"tenant_params": []
111122
}
112123
],
113-
"timestamp": 1739866449826000
124+
"timestamp": 1739866449826000,
125+
"bool_field": false,
126+
"char_field": 12,
127+
"int2_field": 123,
128+
"int4_field": 1234,
129+
"int8_field": 12345678,
130+
"float4_field": 12.34,
131+
"float8_field": 1.23456789012345,
132+
"numeric_field": 1234.5678,
133+
"date_field": "2023-07-19",
134+
"ts_field": "2023-07-19T06:39:15",
135+
"tstz_field": "2023-07-19T06:39:15.000Z"
114136
}
115137
]
116138
}

0 commit comments

Comments
 (0)