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>
90 lines
2.9 KiB
C++
90 lines
2.9 KiB
C++
// 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;
|
|
}
|