fix: Refactor test command handling with modular structure and common utilities

- Added new `test_common` module with helper functions for prompting and input handling.
- Introduced `test_common.cc` and `test_common.h` for shared functionality across test commands.
- Updated `z3ed.cmake` to include `test_common` in the build process.
- Refactored `test_commands.cc` to utilize new common utilities for improved readability and maintainability.
- Adjusted paths for source files in the build configuration to ensure proper linking.

This commit lays the groundwork for a more organized and modular approach to handling test commands, facilitating future enhancements and maintenance.
This commit is contained in:
scawful
2025-10-03 02:10:18 -04:00
parent ba12075ca9
commit 758b0c0a35
5 changed files with 206 additions and 2327 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,133 @@
#include "cli/handlers/agent/test_common.h"
#include <cctype>
#include <iostream>
#include <string>
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/strip.h"
#if defined(_WIN32)
#include <io.h>
#else
#include <unistd.h>
#endif
namespace yaze {
namespace cli {
namespace agent {
std::string TrimWhitespace(absl::string_view value) {
return std::string(absl::StripAsciiWhitespace(value));
}
bool IsInteractiveInput() {
#if defined(_WIN32)
return _isatty(_fileno(stdin)) != 0;
#else
return isatty(fileno(stdin)) != 0;
#endif
}
std::string PromptWithDefault(const std::string& prompt,
const std::string& default_value,
bool allow_empty) {
while (true) {
std::cout << prompt;
if (!default_value.empty()) {
std::cout << " [" << default_value << "]";
}
std::cout << ": ";
std::cout.flush();
std::string line;
if (!std::getline(std::cin, line)) {
return default_value;
}
std::string trimmed = TrimWhitespace(line);
if (!trimmed.empty()) {
return trimmed;
}
if (!default_value.empty()) {
return default_value;
}
if (allow_empty) {
return std::string();
}
std::cout << " Value is required." << std::endl;
}
}
std::string PromptRequired(const std::string& prompt,
const std::string& default_value) {
return PromptWithDefault(prompt, default_value, /*allow_empty=*/false);
}
int PromptInt(const std::string& prompt, int default_value, int min_value) {
while (true) {
std::string default_str = absl::StrCat(default_value);
std::string input = PromptWithDefault(prompt, default_str);
if (input.empty()) {
return default_value;
}
int value = 0;
if (absl::SimpleAtoi(input, &value) && value >= min_value) {
return value;
}
std::cout << " Enter an integer >= " << min_value << "." << std::endl;
}
}
bool PromptYesNo(const std::string& prompt, bool default_value) {
while (true) {
std::cout << prompt << " [" << (default_value ? "Y/n" : "y/N")
<< "]: ";
std::cout.flush();
std::string line;
if (!std::getline(std::cin, line)) {
return default_value;
}
std::string trimmed = TrimWhitespace(line);
if (trimmed.empty()) {
return default_value;
}
char c = static_cast<char>(std::tolower(static_cast<unsigned char>(trimmed[0])));
if (c == 'y') {
return true;
}
if (c == 'n') {
return false;
}
std::cout << " Please respond with 'y' or 'n'." << std::endl;
}
}
std::vector<std::string> ParseCommaSeparated(absl::string_view input) {
std::vector<std::string> values;
for (absl::string_view token : absl::StrSplit(input, ',')) {
std::string trimmed = TrimWhitespace(token);
if (!trimmed.empty()) {
values.push_back(trimmed);
}
}
return values;
}
bool ParseKeyValueEntry(const std::string& input, std::string* key,
std::string* value) {
size_t equals = input.find('=');
if (equals == std::string::npos) {
return false;
}
*key = TrimWhitespace(absl::string_view(input.data(), equals));
*value = TrimWhitespace(absl::string_view(input.data() + equals + 1,
input.size() - equals - 1));
return !key->empty();
}
} // namespace agent
} // namespace cli
} // namespace yaze

View File

@@ -0,0 +1,40 @@
#ifndef YAZE_CLI_HANDLERS_AGENT_TEST_COMMON_H_
#define YAZE_CLI_HANDLERS_AGENT_TEST_COMMON_H_
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
namespace yaze {
namespace cli {
namespace agent {
// Common helper functions for test command handlers
std::string TrimWhitespace(absl::string_view value);
bool IsInteractiveInput();
std::string PromptWithDefault(const std::string& prompt,
const std::string& default_value,
bool allow_empty = true);
std::string PromptRequired(const std::string& prompt,
const std::string& default_value = std::string());
int PromptInt(const std::string& prompt, int default_value, int min_value);
bool PromptYesNo(const std::string& prompt, bool default_value);
std::vector<std::string> ParseCommaSeparated(absl::string_view input);
bool ParseKeyValueEntry(const std::string& input, std::string* key,
std::string* value);
} // namespace agent
} // namespace cli
} // namespace yaze
#endif // YAZE_CLI_HANDLERS_AGENT_TEST_COMMON_H_

View File

@@ -10,8 +10,8 @@
#include "absl/strings/strip.h"
#ifdef YAZE_WITH_JSON
#include "incl/httplib.h"
#include "third_party/json/src/json.hpp"
#include "httplib.h"
#include "nlohmann/json.hpp"
#endif
namespace yaze {

View File

@@ -44,6 +44,7 @@ add_executable(
cli/handlers/agent.cc
cli/handlers/agent/common.cc
cli/handlers/agent/general_commands.cc
cli/handlers/agent/test_common.cc
cli/handlers/agent/test_commands.cc
cli/handlers/agent/gui_commands.cc
cli/service/ai_service.cc
@@ -75,10 +76,11 @@ add_executable(
option(YAZE_WITH_JSON "Build with JSON support" OFF)
if(YAZE_WITH_JSON)
add_subdirectory(../../third_party/json)
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/json ${CMAKE_BINARY_DIR}/third_party/json)
target_compile_definitions(z3ed PRIVATE YAZE_WITH_JSON)
target_link_libraries(z3ed PRIVATE nlohmann_json::nlohmann_json)
list(APPEND Z3ED_SRC_FILES cli/gemini_ai_service.cc)
list(APPEND Z3ED_SRC_FILES cli/service/gemini_ai_service.cc)
list(APPEND Z3ED_SRC_FILES cli/service/prompt_builder.cc)
endif()
target_include_directories(
@@ -91,6 +93,7 @@ target_include_directories(
${CMAKE_SOURCE_DIR}/incl/
${CMAKE_SOURCE_DIR}/src/
${CMAKE_SOURCE_DIR}/src/lib/imgui_test_engine
${CMAKE_SOURCE_DIR}/third_party/httplib
${PNG_INCLUDE_DIRS}
${SDL2_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}