Skip to content

Commit

Permalink
Add simulator support for testing focus commands (and other serial in…
Browse files Browse the repository at this point in the history
…teraction)
  • Loading branch information
obra committed Dec 17, 2024
1 parent 9bed203 commit e22493f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
57 changes: 57 additions & 0 deletions testing/SimHarness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,63 @@ uint8_t SimHarness::CycleTime() const {
return millis_per_cycle_;
}

// Serial support implementation
void SimHarness::ProcessSerialInput() {
// This will be called by RunCycle() to process any pending serial input
// The actual processing is handled by the virtual HardwareSerial implementation
}

void SimHarness::SendSerialData(const uint8_t *data, size_t length) {
// Get direct access to the virtual device's serial port
auto &serial = Serial;
serial.injectInput(data, length);
}

std::vector<uint8_t> SimHarness::GetSerialOutput() {
// Get direct access to the virtual device's serial port
auto &serial = Serial;
return serial.getOutputBuffer();
}

// Focus protocol helper implementations
std::string SimHarness::SendFocusCommand(const std::string &command) {
// Ensure command ends with newline
std::string cmd = command;
if (cmd.empty() || cmd.back() != '\n') {
cmd += '\n';
}

// Send command
SendString(cmd);

// Run cycles until we get a complete response
// (ends with \r\n.\r\n)
std::string response;
size_t max_cycles = 100; // Prevent infinite loops
size_t cycles = 0;

while (cycles++ < max_cycles) {
RunCycle();
response = GetSerialOutputAsString();
if (IsFocusResponse(response)) break;
}

return StripFocusTerminator(response);
}

bool SimHarness::IsFocusResponse(const std::string &response) {
static const std::string terminator = "\r\n.\r\n";
return response.length() >= terminator.length() &&
response.substr(response.length() - terminator.length()) == terminator;
}

std::string SimHarness::StripFocusTerminator(const std::string &response) {
static const std::string terminator = "\r\n.\r\n";
if (IsFocusResponse(response)) {
return response.substr(0, response.length() - terminator.length());
}
return response;
}

} // namespace testing
} // namespace kaleidoscope
19 changes: 19 additions & 0 deletions testing/SimHarness.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include <cstddef> // for size_t
#include <cstdint> // for uint8_t
#include <vector>
#include <string>

#include "kaleidoscope/KeyAddr.h" // for KeyAddr
#include "testing/gtest.h" // IWYU pragma: keep
Expand All @@ -37,6 +39,23 @@ class SimHarness {
void SetCycleTime(uint8_t millis);
uint8_t CycleTime() const;

// Serial support
void ProcessSerialInput();
void SendString(const std::string &str) {
SendSerialData(reinterpret_cast<const uint8_t *>(str.c_str()), str.length());
}
void SendSerialData(const uint8_t *data, size_t length);
std::vector<uint8_t> GetSerialOutput();
std::string GetSerialOutputAsString() {
auto output = GetSerialOutput();
return std::string(output.begin(), output.end());
}

// Focus protocol helpers
std::string SendFocusCommand(const std::string &command);
static bool IsFocusResponse(const std::string &response);
static std::string StripFocusTerminator(const std::string &response);

private:
uint8_t millis_per_cycle_ = 1;
};
Expand Down

0 comments on commit e22493f

Please sign in to comment.