113 lines
4.7 KiB
Rust
113 lines
4.7 KiB
Rust
use super::{ERROR, packages};
|
|
|
|
#[test]
|
|
fn text_policy_is_a_single_model_modifier_and_defaults_use_the_normalized_length() {
|
|
use dever::compiler::model::persistence::{TextMode, Value};
|
|
let program = packages(&[("demo.account.model", "type Account { name: Text(1, 2) lower default \" Ä \"\ncode: Text(2) upper default \" ß \"\nbody: Text raw default \" a \"\nnote: Text? }")]).unwrap();
|
|
let columns = &program.models[0].columns;
|
|
for (column, mode, expected) in [
|
|
(2, TextMode::Lower, "ä"),
|
|
(3, TextMode::Upper, "SS"),
|
|
(4, TextMode::Raw, " a "),
|
|
] {
|
|
assert_eq!(columns[column].text, mode);
|
|
assert!(matches!(&columns[column].default, Some(Value::Text(value)) if value == expected));
|
|
}
|
|
assert_eq!(columns[5].text, TextMode::Trim);
|
|
for field in [
|
|
"name: Text raw lower",
|
|
"name: Text lower upper",
|
|
"name: Text raw raw",
|
|
"name: Int lower",
|
|
"name: List<Text> raw",
|
|
"name: Text(1, 2) default \" \"",
|
|
"name: Text(1) upper default \"ß\"",
|
|
"name: Text trim",
|
|
] {
|
|
assert!(
|
|
packages(&[("demo.account.model", &format!("type Account {{ {field} }}"))]).is_err(),
|
|
"{field}"
|
|
);
|
|
}
|
|
assert!(packages(&[("demo.account.domain", "type Input { name: Text raw }")]).is_err());
|
|
let seeded = packages(&[(
|
|
"demo.account.model",
|
|
"type Account { name: Text(1, 2) lower unique }\nseed { { name = \" Ä \" } }",
|
|
)])
|
|
.unwrap();
|
|
assert!(matches!(&seeded.models[0].seeds[0].values[0].1, Value::Text(value) if value == "ä"));
|
|
}
|
|
|
|
#[test]
|
|
fn model_choice_options_preserve_labels_and_order() {
|
|
let program = packages(&[
|
|
("demo.account.model", "type Status { Active = \"启用\"\nDisabled = \"禁用\" }\ntype Account { status: Status }"),
|
|
("demo.account.app", "options() (values: Map<model.Status, Text>) { values = model.Status.options }"),
|
|
]).unwrap();
|
|
assert!(!program.functions[0].signature.effects.database);
|
|
assert!(packages(&[("main", "type Status { Active }\npublic main() (values: Map<Text, Text>) { values = Status.options }")]).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn checked_defaults_and_generated_columns_keep_static_types() {
|
|
let program = packages(&[
|
|
("dever.database", ERROR),
|
|
("demo.account.model", "type Status { Active = \"启用\"\nDisabled = \"禁用\" }\ntype Account { uid: Uuid generated unique\nstatus: Status default Status.Active\namount: Decimal(5, 2) default -12.30\nnote: Text? default null\nname: Text(1, 8) default \"雪\" }"),
|
|
("demo.account.app", "create() (id: model.id) { row = model.create({})\nid = row.id }"),
|
|
("demo.account.api", "cmd create = app.create"),
|
|
]).unwrap();
|
|
let columns = &program.models[0].columns;
|
|
assert!(columns[2].generated);
|
|
assert_eq!(
|
|
columns[3].choice.as_ref().unwrap(),
|
|
&[
|
|
("Active".into(), "启用".into()),
|
|
("Disabled".into(), "禁用".into())
|
|
]
|
|
);
|
|
assert!(
|
|
matches!(&columns[4].default, Some(dever::compiler::model::persistence::Value::Text(value)) if value == "098770")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_defaults_and_generated_writes_fail_before_database_access() {
|
|
for field in [
|
|
"value: Decimal(5, 2) default 0.001",
|
|
"value: Decimal(5, 2) default 1000",
|
|
"value: Text(2) default \"三字符\"",
|
|
"value: Int default 1.1",
|
|
"value: Int default 9223372036854775808",
|
|
"value: Float default 1e999",
|
|
"value: Bool default null",
|
|
"value: Uuid default \"broken\"",
|
|
"value: Date default \"2025-02-29\"",
|
|
"value: Time default \"24:00:00\"",
|
|
"value: Json default \"{\\\"x\\\":1,\\\"x\\\":2}\"",
|
|
"value: Int generated",
|
|
"value: Uuid? generated",
|
|
"value: Uuid generated default \"00112233-4455-6677-8899-aabbccddeeff\"",
|
|
] {
|
|
let model = format!("type Account {{ {field} }}");
|
|
let error = packages(&[("demo.account.model", &model)]).unwrap_err();
|
|
assert_eq!(error.code, "C014", "{field}: {error:?}");
|
|
}
|
|
for body in [
|
|
"row = model.create({ uid = uid })",
|
|
"row = model.update(id, { uid = uid })",
|
|
"row = model.get(id)\nrow.uid = uid",
|
|
] {
|
|
let app = format!(
|
|
"write(id: model.id, uid: Uuid) (value: model.id) {{ {body}\nvalue = row.id }}"
|
|
);
|
|
let error = packages(&[
|
|
("dever.database", ERROR),
|
|
("demo.account.model", "type Account { uid: Uuid generated }"),
|
|
("demo.account.app", &app),
|
|
])
|
|
.unwrap_err();
|
|
assert!(matches!(error.code, "C014" | "C005"), "{body}: {error:?}");
|
|
assert!(error.message.contains("read-only"), "{error:?}");
|
|
}
|
|
}
|