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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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() {
        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() {
        let messages = messages();
        assert!(messages.len() > 0);

        for message in messages {
            for message_field in message.fields {
                assert_eq!(
                    message_field.message.camelcase_name,
                    message.camelcase_name,
                    "field {} of message {} refers to a different message ({})",
                    message_field.snakecase_name,
                    message.camelcase_name,
                    message_field.message.camelcase_name
                );
            }
        }
    }
}