1#include "gtest/gtest.h"
3#include "absl/strings/str_format.h"
34 using namespace cli::ai;
37 auto result = AIActionParser::ParseCommand(
38 "Place tile 0x42 at overworld position (5, 7)");
40 ASSERT_TRUE(result.ok()) << result.status().message();
41 EXPECT_EQ(result->size(), 3);
44 EXPECT_EQ(result->at(0).type, AIActionType::kSelectTile);
45 EXPECT_EQ(result->at(0).parameters.at(
"tile_id"),
"66");
48 EXPECT_EQ(result->at(1).type, AIActionType::kPlaceTile);
49 EXPECT_EQ(result->at(1).parameters.at(
"x"),
"5");
50 EXPECT_EQ(result->at(1).parameters.at(
"y"),
"7");
51 EXPECT_EQ(result->at(1).parameters.at(
"map_id"),
"0");
54 EXPECT_EQ(result->at(2).type, AIActionType::kSaveTile);
58 using namespace cli::ai;
60 auto result = AIActionParser::ParseCommand(
"Select tile 100");
62 ASSERT_TRUE(result.ok());
63 EXPECT_EQ(result->size(), 1);
64 EXPECT_EQ(result->at(0).type, AIActionType::kSelectTile);
65 EXPECT_EQ(result->at(0).parameters.at(
"tile_id"),
"100");
69 using namespace cli::ai;
71 auto result = AIActionParser::ParseCommand(
"Open the overworld editor");
73 ASSERT_TRUE(result.ok());
74 EXPECT_EQ(result->size(), 1);
75 EXPECT_EQ(result->at(0).type, AIActionType::kOpenEditor);
76 EXPECT_EQ(result->at(0).parameters.at(
"editor"),
"overworld");
80 using namespace cli::ai;
82 AIAction action(AIActionType::kPlaceTile, {
88 std::string str = AIActionParser::ActionToString(action);
89 EXPECT_FALSE(str.empty());
90 EXPECT_TRUE(str.find(
"5") != std::string::npos);
91 EXPECT_TRUE(str.find(
"7") != std::string::npos);
96TEST_F(AITilePlacementTest, DISABLED_VisionAnalysisBasic) {
98 const char* api_key = std::getenv(
"GEMINI_API_KEY");
99 if (!api_key || std::string(api_key).empty()) {
100 GTEST_SKIP() <<
"GEMINI_API_KEY not set";
103 cli::GeminiConfig config;
104 config.api_key = api_key;
105 config.model =
"gemini-2.5-flash";
107 cli::GeminiAIService gemini_service(config);
108 cli::ai::VisionActionRefiner refiner(&gemini_service);
115TEST_F(AITilePlacementTest, DISABLED_FullAIControlLoop) {
121 const char* api_key = std::getenv(
"GEMINI_API_KEY");
122 if (!api_key || std::string(api_key).empty()) {
123 GTEST_SKIP() <<
"GEMINI_API_KEY not set";
127 cli::GeminiConfig gemini_config;
128 gemini_config.api_key = api_key;
129 cli::GeminiAIService gemini_service(gemini_config);
131 cli::GuiAutomationClient gui_client(
"localhost:50051");
132 auto connect_status = gui_client.Connect();
133 if (!connect_status.ok()) {
134 GTEST_SKIP() <<
"GUI test harness not available: "
135 << connect_status.message();
139 cli::ai::AIGUIController controller(&gemini_service, &gui_client);
140 cli::ai::ControlLoopConfig config;
141 config.max_iterations = 5;
142 config.enable_vision_verification =
true;
143 controller.Initialize(config);
146 auto result = controller.ExecuteCommand(
147 "Place tile 0x42 at overworld position (5, 7)");
150 EXPECT_TRUE(result->success);
151 EXPECT_GT(result->iterations_performed, 0);
158 using namespace cli::ai;
161 VisionAnalysisResult analysis;
162 analysis.action_successful =
false;
163 analysis.error_message =
"Element not found";
165 AIAction original_action(AIActionType::kClickButton, {
175 using namespace cli::ai;
178 std::vector<std::string> commands = {
179 "Open overworld editor",
181 "Place tile at position (5, 7)",
185 for (
const auto& cmd : commands) {
186 auto result = AIActionParser::ParseCommand(cmd);
189 EXPECT_FALSE(result->empty());
195 using namespace cli::ai;
198 auto hex_result = AIActionParser::ParseCommand(
"Select tile 0xFF");
199 if (hex_result.ok() && !hex_result->empty()) {
200 EXPECT_EQ(hex_result->at(0).parameters.at(
"tile_id"),
"255");
204 auto dec_result = AIActionParser::ParseCommand(
"Select tile 255");
205 if (dec_result.ok() && !dec_result->empty()) {
206 EXPECT_EQ(dec_result->at(0).parameters.at(
"tile_id"),
"255");
Integration tests for AI-controlled tile placement.
TEST_F(DungeonObjectRenderingE2ETests, RunAllTests)
Main namespace for the application.