build.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. use std::env;
  2. use std::fs::File;
  3. use std::io::Write;
  4. use std::path::Path;
  5. const TEST_PREFIX: &str = "
  6. #[cfg(test)]
  7. use pretty_assertions::assert_eq;
  8. use crate::{grammar,lexer};
  9. use std::collections::BTreeMap;
  10. use std::io::Write;
  11. // to let us use pretty_assertions with strings, we write a newtype
  12. // that delegates Debug to Display
  13. #[derive(PartialEq, Eq)]
  14. struct StringWrapper<'a> {
  15. wrapped: &'a str,
  16. }
  17. impl<'a> core::fmt::Debug for StringWrapper<'a> {
  18. fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
  19. core::fmt::Display::fmt(self.wrapped, f)
  20. }
  21. }
  22. fn assert_eq(x: &str, y: &str) {
  23. assert_eq!(StringWrapper {wrapped: x}, StringWrapper {wrapped: y});
  24. }
  25. fn get_expectations(contents: &str) -> BTreeMap<u64, String> {
  26. let map: BTreeMap<String, String> = serde_yaml::from_str(contents).unwrap();
  27. let mut result = BTreeMap::new();
  28. for (k, v) in map.into_iter() {
  29. result.insert(k.parse().unwrap(), v);
  30. }
  31. result
  32. }
  33. ";
  34. const TEST_TEMPLATE: &str = "
  35. #[test]
  36. fn test_%PREFIX%() {
  37. let state = crate::interp::State::new();
  38. let source = include_str!(\"%ROOT%/tests/%PREFIX%.matzo\");
  39. let lexer = lexer::tokens(source);
  40. let stmts = grammar::StmtsParser::new().parse(&mut state.get_ast().borrow_mut(), lexer);
  41. assert!(stmts.is_ok());
  42. let stmts = stmts.unwrap();
  43. if let Ok(expected) = std::fs::read_to_string(\"%ROOT%/tests/%PREFIX%.parsed\") {
  44. let mut buf = Vec::new();
  45. for s in stmts.iter() {
  46. writeln!(buf, \"{:?}\", s.show(&state.get_ast().borrow())).unwrap();
  47. }
  48. assert_eq(
  49. std::str::from_utf8(&buf).unwrap().trim(),
  50. expected.trim(),
  51. );
  52. }
  53. if let Ok(contents) = std::fs::read_to_string(\"%ROOT%/tests/%PREFIX%.output\") {
  54. let expectations = get_expectations(&contents);
  55. for (seed, expectation) in expectations {
  56. let st = crate::interp::State::new_from_seed(seed);
  57. let mut out = Vec::new();
  58. st.run_with_writer(source, &mut out).unwrap();
  59. assert_eq(
  60. std::str::from_utf8(&out).unwrap().trim(),
  61. expectation.trim(),
  62. );
  63. }
  64. }
  65. }
  66. ";
  67. fn main() -> Result<(), Box<dyn std::error::Error>> {
  68. lalrpop::process_root()?;
  69. for file in ["build.rs", "src/grammar.lalrpop"] {
  70. println!("cargo:rerun-if-changed={}", file);
  71. }
  72. vergen::vergen(vergen::Config::default())?;
  73. let out_dir = env::var("OUT_DIR")?;
  74. let manifest_dir = env::var("CARGO_MANIFEST_DIR")?;
  75. let dest = Path::new(&out_dir).join("exp_tests.rs");
  76. let mut test_file = File::create(&dest)?;
  77. writeln!(test_file, "{}", TEST_PREFIX)?;
  78. for exp in std::fs::read_dir("tests")? {
  79. let exp = exp?.path().canonicalize()?;
  80. let fname = exp.file_name().ok_or("bad file name")?.to_string_lossy();
  81. if let Some(prefix) = fname.strip_suffix(".matzo") {
  82. let test = TEST_TEMPLATE
  83. .replace("%FILE%", &fname)
  84. .replace("%PREFIX%", prefix)
  85. .replace("%ROOT%", &manifest_dir);
  86. writeln!(test_file, "{}", test)?;
  87. }
  88. }
  89. Ok(())
  90. }