lingva 0.1.0

Standalone Lingva localization CLI
use std::{fs, process::Command};

fn lingva(root: &std::path::Path) -> Command {
    let mut command = Command::new(env!("CARGO_BIN_EXE_lingva"));
    command.current_dir(root);
    command
}

#[test]
fn help_exposes_the_portable_customer_surface() {
    let root = tempfile::tempdir().unwrap();
    let output = lingva(root.path()).arg("--help").output().unwrap();
    let stdout = String::from_utf8(output.stdout).unwrap();
    assert!(output.status.success());
    for command in ["auth", "init", "update", "sync", "check", "pull", "push"] {
        assert!(stdout.contains(command), "missing {command} from help");
    }
}

#[test]
fn local_init_and_sync_need_no_language_runtime() {
    let root = tempfile::tempdir().unwrap();
    let initialized = lingva(root.path())
        .args([
            "init",
            "--mode",
            "local",
            "--no-auth",
            "--sdk",
            "python",
            "--project-id",
            "demo",
            "--locale",
            "en,ru",
        ])
        .output()
        .unwrap();
    assert!(
        initialized.status.success(),
        "{}",
        String::from_utf8_lossy(&initialized.stderr)
    );
    let config = fs::read_to_string(root.path().join("lingva.config.yaml")).unwrap();
    assert!(config.contains("projectId: demo"));
    assert!(root.path().join(".lingva/translations/en.json").is_file());
    assert!(root.path().join(".lingva/translations/ru.json").is_file());

    fs::write(
        root.path().join(".lingva/translations/en.json"),
        "{\"welcome\":\"Hello\"}\n",
    )
    .unwrap();
    let drift = lingva(root.path()).arg("check").output().unwrap();
    assert!(!drift.status.success());
    assert!(
        String::from_utf8(drift.stdout)
            .unwrap()
            .contains("locale drift detected")
    );

    assert!(lingva(root.path()).arg("sync").status().unwrap().success());
    assert!(lingva(root.path()).arg("check").status().unwrap().success());
    let russian = fs::read_to_string(root.path().join(".lingva/translations/ru.json")).unwrap();
    assert!(russian.contains("\"welcome\": \"\""));
}

#[test]
fn react_init_generates_a_local_sdk_adapter_from_the_portable_engine() {
    let root = tempfile::tempdir().unwrap();
    let initialized = lingva(root.path())
        .args([
            "init",
            "--mode",
            "local",
            "--no-auth",
            "--sdk",
            "react",
            "--project-id",
            "demo",
            "--locale",
            "en,ru",
        ])
        .output()
        .unwrap();
    assert!(
        initialized.status.success(),
        "{}",
        String::from_utf8_lossy(&initialized.stderr)
    );

    let runtime_config = fs::read_to_string(root.path().join("lingva.config.ts")).unwrap();
    assert!(runtime_config.contains("generatedProjectFile: '.lingva/generated/project.ts'"));
    assert!(!runtime_config.contains("import project"));

    let provider = fs::read_to_string(root.path().join("src/lingva/provider.tsx")).unwrap();
    assert!(provider.contains("configureLingvaReact({"));
    assert!(provider.contains("...lingvaConfig"));
    assert!(provider.contains("project: lingvaProject"));

    let project = fs::read_to_string(root.path().join(".lingva/generated/project.ts")).unwrap();
    assert!(project.contains("createLingvaResources"));
    assert!(project.contains("projectId: \"demo\""));
}

#[test]
fn python_init_stays_runtime_agnostic() {
    let root = tempfile::tempdir().unwrap();
    assert!(
        lingva(root.path())
            .args([
                "init",
                "--mode",
                "local",
                "--no-auth",
                "--sdk",
                "python",
                "--project-id",
                "demo",
            ])
            .status()
            .unwrap()
            .success()
    );
    assert!(root.path().join("lingva.config.yaml").is_file());
    assert!(!root.path().join("lingva.config.ts").exists());
    assert!(!root.path().join(".lingva/generated/project.ts").exists());
}