/ compiler / parser / src / test.rs
test.rs
  1  // Copyright (C) 2019-2025 ADnet Contributors
  2  // This file is part of the ADL library.
  3  
  4  // The ADL library is free software: you can redistribute it and/or modify
  5  // it under the terms of the GNU General Public License as published by
  6  // the Free Software Foundation, either version 3 of the License, or
  7  // (at your option) any later version.
  8  
  9  // The ADL library is distributed in the hope that it will be useful,
 10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 12  // GNU General Public License for more details.
 13  
 14  // You should have received a copy of the GNU General Public License
 15  // along with the ADL library. If not, see <https://www.gnu.org/licenses/>.
 16  
 17  use adl_ast::{NetworkName, NodeBuilder};
 18  use adl_errors::{AdlError, BufferEmitter, Handler};
 19  use adl_span::{Symbol, create_session_if_not_set_then, source_map::FileName, with_session_globals};
 20  
 21  use serde::Serialize;
 22  use serial_test::serial;
 23  use std::fmt::Write as _;
 24  
 25  fn run_parse_many_test<T: Serialize>(
 26      test: &str,
 27      handler: &Handler,
 28      test_index: usize,
 29      parse: fn(Handler, &NodeBuilder, &str, u32) -> Result<T, AdlError>,
 30  ) -> Result<String, ()> {
 31      let source_map =
 32          with_session_globals(|s| s.source_map.new_source(test, FileName::Custom(format!("test_{test_index}"))));
 33      let result = parse(handler.clone(), &Default::default(), &source_map.src, source_map.absolute_start);
 34      let serializable = handler.extend_if_error(result)?;
 35      let value = serde_json::to_value(&serializable).expect("Serialization failure");
 36      let mut s = serde_json::to_string_pretty(&value).expect("string conversion failure");
 37      s.push('\n');
 38      Ok(s)
 39  }
 40  
 41  fn runner_parse_many_test<'a, T: Serialize>(
 42      tests: impl Iterator<Item = &'a str>,
 43      parse: fn(Handler, &NodeBuilder, &str, u32) -> Result<T, AdlError>,
 44  ) -> String {
 45      create_session_if_not_set_then(|_| {
 46          let mut output = String::new();
 47          let buf = BufferEmitter::new();
 48          let handler = Handler::new(buf.clone());
 49  
 50          for (i, test) in tests.enumerate() {
 51              match run_parse_many_test(test, &handler, i, parse) {
 52                  Ok(s) => writeln!(output, "{s}").unwrap(),
 53                  Err(()) => write!(output, "{}{}", buf.extract_errs(), buf.extract_warnings()).unwrap(),
 54              }
 55          }
 56  
 57          output
 58      })
 59  }
 60  
 61  #[test]
 62  #[serial]
 63  fn parse_module_tests() {
 64      adl_test_framework::run_tests("parser-module", runner_module_test);
 65  }
 66  
 67  // Parse module tests.
 68  
 69  fn runner_module_test(test: &str) -> String {
 70      let test_cases: Vec<String> = test
 71          .lines()
 72          .map(str::trim)
 73          .collect::<Vec<_>>()
 74          .split(|line| line.is_empty())
 75          .map(|paragraph| paragraph.join("\n"))
 76          .filter(|s| !s.trim().is_empty())
 77          .collect();
 78  
 79      runner_parse_many_test(test_cases.iter().map(|s| s.as_str()), |handler, node_builder, source, start_pos| {
 80          crate::parse_module(
 81              handler,
 82              node_builder,
 83              source,
 84              start_pos,
 85              Symbol::intern("module_test"),
 86              Vec::new(),
 87              NetworkName::AlphaTestnetV0,
 88          )
 89      })
 90  }
 91  
 92  // Parse expression tests.
 93  
 94  fn runner_expression_test(test: &str) -> String {
 95      let tests = test.lines().map(|line| line.trim()).filter(|line| !line.is_empty());
 96  
 97      runner_parse_many_test(tests, |handler, node_builder, source, start_pos| {
 98          crate::parse_expression(handler, node_builder, source, start_pos, NetworkName::AlphaTestnetV0)
 99      })
100  }
101  
102  #[test]
103  #[serial]
104  fn parse_expression_tests() {
105      adl_test_framework::run_tests("parser-expression", runner_expression_test);
106  }
107  
108  // Parse statement tests.
109  
110  fn runner_statement_test(test: &str) -> String {
111      let tests = test.split("\n\n").map(|text| text.trim()).filter(|text| !text.is_empty());
112  
113      runner_parse_many_test(tests, |handler, node_builder, source, start_pos| {
114          crate::parse_statement(handler, node_builder, source, start_pos, NetworkName::AlphaTestnetV0)
115      })
116  }
117  
118  #[test]
119  #[serial]
120  fn parse_statement_tests() {
121      adl_test_framework::run_tests("parser-statement", runner_statement_test);
122  }
123  
124  // Full parser tests.
125  
126  fn run_parser_test(test: &str, handler: &Handler) -> Result<String, ()> {
127      let source_file = with_session_globals(|s| s.source_map.new_source(test, FileName::Custom("test".into())));
128      let result =
129          crate::parse_ast(handler.clone(), &Default::default(), &source_file, &Vec::new(), NetworkName::AlphaTestnetV0);
130      let ast = handler.extend_if_error(result)?;
131      let value = serde_json::to_value(&ast.ast).expect("Serialization failure");
132      let mut s = serde_json::to_string_pretty(&value).expect("string conversion failure");
133      s.push('\n');
134      Ok(s)
135  }
136  
137  fn runner_parser_test(test: &str) -> String {
138      create_session_if_not_set_then(|_| {
139          let buf = BufferEmitter::new();
140          let handler = Handler::new(buf.clone());
141  
142          match run_parser_test(test, &handler) {
143              Ok(x) => x,
144              Err(()) => format!("{}{}", buf.extract_errs(), buf.extract_warnings()),
145          }
146      })
147  }
148  
149  #[test]
150  #[serial]
151  fn parser_tests() {
152      adl_test_framework::run_tests("parser", runner_parser_test);
153  }