// Step 1923: DAPProxyServer // DAP protocol message dispatcher. // // t1: default request handlers return success response with empty body // t2: response envelope has correct fields (seq, type, request_seq, command, success) // t3: registerHandler overrides default; custom body returned // t4: event messages return empty (no response) // t5: unknown command still returns success response (no crash) #include "DAPProxyServer.h" #include #include using json = nlohmann::json; namespace ws = whetstone; static int p=0,f=0; #define T(n) { std::cout<<" "<<#n<<"... "; } #define P() { std::cout<<"PASS\n"; ++p; } #define F(m) { std::cout<<"FAIL: "<() > resp["seq"].get(), "seq increments"); P(); } void t3(){ T(registerHandler_overrides_default); ws::DAPProxyServer srv; srv.registerHandler("stackTrace", [](const json&) -> json { return {{"stackFrames", json::array({ {{"id",1},{"name","main"},{"source","file:///main.py"},{"line",10}} })}}; }); auto resp = srv.handle(makeReq(1, "stackTrace")); C(resp["success"] == true, "success"); C(resp["body"].contains("stackFrames"), "body has stackFrames"); C(resp["body"]["stackFrames"].size() == 1, "one frame"); C(resp["body"]["stackFrames"][0]["name"] == "main", "frame name"); P(); } void t4(){ T(event_returns_empty); ws::DAPProxyServer srv; json evt = {{"seq",1},{"type","event"},{"event","stopped"}, {"body",{{"reason","breakpoint"}}}}; auto resp = srv.handle(evt); C(resp.is_null() || resp.empty(), "event returns no response"); P(); } void t5(){ T(unknown_command_returns_success_no_crash); ws::DAPProxyServer srv; auto resp = srv.handle(makeReq(1, "customCommand")); C(resp["type"] == "response", "type response"); C(resp["success"] == true, "success true"); C(resp["command"] == "customCommand", "command echoed"); P(); } int main(){ std::cout << "Step 1923: DAPProxyServer\n"; t1(); t2(); t3(); t4(); t5(); std::cout << "\n" << p << "/" << (p+f) << " passed\n"; return f > 0 ? 1 : 0; }