pub(super) fn render_gleam_toml(
pkg_path: &str,
pkg_name: &str,
dep_mode: crate::e2e::config::DependencyMode,
) -> String {
use crate::core::template_versions::hex;
let stdlib = hex::GLEAM_STDLIB_VERSION_RANGE;
let gleeunit = hex::GLEEUNIT_VERSION_RANGE;
let gleam_httpc = hex::GLEAM_HTTPC_VERSION_RANGE;
let envoy = hex::ENVOY_VERSION_RANGE;
let deps = match dep_mode {
crate::e2e::config::DependencyMode::Registry => {
format!(
r#"{pkg_name} = ">= 0.1.0"
gleam_stdlib = "{stdlib}"
gleeunit = "{gleeunit}"
gleam_httpc = "{gleam_httpc}"
gleam_http = ">= 4.0.0 and < 5.0.0"
envoy = "{envoy}""#
)
}
crate::e2e::config::DependencyMode::Local => {
format!(
r#"{pkg_name} = {{ path = "{pkg_path}" }}
gleam_stdlib = "{stdlib}"
gleeunit = "{gleeunit}"
gleam_httpc = "{gleam_httpc}"
gleam_http = ">= 4.0.0 and < 5.0.0"
envoy = "{envoy}""#
)
}
};
format!(
r#"name = "e2e_gleam"
version = "0.1.0"
target = "erlang"
[dependencies]
{deps}
"#
)
}
pub(super) fn render_e2e_helpers_source(app_name: &str) -> String {
format!(
"// Generated by alef. Do not edit by hand.\n\
// E2e helper module — provides file-reading utilities for Gleam tests.\n\
import gleam/dynamic\n\
\n\
/// Read a file into a BitArray via the Erlang :file module.\n\
/// The path is relative to the e2e working directory when `gleam test` runs.\n\
@external(erlang, \"file\", \"read_file\")\n\
pub fn read_file_bytes(path: String) -> Result(BitArray, dynamic.Dynamic)\n\
\n\
/// Ensure the {app_name} OTP application and all its dependencies are started.\n\
/// This is required when running `gleam test` outside of `mix test`, since the\n\
/// Rustler NIF init hook needs the :{app_name} application to be started before\n\
/// any binding-native functions can be called.\n\
/// Calls the Erlang shim e2e_startup:start_app/0.\n\
@external(erlang, \"e2e_startup\", \"start_app\")\n\
pub fn start_app() -> Nil\n",
)
}
pub(super) fn render_erlang_startup_source(app_name: &str) -> String {
format!(
"%% Generated by alef. Do not edit by hand.\n\
%% Starts the {app_name} OTP application and all its dependencies.\n\
%% Called by e2e_gleam_test.main/0 before gleeunit.main/0.\n\
-module(e2e_startup).\n\
-export([start_app/0]).\n\
\n\
start_app() ->\n\
\x20\x20\x20\x20%% Elixir runtime must be started before {app_name} NIF init\n\
\x20\x20\x20\x20%% because Rustler uses Elixir.Application.app_dir/2 to locate the .so.\n\
\x20\x20\x20\x20%% Gracefully fall back when Elixir is not a runtime dependency.\n\
\x20\x20\x20\x20case application:ensure_all_started(elixir) of\n\
\x20\x20\x20\x20\x20\x20\x20\x20{{ok, _}} -> ok;\n\
\x20\x20\x20\x20\x20\x20\x20\x20{{error, _}} -> ok\n\
\x20\x20\x20\x20end,\n\
\x20\x20\x20\x20{{ok, _}} = application:ensure_all_started({app_name}),\n\
\x20\x20\x20\x20nil.\n",
)
}