plum
git clone https://git.pyrossh.dev/plum
A statically typed, imperative programming language inspired by rust, python
plum-checker/tests/examples_test.rs
| 3d6f280 | 1 | #![allow(non_snake_case)] |
| 3d6f280 | 2 | use plum_checker::checkSource; |
| 0e1801a | 3 | use plum_core::AstParser; |
| 0e1801a | 4 | |
| 3d6f280 | 5 | fn examplesDir() -> std::path::PathBuf { |
| 0e1801a | 6 | std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../examples") |
| 0e1801a | 7 | } |
| 0e1801a | 8 | |
| 3d6f280 | 9 | fn exampleFiles() -> Vec<std::path::PathBuf> { |
| 3d6f280 | 10 | let mut files: Vec<_> = std::fs::read_dir(examplesDir()) |
| 0e1801a | 11 | .expect("examples/ directory should exist") |
| 0e1801a | 12 | .filter_map(|e| e.ok()) |
| 0e1801a | 13 | .map(|e| e.path()) |
| 0e1801a | 14 | .filter(|p| p.extension().and_then(|e| e.to_str()) == Some("plum")) |
| 0e1801a | 15 | .collect(); |
| 0e1801a | 16 | files.sort(); |
| 0e1801a | 17 | assert!(!files.is_empty(), "examples/ should contain at least one .plum file"); |
| 0e1801a | 18 | files |
| 0e1801a | 19 | } |
| 0e1801a | 20 | |
| 3d6f280 | 21 | /// Every example must parse with zero ERROR/MISSING nodes and pass `checkSource`. |
| 0e1801a | 22 | /// These files exist specifically to prove each piece of the currently-supported |
| 0e1801a | 23 | /// grammar surface actually works end to end, not just in isolated unit tests. |
| 0e1801a | 24 | #[test] |
| 3d6f280 | 25 | fn everyExampleParsesAndTypeChecks() { |
| 0e1801a | 26 | let mut parser = tree_sitter::Parser::new(); |
| 0e1801a | 27 | parser.set_language(&tree_sitter_plum::LANGUAGE.into()).unwrap(); |
| 0e1801a | 28 | |
| 3d6f280 | 29 | for path in exampleFiles() { |
| 0e1801a | 30 | let src = std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read {}: {}", path.display(), e)); |
| 0e1801a | 31 | let tree = parser.parse(&src, None).unwrap_or_else(|| panic!("failed to parse {}", path.display())); |
| 0e1801a | 32 | assert!( |
| 0e1801a | 33 | !tree.root_node().has_error(), |
| 0e1801a | 34 | "{} has a parse error:\n{}", |
| 0e1801a | 35 | path.display(), |
| 0e1801a | 36 | tree.root_node().to_sexp() |
| 0e1801a | 37 | ); |
| 0e1801a | 38 | |
| 0e1801a | 39 | let ap = AstParser::new(&src); |
| 3d6f280 | 40 | let source = ap.parseSource(tree.root_node()); |
| 3d6f280 | 41 | let result = checkSource(&source); |
| 0e1801a | 42 | assert!( |
| 0e1801a | 43 | result.is_ok(), |
| 0e1801a | 44 | "{} failed type checking: {:?}", |
| 0e1801a | 45 | path.display(), |
| 0e1801a | 46 | result.err().map(|errs| errs.into_iter().map(|e| e.message).collect::<Vec<_>>()) |
| 0e1801a | 47 | ); |
| 0e1801a | 48 | } |
| 0e1801a | 49 | } |