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>
This commit is contained in:
89
editor/tests/step1935_test.cpp
Normal file
89
editor/tests/step1935_test.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
// Step 1935: DAPEventBroadcaster
|
||||
//
|
||||
// t1: subscribe and broadcast fires handler
|
||||
// t2: multiple subscribers for same event type all fire
|
||||
// t3: unsubscribe stops handler from firing
|
||||
// t4: broadcastAll routes by event["event"]
|
||||
// t5: subscriberCount correct; different types independent
|
||||
|
||||
#include "DAPEventBroadcaster.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(subscribe_and_broadcast_fires_handler);
|
||||
ws::DAPEventBroadcaster b;
|
||||
int count = 0;
|
||||
b.subscribe("stopped", [&](const nlohmann::json&){ ++count; });
|
||||
b.broadcast("stopped", {});
|
||||
C(count == 1, "handler fired once");
|
||||
b.broadcast("continued", {});
|
||||
C(count == 1, "other event not fired");
|
||||
P();
|
||||
}
|
||||
|
||||
void t2(){
|
||||
T(multiple_subscribers_all_fire);
|
||||
ws::DAPEventBroadcaster b;
|
||||
int a = 0, c = 0;
|
||||
b.subscribe("output", [&](const nlohmann::json&){ ++a; });
|
||||
b.subscribe("output", [&](const nlohmann::json&){ ++c; });
|
||||
b.broadcast("output", {});
|
||||
C(a == 1 && c == 1, "both handlers fired");
|
||||
P();
|
||||
}
|
||||
|
||||
void t3(){
|
||||
T(unsubscribe_stops_handler);
|
||||
ws::DAPEventBroadcaster b;
|
||||
int count = 0;
|
||||
int id = b.subscribe("stopped", [&](const nlohmann::json&){ ++count; });
|
||||
b.broadcast("stopped", {});
|
||||
C(count == 1, "fired before unsubscribe");
|
||||
b.unsubscribe(id);
|
||||
b.broadcast("stopped", {});
|
||||
C(count == 1, "not fired after unsubscribe");
|
||||
C(b.subscriberCount("stopped") == 0, "count 0 after unsubscribe");
|
||||
P();
|
||||
}
|
||||
|
||||
void t4(){
|
||||
T(broadcastAll_routes_by_event_field);
|
||||
ws::DAPEventBroadcaster b;
|
||||
int stopped = 0, output = 0;
|
||||
b.subscribe("stopped", [&](const nlohmann::json&){ ++stopped; });
|
||||
b.subscribe("output", [&](const nlohmann::json&){ ++output; });
|
||||
nlohmann::json ev = {{"type","event"},{"seq",1},{"event","stopped"},{"body",{}}};
|
||||
b.broadcastAll(ev);
|
||||
C(stopped == 1, "stopped handler fired");
|
||||
C(output == 0, "output handler not fired");
|
||||
// no event field → no-op
|
||||
b.broadcastAll({{"type","event"},{"seq",2}});
|
||||
C(stopped == 1, "still 1 after no-event broadcast");
|
||||
P();
|
||||
}
|
||||
|
||||
void t5(){
|
||||
T(subscriberCount_independent_per_type);
|
||||
ws::DAPEventBroadcaster b;
|
||||
b.subscribe("stopped", [](const nlohmann::json&){});
|
||||
b.subscribe("stopped", [](const nlohmann::json&){});
|
||||
b.subscribe("continued",[](const nlohmann::json&){});
|
||||
C(b.subscriberCount("stopped") == 2, "two stopped");
|
||||
C(b.subscriberCount("continued") == 1, "one continued");
|
||||
C(b.subscriberCount("output") == 0, "zero output");
|
||||
P();
|
||||
}
|
||||
|
||||
int main(){
|
||||
std::cout << "Step 1935: DAPEventBroadcaster\n";
|
||||
t1(); t2(); t3(); t4(); t5();
|
||||
std::cout << "\n" << p << "/" << (p+f) << " passed\n";
|
||||
return f > 0 ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user