Skip to main content

alef_e2e/
lib.rs

1//! Fixture-driven e2e test generation for alef.
2//!
3//! This crate generates complete, runnable e2e test projects for all supported
4//! languages from JSON fixture files. Each project is self-contained with
5//! build files, test files, and local package references.
6
7pub mod codegen;
8pub mod config;
9pub mod escape;
10pub mod field_access;
11pub mod fixture;
12pub mod format;
13pub mod scaffold;
14pub mod validate;
15
16use alef_core::backend::GeneratedFile;
17use alef_core::config::AlefConfig;
18use alef_core::config::e2e::DependencyMode;
19use anyhow::{Context, Result};
20use config::E2eConfig;
21use fixture::{group_fixtures, load_fixtures};
22use std::path::Path;
23use tracing::info;
24
25/// Generate e2e test projects from fixtures.
26///
27/// Returns the list of generated files. The caller is responsible for writing
28/// them to disk.
29pub fn generate_e2e(
30    alef_config: &AlefConfig,
31    e2e_config: &E2eConfig,
32    languages: Option<&[String]>,
33) -> Result<Vec<GeneratedFile>> {
34    let fixtures_dir = Path::new(&e2e_config.fixtures);
35    let fixtures = load_fixtures(fixtures_dir)
36        .with_context(|| format!("failed to load fixtures from {}", fixtures_dir.display()))?;
37
38    info!("Loaded {} fixture(s) from {}", fixtures.len(), e2e_config.fixtures);
39
40    let all_groups = group_fixtures(&fixtures);
41
42    // In registry mode with a non-empty category filter, keep only the listed
43    // categories so the generated test apps contain a curated subset.
44    let groups: Vec<_> =
45        if e2e_config.dep_mode == DependencyMode::Registry && !e2e_config.registry.categories.is_empty() {
46            let allowed = &e2e_config.registry.categories;
47            all_groups
48                .into_iter()
49                .filter(|g| allowed.iter().any(|c| c == &g.category))
50                .collect()
51        } else {
52            all_groups
53        };
54
55    let generators = if let Some(langs) = languages {
56        codegen::generators_for(langs)
57    } else if !e2e_config.languages.is_empty() {
58        codegen::generators_for(&e2e_config.languages)
59    } else {
60        codegen::all_generators()
61    };
62
63    let mut all_files = Vec::new();
64    for generator in &generators {
65        let files = generator.generate(&groups, e2e_config, alef_config)?;
66        info!("  [{}] generated {} file(s)", generator.language_name(), files.len());
67        all_files.extend(files);
68    }
69
70    Ok(all_files)
71}