v0.3.3-pre.003-fix.001
This commit is contained in:
114
crates/ksp-store-postgres-lib/unit_tests/schema.rs
Normal file
114
crates/ksp-store-postgres-lib/unit_tests/schema.rs
Normal file
@@ -0,0 +1,114 @@
|
||||
// file: crates/ksp-store-postgres-lib/unit_tests/schema.rs
|
||||
// version: 1
|
||||
|
||||
fn actual_column(name: &str, udt_name: &str, nullable: bool) -> super::ActualColumn {
|
||||
return super::ActualColumn {
|
||||
default: std::option::Option::None,
|
||||
generated: "NEVER".to_owned(),
|
||||
identity: "NO".to_owned(),
|
||||
name: name.to_owned(),
|
||||
nullable,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: udt_name.to_owned(),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_003_fix_001_v000_resource_is_relocated_without_changing_legacy_sql() {
|
||||
assert_eq!(crate::V000_RESOURCES.len(), 1);
|
||||
let resource = crate::V000_RESOURCES[0];
|
||||
assert_eq!(resource.id, "tables/001_ksp_store_schema_migrations.sql");
|
||||
assert_eq!(
|
||||
resource.sql,
|
||||
"CREATE TABLE ksp_store_schema_migrations (\n version BIGINT PRIMARY KEY,\n name TEXT NOT NULL,\n checksum TEXT NOT NULL,\n applied_at TIMESTAMPTZ NOT NULL\n);\n",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_003_fix_001_v001_resources_are_split_and_idempotent_by_object_family() {
|
||||
assert_eq!(crate::V001_RESOURCES.len(), 40);
|
||||
let table_resources = crate::V001_RESOURCES.iter().filter(|resource| return resource.id.starts_with("tables/")).collect::<std::vec::Vec<_>>();
|
||||
let constraint_resources = crate::V001_RESOURCES.iter().filter(|resource| return resource.id.starts_with("constraints/")).collect::<std::vec::Vec<_>>();
|
||||
let index_resources = crate::V001_RESOURCES.iter().filter(|resource| return resource.id.starts_with("indexes/")).collect::<std::vec::Vec<_>>();
|
||||
assert_eq!(table_resources.len(), 4);
|
||||
assert_eq!(constraint_resources.len(), 35);
|
||||
assert_eq!(index_resources.len(), 1);
|
||||
for resource in table_resources {
|
||||
assert!(resource.sql.contains("CREATE TABLE IF NOT EXISTS"));
|
||||
assert!(resource.sql.contains("ADD COLUMN IF NOT EXISTS"));
|
||||
}
|
||||
for resource in constraint_resources {
|
||||
assert!(resource.sql.contains("IF NOT EXISTS"));
|
||||
}
|
||||
for resource in index_resources {
|
||||
assert!(resource.sql.contains("CREATE INDEX IF NOT EXISTS"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_003_fix_001_external_extra_columns_are_accepted_only_when_they_cannot_block_ksp_inserts() {
|
||||
let nullable = actual_column("external_nullable", "text", true);
|
||||
assert!(nullable.is_non_blocking_extra());
|
||||
let mut with_default = actual_column("external_default", "text", true);
|
||||
with_default.default = std::option::Option::Some("'x'::text".to_owned());
|
||||
assert!(!with_default.is_non_blocking_extra());
|
||||
let mut identity = actual_column("external_identity", "int8", true);
|
||||
identity.identity = "YES".to_owned();
|
||||
assert!(!identity.is_non_blocking_extra());
|
||||
let mut generated = actual_column("external_generated", "text", true);
|
||||
generated.generated = "ALWAYS".to_owned();
|
||||
assert!(!generated.is_non_blocking_extra());
|
||||
let blocking = actual_column("external_required", "text", false);
|
||||
assert!(!blocking.is_non_blocking_extra());
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_003_fix_001_required_column_matching_ignores_integer_precision_but_requires_numeric_20_0() {
|
||||
let expected_int = super::ColumnContract {
|
||||
name: "version",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::None,
|
||||
numeric_scale: std::option::Option::None,
|
||||
udt_name: "int8",
|
||||
};
|
||||
let mut actual_int = actual_column("version", "int8", false);
|
||||
actual_int.numeric_precision = std::option::Option::Some(64);
|
||||
actual_int.numeric_scale = std::option::Option::Some(0);
|
||||
assert!(actual_int.matches(&expected_int));
|
||||
let expected_numeric = super::ColumnContract {
|
||||
name: "slot",
|
||||
nullable: false,
|
||||
numeric_precision: std::option::Option::Some(20),
|
||||
numeric_scale: std::option::Option::Some(0),
|
||||
udt_name: "numeric",
|
||||
};
|
||||
let mut actual_numeric = actual_column("slot", "numeric", false);
|
||||
actual_numeric.numeric_precision = std::option::Option::Some(20);
|
||||
actual_numeric.numeric_scale = std::option::Option::Some(0);
|
||||
assert!(actual_numeric.matches(&expected_numeric));
|
||||
actual_numeric.numeric_precision = std::option::Option::Some(19);
|
||||
assert!(!actual_numeric.matches(&expected_numeric));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_003_fix_001_catalog_normalization_and_resource_owned_constraint_definition_are_deterministic() {
|
||||
let normalized = super::normalize_catalog_sql("CHECK ((slot >= (0)::numeric) AND (slot <= (18446744073709551615)::numeric))");
|
||||
assert_eq!(normalized, "checkslot>=0andslot<=18446744073709551615");
|
||||
let resource = crate::V001_RESOURCES.iter().find(|resource| return resource.id == "constraints/006_ck_ksp_raw_transactions_slot.sql");
|
||||
let resource = match resource {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => {
|
||||
assert!(false, "V001 slot constraint resource must remain embedded");
|
||||
return;
|
||||
},
|
||||
};
|
||||
let expected = super::expected_constraint_definition(resource.sql, "ck_ksp_raw_transactions_slot");
|
||||
assert_eq!(expected.as_deref(), std::option::Option::Some(normalized.as_str()));
|
||||
assert_ne!(expected.as_deref(), std::option::Option::Some("checkslot>=0andslot<=10"));
|
||||
return;
|
||||
}
|
||||
Reference in New Issue
Block a user