use cyrs_syntax::parse;
use proptest::prelude::*;
fn cypher_like() -> impl Strategy<Value = String> {
"[A-Z a-z0-9():,.\n;/*_$'\"\\[\\]{}|+-]{0,120}".prop_map(|s| s)
}
fn cypher_fragments() -> impl Strategy<Value = String> {
prop_oneof![
Just("MATCH (n) RETURN n".to_string()),
Just("MATCH (n:Person) RETURN n".to_string()),
Just("MATCH (n)-[r]->(m) RETURN n, r, m".to_string()),
Just("MATCH (n)-[r:KNOWS]->(m) RETURN n".to_string()),
Just("MATCH (n) WHERE n.age > 21 RETURN n".to_string()),
Just("MATCH (n) RETURN n.name, n.age".to_string()),
Just("MATCH (n) RETURN DISTINCT n".to_string()),
Just("MATCH (n) RETURN n ORDER BY n.name ASC".to_string()),
Just("MATCH (n) RETURN n SKIP 10 LIMIT 5".to_string()),
Just("UNWIND [1,2,3] AS x RETURN x".to_string()),
Just("MATCH (n) WITH n RETURN n".to_string()),
Just("// find nodes\nMATCH (n) RETURN n".to_string()),
Just("/* block */\nMATCH (n) RETURN n".to_string()),
Just("MATCH (n) /* inline */ RETURN n".to_string()),
Just("MATCH".to_string()),
Just("RETURN".to_string()),
Just("(".to_string()),
Just(")".to_string()),
Just("->".to_string()),
Just("MATCH (n) RETURN".to_string()),
Just(String::new()),
Just(" ".to_string()),
Just("\n\n".to_string()),
Just("MATCH (n) WHERE RETURN n".to_string()),
]
}
proptest! {
#![proptest_config(ProptestConfig {
cases: 1024,
..ProptestConfig::default()
})]
#[test]
fn totality_arbitrary(s in ".*") {
let p = parse(&s);
let text = p.syntax().to_string();
prop_assert_eq!(text, s);
}
#[test]
fn totality_cypher_like(s in cypher_like()) {
let p = parse(&s);
let text = p.syntax().to_string();
prop_assert_eq!(text, s);
}
#[test]
fn totality_fragments(s in cypher_fragments()) {
let p = parse(&s);
let text = p.syntax().to_string();
prop_assert_eq!(text, s);
}
}
proptest! {
#![proptest_config(ProptestConfig {
cases: 1024,
..ProptestConfig::default()
})]
#[test]
fn losslessness_arbitrary(s in ".*") {
let text = parse(&s).syntax().to_string();
prop_assert_eq!(text, s,
"CST losslessness violated: parse(s).syntax().to_string() != s");
}
#[test]
fn losslessness_cypher_like(s in cypher_like()) {
let text = parse(&s).syntax().to_string();
prop_assert_eq!(text, s,
"CST losslessness violated: parse(s).syntax().to_string() != s");
}
#[test]
fn losslessness_fragments(s in cypher_fragments()) {
let text = parse(&s).syntax().to_string();
prop_assert_eq!(text, s,
"CST losslessness violated: parse(s).syntax().to_string() != s");
}
}
#[test]
fn regression_empty_input() {
let s = "";
assert_eq!(parse(s).syntax().to_string(), s);
}
#[test]
fn regression_whitespace_only() {
let s = " \n\t ";
assert_eq!(parse(s).syntax().to_string(), s);
}
#[test]
fn regression_partial_keyword() {
let s = "MATC";
let _ = parse(s); assert_eq!(parse(s).syntax().to_string(), s);
}
#[test]
fn regression_unclosed_string() {
let s = r#"MATCH (n {name: "Alice}) RETURN n"#;
let _ = parse(s);
assert_eq!(parse(s).syntax().to_string(), s);
}