Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,112 @@
|
||||
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:?}");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user