conformance/
lib.rs

1#![allow(non_snake_case)]
2use std::{collections::HashSet, str::FromStr as _};
3
4use lang_turtle::lang::{
5    model::{Term, Triple, Turtle},
6    parse_source,
7    // parser2::parse_source as parse_source2,
8};
9
10fn check_turtle_defined_prefixes(turtle: Option<&Turtle>) -> bool {
11    // check defined prefixes
12    let mut prefixes = HashSet::new();
13    if let Some(turtle) = turtle {
14        for pref in &turtle.prefixes {
15            prefixes.insert(pref.value().prefix.value().to_string());
16        }
17
18        turtle.triples.iter().all(|t| check_triple(&t, &prefixes))
19    } else {
20        true
21    }
22}
23
24pub fn test_syntax(location: &str, is_positive: bool) {
25    let url = lsp_types::Url::from_str(location).unwrap();
26    let path = url.to_file_path().expect("file path");
27    let turtle_source = std::fs::read_to_string(&path).expect("Failed to turtle");
28    let (turtle, errors) = parse_source(&url, &turtle_source);
29    // let turtle2 = parse_source2(&url, &turtle_source);
30
31    let combinator = errors.is_empty() && turtle.is_some();
32    // let new = turtle2.is_some();
33    // assert!(turtle.is_some(), "Always return some turtle");
34    let defined_prefixes = check_turtle_defined_prefixes(turtle.as_ref());
35
36    // if combinator != new {
37    //     eprintln!(
38    //         "Expected new parser to be the same as the old one. Old {} New {}",
39    //         combinator, new
40    //     );
41    //
42    //     println!("Trutle\n{:?}", turtle2);
43    //     for e in &errors {
44    //         eprintln!("Error {:?}", e)
45    //     }
46    //
47    //     assert!(false, "Expected new parser to be the same as the old one");
48    // }
49    if is_positive {
50        if !combinator || !defined_prefixes {
51            eprintln!(
52                "Failed to parse turtle\n{}\n\nErrors {:?}",
53                turtle_source, errors
54            );
55            assert!(false, "Parsing failed, and shouldn't have failed");
56        }
57    } else {
58        if errors.is_empty() && turtle.is_some() && defined_prefixes {
59            eprintln!(
60                "Failed to succeeded but shouldn't have: turtle\n{}",
61                turtle_source
62            );
63
64            assert!(false, "Parsing succeeded, and should have failed");
65        }
66    }
67}
68
69fn check_triple(triple: &Triple, defined: &HashSet<String>) -> bool {
70    if !check_term(&triple.subject, &defined) {
71        return false;
72    }
73
74    for po in &triple.po {
75        if !check_term(&po.predicate, defined) {
76            return false;
77        }
78
79        if !po.object.iter().all(|t| check_term(t, defined)) {
80            return false;
81        }
82    }
83
84    true
85}
86
87fn check_term(term: &Term, defined: &HashSet<String>) -> bool {
88    match term {
89        Term::BlankNode(lang_turtle::lang::model::BlankNode::Unnamed(pos, _, _)) => {
90            for po in pos {
91                if !check_term(&po.predicate, defined) {
92                    return false;
93                }
94
95                if !po.object.iter().all(|t| check_term(t, defined)) {
96                    return false;
97                }
98            }
99            true
100        }
101        Term::NamedNode(lang_turtle::lang::model::NamedNode::Prefixed { prefix, .. }) => {
102            defined.contains(prefix)
103        }
104        Term::Collection(spanneds) => spanneds.iter().all(|t| check_term(t, defined)),
105        _ => true,
106    }
107}
108
109include!(concat!(env!("OUT_DIR"), "/generated_tests.rs"));