scryer-engine 0.2.1

Tree-sitter and stack-graphs AST indexing engine for Scryer code intelligence
use std::path::Path;

use scryer_engine::parsers::{ParseMode, PythonAstParser, RustAstParser, TypeScriptAstParser};

#[test]
fn test_rust_broken_syntax_resilience() {
    let corrupted_rust = r#"
/// First undamaged function.
pub fn valid_entry_point() -> u64 {
    42
}

// Deliberately corrupted function with unclosed delimiters and incomplete statements
pub fn broken_fn(a: u32) {
    let x = [1, 2, 3;
    unclosed_tokens(
}

/// Undamaged struct definition.
pub struct ValidModel {
    pub id: u64,
    pub name: String,
}

// Incomplete struct declaration
pub struct IncompleteStruct {
    pub x:
}

// Function with invalid tokens
pub fn broken_tokens() {
    @@@ $$$ %%% invalid token chaos;
}

/// Second undamaged function following syntax corruption.
pub fn valid_recovery_point() -> &'static str {
    "recovered"
}
"#;

    let payload = RustAstParser::parse(
        Path::new("src/broken.rs"),
        corrupted_rust.as_bytes(),
        "hash_broken_rs",
        ParseMode::Workspace,
    )
    .expect("Tree-sitter parser must not crash on malformed syntax");

    assert_eq!(payload.language, "rust");

    // Assert undamaged symbols are cleanly extracted despite syntactic corruption
    let entry_fn = payload
        .symbols
        .iter()
        .find(|s| s.name == "valid_entry_point")
        .expect("valid_entry_point should be extracted despite errors");
    assert_eq!(entry_fn.kind, "fn");
    assert_eq!(entry_fn.visibility, "public");

    let model_struct = payload
        .symbols
        .iter()
        .find(|s| s.name == "ValidModel")
        .expect("ValidModel struct should be extracted despite syntax errors");
    assert_eq!(model_struct.kind, "struct");
    assert_eq!(model_struct.visibility, "public");

    let recovery_fn = payload
        .symbols
        .iter()
        .find(|s| s.name == "valid_recovery_point")
        .expect("valid_recovery_point should be extracted despite prior syntax errors");
    assert_eq!(recovery_fn.kind, "fn");
    assert_eq!(recovery_fn.visibility, "public");

    // Scopes should also contain recovered blocks
    assert!(!payload.scopes.is_empty());
}

#[test]
fn test_python_broken_syntax_resilience() {
    let corrupted_python = r#"
def valid_py_start():
    """Initial valid function."""
    return True

# Corrupted function with unclosed delimiter and incomplete expression
def broken_py_func(a, b):
    x = [1, 2, 3,
    y = (foo +

class ValidPyService:
    """Undamaged service class."""
    def run(self):
        return "running"

# Incomplete function definition
def incomplete_py():

def valid_py_end():
    """Final valid function."""
    pass
"#;

    let payload = PythonAstParser::parse(
        Path::new("pkg/broken.py"),
        corrupted_python.as_bytes(),
        "hash_broken_py",
    )
    .expect("Tree-sitter Python parser must not crash on malformed syntax");

    assert_eq!(payload.language, "python");

    let start_fn = payload
        .symbols
        .iter()
        .find(|s| s.name == "valid_py_start")
        .expect("valid_py_start should be extracted");
    assert_eq!(start_fn.kind, "fn");

    let service_cls = payload
        .symbols
        .iter()
        .find(|s| s.name == "ValidPyService")
        .expect("ValidPyService class should be extracted");
    assert_eq!(service_cls.kind, "class");

    let end_fn = payload
        .symbols
        .iter()
        .find(|s| s.name == "valid_py_end")
        .expect("valid_py_end should be extracted");
    assert_eq!(end_fn.kind, "fn");
}

#[test]
fn test_typescript_broken_syntax_resilience() {
    let corrupted_typescript = r#"
export interface ValidConfig {
    host: string;
    port: number;
}

// Deliberately corrupted declaration
export function brokenTs(arg: {
    const broken = (1 + ;

export class ValidWorker {
    public process(): boolean {
        return true;
    }
}

!!! @@@ invalid tokens in ts

export const validConstant = (): string => "ok";
"#;

    let payload = TypeScriptAstParser::parse(
        Path::new("src/broken.ts"),
        corrupted_typescript.as_bytes(),
        "hash_broken_ts",
    )
    .expect("Tree-sitter TypeScript parser must not crash on malformed syntax");

    assert_eq!(payload.language, "typescript");

    let config_iface = payload
        .symbols
        .iter()
        .find(|s| s.name == "ValidConfig")
        .expect("ValidConfig interface should be extracted");
    assert_eq!(config_iface.kind, "interface");

    let worker_cls = payload
        .symbols
        .iter()
        .find(|s| s.name == "ValidWorker")
        .expect("ValidWorker class should be extracted");
    assert_eq!(worker_cls.kind, "class");

    let const_fn = payload
        .symbols
        .iter()
        .find(|s| s.name == "validConstant")
        .expect("validConstant should be extracted");
    assert_eq!(const_fn.kind, "fn");
}