Skip to content

Commit ed3ecbf

Browse files
committed
Add testcase
1 parent f42fc3a commit ed3ecbf

16 files changed

+708
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ settings.local.json
44
coverage
55
lcov.info
66
.sisyphus
7+
.omc

crates/vespertide-cli/src/commands/diff.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,9 @@ mod tests {
247247
use std::path::PathBuf;
248248
use tempfile::tempdir;
249249
use vespertide_config::VespertideConfig;
250-
use vespertide_core::{ColumnDef, ColumnType, SimpleColumnType, TableConstraint, TableDef};
250+
use vespertide_core::{
251+
ColumnDef, ColumnType, ReferenceAction, SimpleColumnType, TableConstraint, TableDef,
252+
};
251253

252254
struct CwdGuard {
253255
original: PathBuf,
@@ -578,6 +580,28 @@ mod tests {
578580
"This is a very long comment...".bright_cyan().bold()
579581
)
580582
)]
583+
#[case(
584+
MigrationAction::ReplaceConstraint {
585+
table: "posts".into(),
586+
from: vespertide_core::TableConstraint::ForeignKey {
587+
name: Some("fk_user".into()),
588+
columns: vec!["user_id".into()],
589+
ref_table: "users".into(),
590+
ref_columns: vec!["id".into()],
591+
on_delete: None,
592+
on_update: None,
593+
},
594+
to: vespertide_core::TableConstraint::ForeignKey {
595+
name: Some("fk_user".into()),
596+
columns: vec!["user_id".into()],
597+
ref_table: "users".into(),
598+
ref_columns: vec!["id".into()],
599+
on_delete: Some(ReferenceAction::Cascade),
600+
on_update: None,
601+
},
602+
},
603+
format!("{} {} {} {} {} {}", "Replace constraint:".bright_yellow(), "fk_user FK (user_id) -> users".bright_cyan().bold(), "->".bright_white(), "fk_user FK (user_id) -> users".bright_cyan().bold(), "on".bright_white(), "posts".bright_cyan())
604+
)]
581605
#[serial]
582606
fn format_action_cases(#[case] action: MigrationAction, #[case] expected: String) {
583607
assert_eq!(format_action(&action), expected);

crates/vespertide-core/src/action.rs

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,4 +1095,176 @@ mod tests {
10951095
panic!("Expected RemoveConstraint");
10961096
}
10971097
}
1098+
1099+
#[rstest]
1100+
#[case::replace_constraint_primary_key(
1101+
MigrationAction::ReplaceConstraint {
1102+
table: "users".into(),
1103+
from: TableConstraint::PrimaryKey {
1104+
auto_increment: false,
1105+
columns: vec!["id".into()],
1106+
},
1107+
to: TableConstraint::PrimaryKey {
1108+
auto_increment: true,
1109+
columns: vec!["id".into()],
1110+
},
1111+
},
1112+
"ReplaceConstraint: users.PRIMARY KEY"
1113+
)]
1114+
#[case::replace_constraint_unique_with_name(
1115+
MigrationAction::ReplaceConstraint {
1116+
table: "users".into(),
1117+
from: TableConstraint::Unique {
1118+
name: None,
1119+
columns: vec!["email".into()],
1120+
},
1121+
to: TableConstraint::Unique {
1122+
name: Some("uq_email".into()),
1123+
columns: vec!["email".into()],
1124+
},
1125+
},
1126+
"ReplaceConstraint: users.uq_email (UNIQUE)"
1127+
)]
1128+
#[case::replace_constraint_unique_without_name(
1129+
MigrationAction::ReplaceConstraint {
1130+
table: "users".into(),
1131+
from: TableConstraint::Unique {
1132+
name: Some("uq_email".into()),
1133+
columns: vec!["email".into()],
1134+
},
1135+
to: TableConstraint::Unique {
1136+
name: None,
1137+
columns: vec!["email".into()],
1138+
},
1139+
},
1140+
"ReplaceConstraint: users.UNIQUE"
1141+
)]
1142+
#[case::replace_constraint_foreign_key_with_name(
1143+
MigrationAction::ReplaceConstraint {
1144+
table: "posts".into(),
1145+
from: TableConstraint::ForeignKey {
1146+
name: None,
1147+
columns: vec!["user_id".into()],
1148+
ref_table: "users".into(),
1149+
ref_columns: vec!["id".into()],
1150+
on_delete: None,
1151+
on_update: None,
1152+
},
1153+
to: TableConstraint::ForeignKey {
1154+
name: Some("fk_user".into()),
1155+
columns: vec!["user_id".into()],
1156+
ref_table: "users".into(),
1157+
ref_columns: vec!["id".into()],
1158+
on_delete: None,
1159+
on_update: None,
1160+
},
1161+
},
1162+
"ReplaceConstraint: posts.fk_user (FOREIGN KEY)"
1163+
)]
1164+
#[case::replace_constraint_foreign_key_without_name(
1165+
MigrationAction::ReplaceConstraint {
1166+
table: "posts".into(),
1167+
from: TableConstraint::ForeignKey {
1168+
name: Some("fk_user".into()),
1169+
columns: vec!["user_id".into()],
1170+
ref_table: "users".into(),
1171+
ref_columns: vec!["id".into()],
1172+
on_delete: None,
1173+
on_update: None,
1174+
},
1175+
to: TableConstraint::ForeignKey {
1176+
name: None,
1177+
columns: vec!["user_id".into()],
1178+
ref_table: "users".into(),
1179+
ref_columns: vec!["id".into()],
1180+
on_delete: None,
1181+
on_update: None,
1182+
},
1183+
},
1184+
"ReplaceConstraint: posts.FOREIGN KEY"
1185+
)]
1186+
#[case::replace_constraint_check(
1187+
MigrationAction::ReplaceConstraint {
1188+
table: "users".into(),
1189+
from: TableConstraint::Check {
1190+
name: "chk_age".into(),
1191+
expr: "age > 0".into(),
1192+
},
1193+
to: TableConstraint::Check {
1194+
name: "chk_age".into(),
1195+
expr: "age >= 0".into(),
1196+
},
1197+
},
1198+
"ReplaceConstraint: users.chk_age (CHECK)"
1199+
)]
1200+
#[case::replace_constraint_index_with_name(
1201+
MigrationAction::ReplaceConstraint {
1202+
table: "users".into(),
1203+
from: TableConstraint::Index {
1204+
name: None,
1205+
columns: vec!["email".into()],
1206+
},
1207+
to: TableConstraint::Index {
1208+
name: Some("ix_users__email".into()),
1209+
columns: vec!["email".into()],
1210+
},
1211+
},
1212+
"ReplaceConstraint: users.ix_users__email (INDEX)"
1213+
)]
1214+
#[case::replace_constraint_index_without_name(
1215+
MigrationAction::ReplaceConstraint {
1216+
table: "users".into(),
1217+
from: TableConstraint::Index {
1218+
name: Some("ix_users__email".into()),
1219+
columns: vec!["email".into()],
1220+
},
1221+
to: TableConstraint::Index {
1222+
name: None,
1223+
columns: vec!["email".into()],
1224+
},
1225+
},
1226+
"ReplaceConstraint: users.INDEX"
1227+
)]
1228+
fn test_display_replace_constraint(#[case] action: MigrationAction, #[case] expected: &str) {
1229+
assert_eq!(action.to_string(), expected);
1230+
}
1231+
1232+
#[test]
1233+
fn test_action_with_prefix_replace_constraint() {
1234+
let action = MigrationAction::ReplaceConstraint {
1235+
table: "posts".into(),
1236+
from: TableConstraint::ForeignKey {
1237+
name: Some("fk_user".into()),
1238+
columns: vec!["user_id".into()],
1239+
ref_table: "users".into(),
1240+
ref_columns: vec!["id".into()],
1241+
on_delete: Some(ReferenceAction::Cascade),
1242+
on_update: None,
1243+
},
1244+
to: TableConstraint::ForeignKey {
1245+
name: Some("fk_user".into()),
1246+
columns: vec!["user_id".into()],
1247+
ref_table: "users".into(),
1248+
ref_columns: vec!["id".into()],
1249+
on_delete: Some(ReferenceAction::SetNull),
1250+
on_update: None,
1251+
},
1252+
};
1253+
let prefixed = action.with_prefix("myapp_");
1254+
if let MigrationAction::ReplaceConstraint { table, from, to } = prefixed {
1255+
assert_eq!(table.as_str(), "myapp_posts");
1256+
if let TableConstraint::ForeignKey { ref_table, .. } = from {
1257+
assert_eq!(ref_table.as_str(), "myapp_users");
1258+
} else {
1259+
panic!("Expected ForeignKey constraint in from");
1260+
}
1261+
if let TableConstraint::ForeignKey { ref_table, .. } = to {
1262+
assert_eq!(ref_table.as_str(), "myapp_users");
1263+
} else {
1264+
panic!("Expected ForeignKey constraint in to");
1265+
}
1266+
} else {
1267+
panic!("Expected ReplaceConstraint");
1268+
}
1269+
}
10981270
}

crates/vespertide-planner/src/apply.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,4 +1562,92 @@ mod tests {
15621562

15631563
assert_err_kind(err, ErrKind::ColumnNotFound);
15641564
}
1565+
1566+
#[test]
1567+
fn apply_replace_constraint_fk() {
1568+
let mut schema = vec![table(
1569+
"posts",
1570+
vec![
1571+
col("id", ColumnType::Simple(SimpleColumnType::Integer)),
1572+
col("user_id", ColumnType::Simple(SimpleColumnType::Integer)),
1573+
],
1574+
vec![TableConstraint::ForeignKey {
1575+
name: Some("fk_user".into()),
1576+
columns: vec!["user_id".into()],
1577+
ref_table: "users".into(),
1578+
ref_columns: vec!["id".into()],
1579+
on_delete: None,
1580+
on_update: None,
1581+
}],
1582+
)];
1583+
1584+
let from = TableConstraint::ForeignKey {
1585+
name: Some("fk_user".into()),
1586+
columns: vec!["user_id".into()],
1587+
ref_table: "users".into(),
1588+
ref_columns: vec!["id".into()],
1589+
on_delete: None,
1590+
on_update: None,
1591+
};
1592+
let to = TableConstraint::ForeignKey {
1593+
name: Some("fk_user".into()),
1594+
columns: vec!["user_id".into()],
1595+
ref_table: "users".into(),
1596+
ref_columns: vec!["id".into()],
1597+
on_delete: Some(vespertide_core::ReferenceAction::Cascade),
1598+
on_update: None,
1599+
};
1600+
1601+
apply_action(
1602+
&mut schema,
1603+
&MigrationAction::ReplaceConstraint {
1604+
table: "posts".into(),
1605+
from,
1606+
to: to.clone(),
1607+
},
1608+
)
1609+
.unwrap();
1610+
assert_eq!(schema[0].constraints.len(), 1);
1611+
assert_eq!(schema[0].constraints[0], to);
1612+
}
1613+
1614+
#[test]
1615+
fn apply_replace_constraint_table_not_found() {
1616+
let mut schema = vec![];
1617+
let from = idx("ix_old", vec!["col"]);
1618+
let to = idx("ix_new", vec!["col"]);
1619+
let err = apply_action(
1620+
&mut schema,
1621+
&MigrationAction::ReplaceConstraint {
1622+
table: "missing".into(),
1623+
from,
1624+
to,
1625+
},
1626+
)
1627+
.unwrap_err();
1628+
assert_err_kind(err, ErrKind::TableNotFound);
1629+
}
1630+
1631+
#[test]
1632+
fn apply_replace_constraint_no_match_leaves_unchanged() {
1633+
let existing = idx("ix_existing", vec!["col"]);
1634+
let mut schema = vec![table(
1635+
"users",
1636+
vec![col("col", ColumnType::Simple(SimpleColumnType::Integer))],
1637+
vec![existing.clone()],
1638+
)];
1639+
1640+
let from = idx("ix_nonexistent", vec!["other"]);
1641+
let to = idx("ix_new", vec!["other"]);
1642+
apply_action(
1643+
&mut schema,
1644+
&MigrationAction::ReplaceConstraint {
1645+
table: "users".into(),
1646+
from,
1647+
to,
1648+
},
1649+
)
1650+
.unwrap();
1651+
assert_eq!(schema[0].constraints, vec![existing]);
1652+
}
15651653
}

0 commit comments

Comments
 (0)