feat: add integration tests and lint script for examples

- Add 30 integration tests that verify all examples and projects
  parse and type-check correctly
- Add scripts/lint-examples.sh for quick pre-commit validation
- Tests will catch regressions like missing `run ... with {}` syntax
  or broken escape sequences

Run with: cargo test example_tests
Or quick check: ./scripts/lint-examples.sh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 23:35:22 -05:00
parent f5fe7d5335
commit 6ace4dea01
2 changed files with 244 additions and 0 deletions

View File

@@ -2814,4 +2814,177 @@ c")"#;
assert_eq!(eval(source).unwrap(), "42");
}
}
// Integration tests for example files
mod example_tests {
use super::*;
use std::fs;
use std::path::Path;
fn check_file(path: &str) -> Result<(), String> {
let source = fs::read_to_string(path)
.map_err(|e| format!("Failed to read {}: {}", path, e))?;
let program = Parser::parse_source(&source)
.map_err(|e| format!("Parse error in {}: {}", path, e))?;
let mut checker = TypeChecker::new();
checker.check_program(&program).map_err(|errors| {
format!("Type errors in {}:\n{}", path,
errors.iter().map(|e| e.to_string()).collect::<Vec<_>>().join("\n"))
})?;
Ok(())
}
#[test]
fn test_example_hello() {
check_file("examples/hello.lux").unwrap();
}
#[test]
fn test_example_factorial() {
check_file("examples/factorial.lux").unwrap();
}
#[test]
fn test_example_functional() {
check_file("examples/functional.lux").unwrap();
}
#[test]
fn test_example_pipelines() {
check_file("examples/pipelines.lux").unwrap();
}
#[test]
fn test_example_tailcall() {
check_file("examples/tailcall.lux").unwrap();
}
#[test]
fn test_example_effects() {
check_file("examples/effects.lux").unwrap();
}
#[test]
fn test_example_handlers() {
check_file("examples/handlers.lux").unwrap();
}
#[test]
fn test_example_builtin_effects() {
check_file("examples/builtin_effects.lux").unwrap();
}
#[test]
fn test_example_datatypes() {
check_file("examples/datatypes.lux").unwrap();
}
#[test]
fn test_example_generics() {
check_file("examples/generics.lux").unwrap();
}
#[test]
fn test_example_traits() {
check_file("examples/traits.lux").unwrap();
}
#[test]
fn test_example_interpolation() {
check_file("examples/interpolation.lux").unwrap();
}
#[test]
fn test_example_behavioral() {
check_file("examples/behavioral.lux").unwrap();
}
#[test]
fn test_example_behavioral_types() {
check_file("examples/behavioral_types.lux").unwrap();
}
#[test]
fn test_example_versioning() {
check_file("examples/versioning.lux").unwrap();
}
#[test]
fn test_example_schema_evolution() {
check_file("examples/schema_evolution.lux").unwrap();
}
#[test]
fn test_example_file_io() {
check_file("examples/file_io.lux").unwrap();
}
#[test]
fn test_example_json() {
check_file("examples/json.lux").unwrap();
}
#[test]
fn test_example_random() {
check_file("examples/random.lux").unwrap();
}
#[test]
fn test_example_statemachine() {
check_file("examples/statemachine.lux").unwrap();
}
#[test]
fn test_example_shell() {
check_file("examples/shell.lux").unwrap();
}
#[test]
fn test_example_http() {
check_file("examples/http.lux").unwrap();
}
#[test]
fn test_example_http_server() {
check_file("examples/http_server.lux").unwrap();
}
#[test]
fn test_example_jit_test() {
check_file("examples/jit_test.lux").unwrap();
}
#[test]
fn test_project_json_parser() {
check_file("projects/json-parser/main.lux").unwrap();
}
#[test]
fn test_project_markdown_converter() {
check_file("projects/markdown-converter/main.lux").unwrap();
}
#[test]
fn test_project_todo_app() {
check_file("projects/todo-app/main.lux").unwrap();
}
#[test]
fn test_project_mini_interpreter() {
check_file("projects/mini-interpreter/main.lux").unwrap();
}
#[test]
fn test_project_guessing_game() {
check_file("projects/guessing-game/main.lux").unwrap();
}
#[test]
fn test_project_rest_api() {
check_file("projects/rest-api/main.lux").unwrap();
}
}
}