1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
pub mod comment;
pub mod helpers;
mod messages;
#[allow(non_upper_case_globals)]
mod messages_data;
mod nodes;
#[allow(non_upper_case_globals)]
mod nodes_data;
pub mod template;

pub use messages::*;
pub use nodes::*;

pub fn nodes() -> NodeList {
    nodes_data::ALL_NODES
}

pub fn messages() -> MessagesList {
    messages_data::ALL_MESSAGES
}

#[cfg(test)]
mod tests {
    use crate::NodeFieldType;

    use super::{messages, nodes};

    #[test]
    fn test_nodes() {
        let nodes = nodes();
        assert!(nodes.len() > 0);

        for node in nodes {
            for node_field in node.fields {
                assert_eq!(
                    node_field.node.camelcase_name, node.camelcase_name,
                    "field {} of node {} refers to a different node ({})",
                    node_field.snakecase_name, node.camelcase_name, node_field.node.camelcase_name
                );
            }
        }
    }

    #[test]
    fn test_nodes_order() {
        let nodes = nodes();

        let contents = std::fs::read_to_string("src/nodes_data.rs").unwrap();
        let mut node_decls = vec![];
        for line in contents.lines() {
            if line.starts_with("static") && line.ends_with(": Node = Node {") {
                let decl = line
                    .strip_prefix("static ")
                    .unwrap()
                    .strip_suffix(": Node = Node {")
                    .unwrap();
                node_decls.push(decl);
            }
        }
        for (left, right) in node_decls.iter().zip(node_decls.iter().skip(1)) {
            assert!(
                left.to_lowercase() < right.to_lowercase(),
                "node declarations are not sorted: {} goes before {}",
                left,
                right
            )
        }

        for (left, right) in nodes.iter().zip(nodes.iter().skip(1)) {
            let lhs = left.camelcase_name;
            let rhs = right.camelcase_name;
            assert!(
                lhs.to_lowercase() < rhs.to_lowercase(),
                "nodes are not sorted: {} goes before {}",
                lhs,
                rhs
            )
        }

        assert_eq!(node_decls.len(), nodes.len());

        for (node_decl, node) in node_decls.iter().zip(nodes.iter()) {
            assert_eq!(
                node_decl, &node.camelcase_name,
                "node declaration order doesn't match nodes order: {} / {}",
                node_decl, node.camelcase_name
            )
        }
    }

    #[test]
    fn test_node_fields_order() {
        let nodes = nodes();

        for node in nodes {
            assert!(
                node.fields
                    .iter()
                    .any(|f| f.snakecase_name == "expression_l"),
                "node {} doesn't have 'expression_l' field",
                node.camelcase_name
            );

            let mut found_loc = false;
            for node_field in node.fields {
                if node_field.field_type == NodeFieldType::Loc
                    || node_field.field_type == NodeFieldType::MaybeLoc
                {
                    found_loc = true;
                } else if found_loc {
                    panic!(
                        "Fields of node {} are not sorted: {} goes after *_l fields",
                        node.camelcase_name, node_field.snakecase_name
                    )
                }
            }
        }
    }

    #[test]
    fn test_messages() {
        assert!(messages().len() > 0)
    }
}