1use crate::config::E2eConfig;
4use alef_core::config::AlefConfig;
5use anyhow::{Context, Result};
6use std::path::Path;
7
8static FIXTURE_SCHEMA: &str = include_str!("../schema/fixture.schema.json");
9
10pub fn init_fixtures(e2e_config: &E2eConfig, _alef_config: &AlefConfig) -> Result<Vec<String>> {
13 let fixtures_dir = Path::new(&e2e_config.fixtures);
14 let mut created = Vec::new();
15
16 if !fixtures_dir.exists() {
18 std::fs::create_dir_all(fixtures_dir)
19 .with_context(|| format!("failed to create fixtures dir: {}", fixtures_dir.display()))?;
20 created.push(fixtures_dir.display().to_string());
21 }
22
23 let schema_path = fixtures_dir.join("schema.json");
25 std::fs::write(&schema_path, FIXTURE_SCHEMA)
26 .with_context(|| format!("failed to write {}", schema_path.display()))?;
27 created.push(schema_path.display().to_string());
28
29 let smoke_dir = fixtures_dir.join("smoke");
31 if !smoke_dir.exists() {
32 std::fs::create_dir_all(&smoke_dir)
33 .with_context(|| format!("failed to create smoke dir: {}", smoke_dir.display()))?;
34 created.push(smoke_dir.display().to_string());
35 }
36
37 let basic_path = smoke_dir.join("basic.json");
39 let basic_fixture = build_example_fixture(e2e_config);
40 std::fs::write(&basic_path, basic_fixture).with_context(|| format!("failed to write {}", basic_path.display()))?;
41 created.push(basic_path.display().to_string());
42
43 Ok(created)
44}
45
46pub fn scaffold_fixture(
49 e2e_config: &E2eConfig,
50 _alef_config: &AlefConfig,
51 id: &str,
52 category: &str,
53 description: &str,
54) -> Result<String> {
55 let fixtures_dir = Path::new(&e2e_config.fixtures);
56 let category_dir = fixtures_dir.join(category);
57
58 if !category_dir.exists() {
60 std::fs::create_dir_all(&category_dir)
61 .with_context(|| format!("failed to create category dir: {}", category_dir.display()))?;
62 }
63
64 let fixture_path = category_dir.join(format!("{id}.json"));
66 let fixture = build_scaffold_fixture(e2e_config, id, description);
67 std::fs::write(&fixture_path, fixture).with_context(|| format!("failed to write {}", fixture_path.display()))?;
68
69 Ok(fixture_path.display().to_string())
70}
71
72fn build_example_fixture(e2e_config: &E2eConfig) -> String {
74 let mut input_fields = Vec::new();
75 for arg in &e2e_config.call.args {
76 let value = example_value_for_type(&arg.arg_type);
77 input_fields.push(format!(" \"{}\": {value}", arg.field));
78 }
79
80 let input_block = if input_fields.is_empty() {
81 "{}".to_string()
82 } else {
83 format!("{{\n{}\n }}", input_fields.join(",\n"))
84 };
85
86 let first_field = e2e_config
88 .call
89 .args
90 .first()
91 .map(|a| a.field.as_str())
92 .unwrap_or("result");
93
94 format!(
95 r#"{{
96 "id": "basic_smoke",
97 "description": "Basic smoke test verifying the function returns without error",
98 "input": {input_block},
99 "assertions": [
100 {{ "type": "not_error" }},
101 {{ "type": "not_empty", "field": "{first_field}" }}
102 ]
103}}
104"#
105 )
106}
107
108fn build_scaffold_fixture(e2e_config: &E2eConfig, id: &str, description: &str) -> String {
110 let mut input_fields = Vec::new();
111 for arg in &e2e_config.call.args {
112 let value = empty_value_for_type(&arg.arg_type);
113 input_fields.push(format!(" \"{}\": {value}", arg.field));
114 }
115
116 let input_block = if input_fields.is_empty() {
117 "{}".to_string()
118 } else {
119 format!("{{\n{}\n }}", input_fields.join(",\n"))
120 };
121
122 format!(
123 r#"{{
124 "id": "{id}",
125 "description": "{description}",
126 "input": {input_block},
127 "assertions": [
128 {{ "type": "not_error" }}
129 ]
130}}
131"#
132 )
133}
134
135fn example_value_for_type(arg_type: &str) -> &'static str {
137 match arg_type {
138 "string" => "\"example\"",
139 "int" | "integer" => "0",
140 "float" | "number" => "0.0",
141 "bool" | "boolean" => "true",
142 "json_object" => "{}",
143 "bytes" => "\"\"",
144 _ => "\"\"",
145 }
146}
147
148fn empty_value_for_type(arg_type: &str) -> &'static str {
150 match arg_type {
151 "string" => "\"\"",
152 "int" | "integer" => "0",
153 "float" | "number" => "0.0",
154 "bool" | "boolean" => "false",
155 "json_object" => "{}",
156 "bytes" => "\"\"",
157 _ => "\"\"",
158 }
159}