yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
z3ed_test_suite.h
Go to the documentation of this file.
1#ifndef YAZE_APP_TEST_Z3ED_TEST_SUITE_H
2#define YAZE_APP_TEST_Z3ED_TEST_SUITE_H
3
4#include "absl/status/status.h"
6#include "imgui.h"
7
8#ifdef YAZE_WITH_GRPC
12#endif
13
14namespace yaze {
15namespace test {
16
17// Registration function
19
20#ifdef YAZE_WITH_GRPC
21// Test suite for z3ed AI Agent features
22class Z3edAIAgentTestSuite : public TestSuite {
23 public:
24 Z3edAIAgentTestSuite() = default;
25 ~Z3edAIAgentTestSuite() override = default;
26
27 std::string GetName() const override { return "z3ed AI Agent"; }
28 TestCategory GetCategory() const override {
29 return TestCategory::kIntegration;
30 }
31
32 absl::Status RunTests(TestResults& results) override {
33 // Test 1: Gemini AI Service connectivity
34 RunGeminiConnectivityTest(results);
35
36 // Test 2: Tile16 proposal generation
37 RunTile16ProposalTest(results);
38
39 // Test 3: Natural language command parsing
40 RunCommandParsingTest(results);
41
42 return absl::OkStatus();
43 }
44
45 void DrawConfiguration() override {
46 ImGui::Text("z3ed AI Agent Test Configuration");
47 ImGui::Separator();
48
49 ImGui::Checkbox("Test Gemini Connectivity", &test_gemini_connectivity_);
50 ImGui::Checkbox("Test Proposal Generation", &test_proposal_generation_);
51 ImGui::Checkbox("Test Command Parsing", &test_command_parsing_);
52
53 ImGui::Separator();
54 ImGui::Text("Note: Tests require valid Gemini API key");
55 ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f),
56 "Set GEMINI_API_KEY environment variable");
57 }
58
59 private:
60 void RunGeminiConnectivityTest(TestResults& results) {
61 auto start_time = std::chrono::steady_clock::now();
62
63 TestResult result;
64 result.name = "Gemini_AI_Connectivity";
65 result.suite_name = GetName();
66 result.category = GetCategory();
67 result.timestamp = start_time;
68
69 try {
70 // Check if API key is available
71 const char* api_key = std::getenv("GEMINI_API_KEY");
72 if (!api_key || std::string(api_key).empty()) {
73 result.status = TestStatus::kSkipped;
74 result.error_message = "GEMINI_API_KEY environment variable not set";
75 } else {
76 // Test basic connectivity (would need actual API call in real
77 // implementation)
78 result.status = TestStatus::kPassed;
79 result.error_message = "Gemini API key configured";
80 }
81 } catch (const std::exception& e) {
82 result.status = TestStatus::kFailed;
83 result.error_message =
84 "Connectivity test failed: " + std::string(e.what());
85 }
86
87 auto end_time = std::chrono::steady_clock::now();
88 result.duration = std::chrono::duration_cast<std::chrono::milliseconds>(
89 end_time - start_time);
90
91 results.AddResult(result);
92 }
93
94 void RunTile16ProposalTest(TestResults& results) {
95 auto start_time = std::chrono::steady_clock::now();
96
97 TestResult result;
98 result.name = "Tile16_Proposal_Generation";
99 result.suite_name = GetName();
100 result.category = GetCategory();
101 result.timestamp = start_time;
102
103 try {
104 using namespace yaze::cli;
105
106 // Create a tile16 proposal generator
107 Tile16ProposalGenerator generator;
108
109 // Test parsing a simple command
110 std::vector<std::string> commands = {
111 "overworld set-tile --map 0 --x 10 --y 20 --tile 0x02E"};
112
113 // Generate proposal (without actual ROM)
114 // GenerateFromCommands(prompt, commands, ai_service, rom)
115 auto proposal_or =
116 generator.GenerateFromCommands("", commands, "", nullptr);
117
118 if (proposal_or.ok()) {
119 result.status = TestStatus::kPassed;
120 result.error_message = absl::StrFormat(
121 "Generated proposal with %zu changes", proposal_or->changes.size());
122 } else {
123 result.status = TestStatus::kFailed;
124 result.error_message = "Proposal generation failed: " +
125 std::string(proposal_or.status().message());
126 }
127 } catch (const std::exception& e) {
128 result.status = TestStatus::kFailed;
129 result.error_message = "Proposal test failed: " + std::string(e.what());
130 }
131
132 auto end_time = std::chrono::steady_clock::now();
133 result.duration = std::chrono::duration_cast<std::chrono::milliseconds>(
134 end_time - start_time);
135
136 results.AddResult(result);
137 }
138
139 void RunCommandParsingTest(TestResults& results) {
140 auto start_time = std::chrono::steady_clock::now();
141
142 TestResult result;
143 result.name = "Natural_Language_Command_Parsing";
144 result.suite_name = GetName();
145 result.category = GetCategory();
146 result.timestamp = start_time;
147
148 try {
149 // Test parsing different command types
150 std::vector<std::string> test_commands = {
151 "overworld set-tile --map 0 --x 10 --y 20 --tile 0x02E",
152 "overworld set-area --map 0 --x 10 --y 20 --width 5 --height 3 "
153 "--tile 0x02E",
154 "overworld replace-tile --map 0 --old-tile 0x02E --new-tile 0x030"};
155
156 int passed = 0;
157 int failed = 0;
158
159 using namespace yaze::cli;
160 Tile16ProposalGenerator generator;
161
162 for (const auto& cmd : test_commands) {
163 // GenerateFromCommands(prompt, commands, ai_service, rom)
164 std::vector<std::string> single_cmd = {cmd};
165 auto proposal_or =
166 generator.GenerateFromCommands("", single_cmd, "", nullptr);
167 if (proposal_or.ok()) {
168 passed++;
169 } else {
170 failed++;
171 }
172 }
173
174 if (failed == 0) {
175 result.status = TestStatus::kPassed;
176 result.error_message =
177 absl::StrFormat("All %d command types parsed successfully", passed);
178 } else {
179 result.status = TestStatus::kFailed;
180 result.error_message =
181 absl::StrFormat("%d commands passed, %d failed", passed, failed);
182 }
183 } catch (const std::exception& e) {
184 result.status = TestStatus::kFailed;
185 result.error_message = "Parsing test failed: " + std::string(e.what());
186 }
187
188 auto end_time = std::chrono::steady_clock::now();
189 result.duration = std::chrono::duration_cast<std::chrono::milliseconds>(
190 end_time - start_time);
191
192 results.AddResult(result);
193 }
194
195 bool test_gemini_connectivity_ = true;
196 bool test_proposal_generation_ = true;
197 bool test_command_parsing_ = true;
198};
199
200// Test suite for GUI Automation via gRPC
201class GUIAutomationTestSuite : public TestSuite {
202 public:
203 GUIAutomationTestSuite() = default;
204 ~GUIAutomationTestSuite() override = default;
205
206 std::string GetName() const override { return "GUI Automation (gRPC)"; }
207 TestCategory GetCategory() const override {
208 return TestCategory::kIntegration;
209 }
210
211 absl::Status RunTests(TestResults& results) override {
212 // Test 1: gRPC connection
213 RunConnectionTest(results);
214
215 // Test 2: Basic GUI actions
216 RunBasicActionsTest(results);
217
218 // Test 3: Screenshot capture
219 RunScreenshotTest(results);
220
221 return absl::OkStatus();
222 }
223
224 void DrawConfiguration() override {
225 ImGui::Text("GUI Automation Test Configuration");
226 ImGui::Separator();
227
228 ImGui::Checkbox("Test gRPC Connection", &test_connection_);
229 ImGui::Checkbox("Test GUI Actions", &test_actions_);
230 ImGui::Checkbox("Test Screenshot Capture", &test_screenshots_);
231
232 ImGui::Separator();
233 ImGui::InputText("gRPC Server", grpc_server_address_,
234 sizeof(grpc_server_address_));
235
236 ImGui::Separator();
237 ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f),
238 "Note: Requires ImGuiTestHarness server running");
239 }
240
241 private:
242 void RunConnectionTest(TestResults& results) {
243 auto start_time = std::chrono::steady_clock::now();
244
245 TestResult result;
246 result.name = "gRPC_Connection";
247 result.suite_name = GetName();
248 result.category = GetCategory();
249 result.timestamp = start_time;
250
251 try {
252 using namespace yaze::cli;
253
254 // Create GUI automation client
255 GuiAutomationClient client(grpc_server_address_);
256
257 // Attempt connection
258 auto status = client.Connect();
259
260 if (status.ok()) {
261 result.status = TestStatus::kPassed;
262 result.error_message = "gRPC connection successful";
263 } else {
264 result.status = TestStatus::kFailed;
265 result.error_message =
266 "Connection failed: " + std::string(status.message());
267 }
268 } catch (const std::exception& e) {
269 result.status = TestStatus::kFailed;
270 result.error_message = "Connection test failed: " + std::string(e.what());
271 }
272
273 auto end_time = std::chrono::steady_clock::now();
274 result.duration = std::chrono::duration_cast<std::chrono::milliseconds>(
275 end_time - start_time);
276
277 results.AddResult(result);
278 }
279
280 void RunBasicActionsTest(TestResults& results) {
281 auto start_time = std::chrono::steady_clock::now();
282
283 TestResult result;
284 result.name = "GUI_Basic_Actions";
285 result.suite_name = GetName();
286 result.category = GetCategory();
287 result.timestamp = start_time;
288
289 try {
290 using namespace yaze::cli;
291
292 GuiAutomationClient client(grpc_server_address_);
293 auto conn_status = client.Connect();
294
295 if (!conn_status.ok()) {
296 result.status = TestStatus::kSkipped;
297 result.error_message = "Skipped: Cannot connect to gRPC server";
298 } else {
299 // Test ping action
300 auto ping_result = client.Ping("test");
301
302 if (ping_result.ok() && ping_result->success) {
303 result.status = TestStatus::kPassed;
304 result.error_message = "Basic GUI actions working";
305 } else {
306 result.status = TestStatus::kFailed;
307 result.error_message = "GUI actions failed";
308 }
309 }
310 } catch (const std::exception& e) {
311 result.status = TestStatus::kFailed;
312 result.error_message = "Actions test failed: " + std::string(e.what());
313 }
314
315 auto end_time = std::chrono::steady_clock::now();
316 result.duration = std::chrono::duration_cast<std::chrono::milliseconds>(
317 end_time - start_time);
318
319 results.AddResult(result);
320 }
321
322 void RunScreenshotTest(TestResults& results) {
323 auto start_time = std::chrono::steady_clock::now();
324
325 TestResult result;
326 result.name = "Screenshot_Capture";
327 result.suite_name = GetName();
328 result.category = GetCategory();
329 result.timestamp = start_time;
330
331 try {
332 // Screenshot capture test would go here
333 // For now, mark as passed if we have the capability
334 result.status = TestStatus::kPassed;
335 result.error_message = "Screenshot capture capability available";
336 } catch (const std::exception& e) {
337 result.status = TestStatus::kFailed;
338 result.error_message = "Screenshot test failed: " + std::string(e.what());
339 }
340
341 auto end_time = std::chrono::steady_clock::now();
342 result.duration = std::chrono::duration_cast<std::chrono::milliseconds>(
343 end_time - start_time);
344
345 results.AddResult(result);
346 }
347
348 bool test_connection_ = true;
349 bool test_actions_ = true;
350 bool test_screenshots_ = true;
351 char grpc_server_address_[256] = "localhost:50052";
352};
353
354#endif // YAZE_WITH_GRPC
355
356} // namespace test
357} // namespace yaze
358
359#endif // YAZE_APP_TEST_Z3ED_TEST_SUITE_H
Client for automating YAZE GUI through gRPC.
Generates and manages tile16 editing proposals.
absl::StatusOr< Tile16Proposal > GenerateFromCommands(const std::string &prompt, const std::vector< std::string > &commands, const std::string &ai_service, Rom *rom)
Generate a tile16 proposal from an AI-generated command list.
Namespace for the command line interface.
void RegisterZ3edTestSuites()