Skip to content

Commit f70f314

Browse files
committed
Add testcase
1 parent e60f10f commit f70f314

5 files changed

Lines changed: 283 additions & 0 deletions

File tree

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

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ mod tests {
603603
#[case(OrmArg::Seaorm, Orm::SeaOrm)]
604604
#[case(OrmArg::Sqlalchemy, Orm::SqlAlchemy)]
605605
#[case(OrmArg::Sqlmodel, Orm::SqlModel)]
606+
#[case(OrmArg::Jpa, Orm::Jpa)]
606607
fn orm_arg_maps_to_enum(#[case] arg: OrmArg, #[case] expected: Orm) {
607608
assert_eq!(Orm::from(arg), expected);
608609
}
@@ -767,6 +768,23 @@ mod tests {
767768
assert!(!root.join("model.py").exists());
768769
}
769770

771+
#[tokio::test]
772+
async fn clean_export_dir_removes_java_files_for_jpa() {
773+
let tmp = tempdir().unwrap();
774+
let root = tmp.path().join("export_dir");
775+
std_fs::create_dir_all(&root).unwrap();
776+
777+
std_fs::write(root.join("User.java"), "// java entity").unwrap();
778+
std_fs::write(root.join("Order.java"), "// java entity").unwrap();
779+
std_fs::write(root.join("keep.rs"), "// keep this").unwrap();
780+
781+
clean_export_dir(&root, Orm::Jpa).await.unwrap();
782+
783+
assert!(!root.join("User.java").exists());
784+
assert!(!root.join("Order.java").exists());
785+
assert!(root.join("keep.rs").exists());
786+
}
787+
770788
#[tokio::test]
771789
async fn clean_export_dir_handles_missing_directory() {
772790
let tmp = tempdir().unwrap();
@@ -828,4 +846,44 @@ mod tests {
828846
let result = clean_dir_recursive(&file_path, "rs").await;
829847
assert!(result.is_ok());
830848
}
849+
850+
#[test]
851+
fn build_output_path_jpa_uses_pascal_case_java_extension() {
852+
use std::path::Path;
853+
let root = Path::new("src/models");
854+
855+
// snake_case model → PascalCase .java
856+
let rel_path = Path::new("order_item.json");
857+
let out = build_output_path(root, rel_path, Orm::Jpa);
858+
assert_eq!(out, Path::new("src/models/OrderItem.java"));
859+
860+
// Single word
861+
let rel_path2 = Path::new("users.json");
862+
let out2 = build_output_path(root, rel_path2, Orm::Jpa);
863+
assert_eq!(out2, Path::new("src/models/Users.java"));
864+
865+
// Nested path
866+
let rel_path3 = Path::new("blog/post_comment.yaml");
867+
let out3 = build_output_path(root, rel_path3, Orm::Jpa);
868+
assert_eq!(out3, Path::new("src/models/blog/PostComment.java"));
869+
}
870+
871+
#[test]
872+
fn build_output_path_jpa_strips_vespertide_suffix() {
873+
use std::path::Path;
874+
let root = Path::new("src/models");
875+
876+
let rel_path = Path::new("user.vespertide.json");
877+
let out = build_output_path(root, rel_path, Orm::Jpa);
878+
assert_eq!(out, Path::new("src/models/User.java"));
879+
}
880+
881+
#[rstest]
882+
#[case("order_item", "OrderItem")]
883+
#[case("users", "Users")]
884+
#[case("a", "A")]
885+
#[case("user_profile_image", "UserProfileImage")]
886+
fn test_to_pascal_case(#[case] input: &str, #[case] expected: &str) {
887+
assert_eq!(to_pascal_case(input), expected);
888+
}
831889
}

crates/vespertide-exporter/src/jpa/mod.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,11 +1059,153 @@ mod tests {
10591059
assert_snapshot!(result);
10601060
}
10611061

1062+
#[test]
1063+
fn test_unnamed_index_and_unique() {
1064+
let table = TableDef {
1065+
name: "events".into(),
1066+
description: None,
1067+
columns: vec![
1068+
col("id", ColumnType::Simple(SimpleColumnType::Integer)),
1069+
col("venue_id", ColumnType::Simple(SimpleColumnType::Integer)),
1070+
col("date", ColumnType::Simple(SimpleColumnType::Date)),
1071+
],
1072+
constraints: vec![
1073+
TableConstraint::PrimaryKey {
1074+
auto_increment: false,
1075+
columns: vec!["id".into()],
1076+
},
1077+
TableConstraint::Index {
1078+
name: None,
1079+
columns: vec!["venue_id".into(), "date".into()],
1080+
},
1081+
TableConstraint::Unique {
1082+
name: None,
1083+
columns: vec!["venue_id".into(), "date".into()],
1084+
},
1085+
],
1086+
};
1087+
1088+
let result = render_entity(&table).unwrap();
1089+
assert_snapshot!(result);
1090+
}
1091+
1092+
#[test]
1093+
fn test_fk_with_comment_and_auto_increment() {
1094+
let table = TableDef {
1095+
name: "child".into(),
1096+
description: None,
1097+
columns: vec![
1098+
ColumnDef {
1099+
name: "parent_id".into(),
1100+
r#type: ColumnType::Simple(SimpleColumnType::Integer),
1101+
nullable: false,
1102+
default: None,
1103+
comment: Some("References parent table".into()),
1104+
primary_key: None,
1105+
unique: None,
1106+
index: None,
1107+
foreign_key: None,
1108+
},
1109+
col("value", ColumnType::Simple(SimpleColumnType::Text)),
1110+
],
1111+
constraints: vec![
1112+
TableConstraint::PrimaryKey {
1113+
auto_increment: true,
1114+
columns: vec!["parent_id".into()],
1115+
},
1116+
TableConstraint::ForeignKey {
1117+
name: None,
1118+
columns: vec!["parent_id".into()],
1119+
ref_table: "parent".into(),
1120+
ref_columns: vec!["id".into()],
1121+
on_delete: None,
1122+
on_update: None,
1123+
},
1124+
],
1125+
};
1126+
1127+
let result = render_entity(&table).unwrap();
1128+
assert_snapshot!(result);
1129+
}
1130+
1131+
#[test]
1132+
fn test_server_default_and_true_boolean() {
1133+
let table = TableDef {
1134+
name: "logs".into(),
1135+
description: None,
1136+
columns: vec![
1137+
col("id", ColumnType::Simple(SimpleColumnType::Integer)),
1138+
ColumnDef {
1139+
name: "active".into(),
1140+
r#type: ColumnType::Simple(SimpleColumnType::Boolean),
1141+
nullable: false,
1142+
default: Some(DefaultValue::Bool(true)),
1143+
comment: None,
1144+
primary_key: None,
1145+
unique: None,
1146+
index: None,
1147+
foreign_key: None,
1148+
},
1149+
ColumnDef {
1150+
name: "created_at".into(),
1151+
r#type: ColumnType::Simple(SimpleColumnType::Timestamptz),
1152+
nullable: false,
1153+
default: Some(DefaultValue::String("NOW()".into())),
1154+
comment: None,
1155+
primary_key: None,
1156+
unique: None,
1157+
index: None,
1158+
foreign_key: None,
1159+
},
1160+
ColumnDef {
1161+
name: "score".into(),
1162+
r#type: ColumnType::Simple(SimpleColumnType::Real),
1163+
nullable: false,
1164+
default: Some(DefaultValue::Float(1.5)),
1165+
comment: None,
1166+
primary_key: None,
1167+
unique: None,
1168+
index: None,
1169+
foreign_key: None,
1170+
},
1171+
ColumnDef {
1172+
name: "tag".into(),
1173+
r#type: ColumnType::Simple(SimpleColumnType::Text),
1174+
nullable: false,
1175+
default: Some(DefaultValue::String("UNKNOWN_EXPR".into())),
1176+
comment: None,
1177+
primary_key: None,
1178+
unique: None,
1179+
index: None,
1180+
foreign_key: None,
1181+
},
1182+
],
1183+
constraints: vec![TableConstraint::PrimaryKey {
1184+
auto_increment: true,
1185+
columns: vec!["id".into()],
1186+
}],
1187+
};
1188+
1189+
let result = render_entity(&table).unwrap();
1190+
assert_snapshot!(result);
1191+
}
1192+
1193+
#[test]
1194+
fn test_column_type_to_java_string_enum() {
1195+
// Exercises the string enum branch in column_type_to_java
1196+
let ty = ColumnType::Complex(ComplexColumnType::Enum {
1197+
name: "status".into(),
1198+
values: EnumValues::String(vec!["a".into()]),
1199+
});
1200+
assert_eq!(column_type_to_java(&ty), "String");
1201+
}
1202+
10621203
#[rstest]
10631204
#[case("order_item", "OrderItem")]
10641205
#[case("users", "Users")]
10651206
#[case("a", "A")]
10661207
#[case("user_profile_image", "UserProfileImage")]
1208+
#[case("", "")]
10671209
fn test_to_pascal_case(#[case] input: &str, #[case] expected: &str) {
10681210
assert_eq!(to_pascal_case(input), expected);
10691211
}
@@ -1072,6 +1214,7 @@ mod tests {
10721214
#[case("created_at", "createdAt")]
10731215
#[case("id", "id")]
10741216
#[case("user_profile_image", "userProfileImage")]
1217+
#[case("", "")]
10751218
fn test_to_camel_case(#[case] input: &str, #[case] expected: &str) {
10761219
assert_eq!(to_camel_case(input), expected);
10771220
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
source: crates/vespertide-exporter/src/jpa/mod.rs
3+
expression: result
4+
---
5+
import jakarta.persistence.*;
6+
7+
@Entity
8+
@Table(name = "child")
9+
public class Child {
10+
11+
/** References parent table */
12+
@Id
13+
@GeneratedValue(strategy = GenerationType.IDENTITY)
14+
@ManyToOne(fetch = FetchType.LAZY)
15+
@JoinColumn(name = "parent_id", nullable = false)
16+
private Parent parent;
17+
18+
@Column(name = "value", nullable = false, columnDefinition = "TEXT")
19+
private String value;
20+
21+
protected Child() {
22+
}
23+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
source: crates/vespertide-exporter/src/jpa/mod.rs
3+
expression: result
4+
---
5+
import jakarta.persistence.*;
6+
import java.time.OffsetDateTime;
7+
8+
@Entity
9+
@Table(name = "logs")
10+
public class Logs {
11+
12+
@Id
13+
@GeneratedValue(strategy = GenerationType.IDENTITY)
14+
@Column(name = "id")
15+
private Integer id;
16+
17+
@Column(name = "active", nullable = false)
18+
private Boolean active = true;
19+
20+
@Column(name = "created_at", nullable = false)
21+
private OffsetDateTime createdAt;
22+
23+
@Column(name = "score", nullable = false)
24+
private Float score = 1.5;
25+
26+
@Column(name = "tag", nullable = false, columnDefinition = "TEXT")
27+
private String tag;
28+
29+
protected Logs() {
30+
}
31+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
source: crates/vespertide-exporter/src/jpa/mod.rs
3+
expression: result
4+
---
5+
import jakarta.persistence.*;
6+
import java.time.LocalDate;
7+
8+
@Entity
9+
@Table(name = "events", indexes = {
10+
@Index(columnList = "venue_id, date")
11+
}, uniqueConstraints = {
12+
@UniqueConstraint(columnNames = {"venue_id", "date"})
13+
})
14+
public class Events {
15+
16+
@Id
17+
@Column(name = "id")
18+
private Integer id;
19+
20+
@Column(name = "venue_id", nullable = false)
21+
private Integer venueId;
22+
23+
@Column(name = "date", nullable = false)
24+
private LocalDate date;
25+
26+
protected Events() {
27+
}
28+
}

0 commit comments

Comments
 (0)