Files
whetstone_DSL/editor/tests/step1933_test.cpp
Bill 99cc6319c0 Sprint 281: DAP Hardening (steps 1933–1937)
DAPRequestValidator, DAPCapabilityNegotiator, DAPEventBroadcaster,
DAPBreakpointHitDispatcher — 26/26 tests pass.
Integration step 1937: Python+Rust DAP session round-trip verified.
Also adds allBreakpoints() to ASTNodeBreakpointMapper.
Metrics: 8 whetstone calls, 8853 tokens.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 21:45:53 -07:00

91 lines
3.2 KiB
C++

// Step 1933: DAPRequestValidator
//
// t1: valid request message passes
// t2: valid response and event messages pass
// t3: missing/wrong type fails
// t4: bad seq fails; missing command/event field fails
// t5: validateBatch and static predicates
#include "DAPRequestValidator.h"
#include <iostream>
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: "<<m<<"\n"; ++f; }
#define C(c,m) if(!(c)){F(m);return;}
void t1(){
T(valid_request_passes);
ws::DAPRequestValidator v;
nlohmann::json req = {{"type","request"},{"seq",1},{"command","launch"}};
auto r = v.validate(req);
C(r.valid, "valid");
C(r.errorCode.empty(),"no error code");
P();
}
void t2(){
T(valid_response_and_event);
ws::DAPRequestValidator v;
nlohmann::json resp = {{"type","response"},{"seq",2},{"command","launch"}};
nlohmann::json event = {{"type","event"}, {"seq",3},{"event","stopped"}};
auto rr = v.validate(resp);
auto re = v.validate(event);
C(rr.valid, "response valid");
C(re.valid, "event valid");
P();
}
void t3(){
T(wrong_or_missing_type_fails);
ws::DAPRequestValidator v;
nlohmann::json noType = {{"seq",1},{"command","x"}};
nlohmann::json badType = {{"type","other"},{"seq",1},{"command","x"}};
C(!v.validate(noType).valid, "missing type invalid");
C(!v.validate(badType).valid, "unknown type invalid");
C(v.validate(badType).errorCode == "unknown_type", "unknown_type code");
P();
}
void t4(){
T(bad_seq_and_missing_command_fail);
ws::DAPRequestValidator v;
nlohmann::json zeroSeq = {{"type","request"},{"seq",0},{"command","x"}};
nlohmann::json noCommand = {{"type","request"},{"seq",1}};
nlohmann::json noEvent = {{"type","event"}, {"seq",1}};
C(!v.validate(zeroSeq).valid, "seq 0 invalid");
C(!v.validate(noCommand).valid, "missing command invalid");
C(!v.validate(noEvent).valid, "missing event field invalid");
C(v.validate(noCommand).errorCode == "missing_command", "missing_command code");
P();
}
void t5(){
T(validateBatch_and_static_predicates);
ws::DAPRequestValidator v;
nlohmann::json req = {{"type","request"}, {"seq",1},{"command","next"}};
nlohmann::json resp = {{"type","response"},{"seq",2},{"command","next"}};
nlohmann::json ev = {{"type","event"}, {"seq",3},{"event","output"}};
nlohmann::json bad = {{"type","bad"}, {"seq",4},{"command","x"}};
auto results = v.validateBatch({req, resp, ev, bad});
C(results.size() == 4, "batch size 4");
C( results[0].valid, "req valid");
C( results[1].valid, "resp valid");
C( results[2].valid, "ev valid");
C(!results[3].valid, "bad invalid");
C(ws::DAPRequestValidator::isRequest(req), "isRequest");
C(ws::DAPRequestValidator::isResponse(resp),"isResponse");
C(ws::DAPRequestValidator::isEvent(ev), "isEvent");
C(!ws::DAPRequestValidator::isRequest(ev), "req not event");
P();
}
int main(){
std::cout << "Step 1933: DAPRequestValidator\n";
t1(); t2(); t3(); t4(); t5();
std::cout << "\n" << p << "/" << (p+f) << " passed\n";
return f > 0 ? 1 : 0;
}