Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,116 @@
|
||||
use super::checked;
|
||||
|
||||
#[test]
|
||||
fn unconstrained_parameters_do_not_expand_clause_products() {
|
||||
let inputs = (0..40)
|
||||
.map(|position| format!("flag{position}: Bool"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
let body = (0..40)
|
||||
.map(|position| format!("flag{position}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" or ");
|
||||
let ordinary = format!("choose({inputs}) (answer: Bool) {{ answer = {body} }}\n");
|
||||
assert!(checked(&ordinary).is_ok());
|
||||
let clause = |pattern: &str| {
|
||||
format!("choose(test: {pattern}, {inputs}) (answer: Bool) {{ answer = {body} }}\n")
|
||||
};
|
||||
assert!(checked(&(clause("true") + &clause("false"))).is_ok());
|
||||
assert_eq!(checked(&clause("true")).unwrap_err().code, "C009");
|
||||
assert_eq!(
|
||||
checked(&(clause("Bool") + &clause("false")))
|
||||
.unwrap_err()
|
||||
.code,
|
||||
"C009"
|
||||
);
|
||||
assert!(checked("type State { One\n Two }\nvalue(input: State, optional: Bool?) (answer: Bool) { answer = optional == null }").is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn choice_coverage_and_payload_contracts() {
|
||||
let prefix = "type State { Idle\n Working(value: Int) }\n";
|
||||
let valid = "read(value: State.Idle) (answer: Int) { answer = 0 }\nread(value: State.Working(number)) (answer: Int) { answer = number }";
|
||||
assert!(checked(&(prefix.to_owned() + valid)).is_ok());
|
||||
for (body, code) in [
|
||||
(
|
||||
"read(value: State.Idle) (answer: Int) { answer = 0 }",
|
||||
"C009",
|
||||
),
|
||||
(
|
||||
"read(value: State) (answer: Int) { answer = 0 }\nread(value: State.Idle) (answer: Int) { answer = 1 }",
|
||||
"C009",
|
||||
),
|
||||
(
|
||||
"read(value: State.Working) (answer: Int) { answer = 0 }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"read(value: State.Working(first, second)) (answer: Int) { answer = first }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"read(value: State.Working(value)) (answer: Int) { answer = 0 }",
|
||||
"C009",
|
||||
),
|
||||
(
|
||||
"main() (answer: State) { answer = State.Working() }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"main() (answer: State) { answer = State.Working(true) }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"read(value: State) (answer: Int) { answer = value.value }",
|
||||
"C005",
|
||||
),
|
||||
] {
|
||||
let error = checked(&(prefix.to_owned() + body)).unwrap_err();
|
||||
assert_eq!(error.code, code, "{body}: {error:?}");
|
||||
}
|
||||
let wildcard = "read(value: State.Working(_)) (answer: Int) { answer = 1 }\nread(value: other) (answer: Int) { answer = 0 }";
|
||||
assert!(checked(&(prefix.to_owned() + wildcard)).is_ok());
|
||||
assert_eq!(
|
||||
checked("type Cycle { Next(value: Cycle) }")
|
||||
.unwrap_err()
|
||||
.code,
|
||||
"C007"
|
||||
);
|
||||
assert_eq!(
|
||||
checked("type State { Item(value: Row) }\ntype Row { state: State }")
|
||||
.unwrap_err()
|
||||
.code,
|
||||
"C007"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nullable_domains_and_complements_are_order_independent() {
|
||||
for clauses in [
|
||||
"read(value: Text) (answer: Int) { answer = length(value) }\nread(value: null) (answer: Int) { answer = -1 }",
|
||||
"read(value: null) (answer: Int) { answer = -1 }\nread(value: Text) (answer: Int) { answer = length(value) }",
|
||||
"read(value: other) (answer: Int) { answer = length(value) }\nread(value: null) (answer: Int) { answer = -1 }\nread(value: \"x\") (answer: Int) { answer = 1 }",
|
||||
] {
|
||||
assert!(checked(clauses).is_ok(), "{clauses}");
|
||||
}
|
||||
for clauses in [
|
||||
"read(value: Text?) (answer: Int) { answer = 0 }\nread(value: null) (answer: Int) { answer = 1 }",
|
||||
"read(value: \"x\") (answer: Int) { answer = 0 }\nread(value: null) (answer: Int) { answer = 1 }",
|
||||
] {
|
||||
assert_eq!(checked(clauses).unwrap_err().code, "C009");
|
||||
}
|
||||
assert!(checked("equal(value: Int?) (answer: Bool) { answer = value == null or null == value or value == 1 or 1 == value }").is_ok());
|
||||
assert!(checked("number() (answer: Decimal?) { answer = 1 }").is_ok());
|
||||
assert!(checked("number() (answer: Float?) { answer = 1.5 + 2.5 }").is_ok());
|
||||
assert!(checked("values() (answer: List<Int>?) { answer = [] }").is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn payload_bindings_do_not_shadow_inputs_or_outputs() {
|
||||
for binding in ["value", "answer"] {
|
||||
let text = format!(
|
||||
"type State {{ Item(number: Int) }}\nread(value: State.Item({binding})) (answer: Int) {{ answer = 1 }}"
|
||||
);
|
||||
assert_eq!(checked(&text).unwrap_err().code, "C002");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user