windjammer 0.48.0

A simple language inspired by Go, Ruby, and Elixir that transpiles to Rust - 80% of Rust's power with 20% of the complexity
Documentation
#![cfg(any(
    not(any(
        feature = "parser_tests",
        feature = "analyzer_tests",
        feature = "codegen_tests",
        feature = "interpreter_tests",
        feature = "conformance_tests",
        feature = "integration_tests",
    )),
    feature = "analyzer_tests",
))]

// TDD Test: Type Alias Support
// Test that Windjammer can parse and generate type aliases

use std::env;
use std::fs;
use std::path::PathBuf;

#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_simple_type_alias() {
    let _tmp = tempfile::tempdir().unwrap();
    let test_dir = _tmp.path().join(format!(
        "wj_type_alias_{}_{}",
        std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_nanos(),
        std::process::id()
    ));

    fs::create_dir_all(&test_dir).unwrap();

    let source = r#"
pub type UserId = u32

pub fn get_user() -> UserId {
    42
}

fn main() {
    let id: UserId = get_user()
    println!("{}", id)
}
"#;

    fs::write(test_dir.join("main.wj"), source).unwrap();

    let wj_binary = PathBuf::from(env!("CARGO_BIN_EXE_wj"));
    let output = std::process::Command::new(&wj_binary)
        .arg("build")
        .arg("--no-cargo")
        .arg(test_dir.join("main.wj"))
        .arg("--output")
        .arg(test_dir.join("output"))
        .arg("--target")
        .arg("rust")
        .output()
        .expect("Failed to run wj command");

    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        panic!("Compilation failed:\n{}", stderr);
    }

    let result = fs::read_to_string(test_dir.join("output/main.rs"))
        .expect("Failed to read generated Rust file");

    // Should generate "pub type UserId = u32;"
    assert!(
        result.contains("type UserId"),
        "Expected 'type UserId' in generated code, got: {}",
        result
    );
    assert!(
        result.contains("u32"),
        "Expected 'u32' in type alias, got: {}",
        result
    );
}

#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_string_type_alias() {
    let _tmp2 = tempfile::tempdir().unwrap();
    let test_dir = _tmp2.path().join(format!(
        "wj_type_alias_string_{}_{}",
        std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_nanos(),
        std::process::id()
    ));

    fs::create_dir_all(&test_dir).unwrap();

    let source = r#"
pub type QuestId = string

pub fn create_quest(id: QuestId) -> QuestId {
    id
}

fn main() {
    let quest: QuestId = "rescue_silas".to_string()
    println!("{}", create_quest(quest))
}
"#;

    fs::write(test_dir.join("main.wj"), source).unwrap();

    let wj_binary = PathBuf::from(env!("CARGO_BIN_EXE_wj"));
    let output = std::process::Command::new(&wj_binary)
        .arg("build")
        .arg("--no-cargo")
        .arg(test_dir.join("main.wj"))
        .arg("--output")
        .arg(test_dir.join("output"))
        .arg("--target")
        .arg("rust")
        .output()
        .expect("Failed to run wj command");

    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        panic!("Compilation failed:\n{}", stderr);
    }

    let result = fs::read_to_string(test_dir.join("output/main.rs"))
        .expect("Failed to read generated Rust file");

    // Should generate "pub type QuestId = String;"
    assert!(
        result.contains("type QuestId"),
        "Expected 'type QuestId' in generated code, got: {}",
        result
    );
    assert!(
        result.contains("String"),
        "Expected 'String' in type alias, got: {}",
        result
    );
}