// Step 1920: LSPRequestThrottler // Debounces per-URI requests to prevent flooding language servers. // // t1: no prior record → shouldAllow true // t2: within debounce window → shouldAllow false // t3: after debounce window expires → shouldAllow true // t4: reset clears uri; resetAll clears everything // t5: lastTimestamp returns -1 for missing, correct value after record #include "LSPRequestThrottler.h" #include 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: "<=) C( t.shouldAllow("file:///a.go","textDocument/didChange",1500,500), "at boundary allowed"); // past boundary C( t.shouldAllow("file:///a.go","textDocument/didChange",1600,500), "past boundary allowed"); P(); } void t4(){ T(reset_and_resetAll); ws::LSPRequestThrottler t; t.record("file:///a.go","textDocument/didChange",1000); t.record("file:///b.go","textDocument/didChange",1000); t.reset("file:///a.go"); C( t.shouldAllow("file:///a.go","textDocument/didChange",1100,500), "a.go reset → allowed"); C(!t.shouldAllow("file:///b.go","textDocument/didChange",1100,500), "b.go still throttled"); t.resetAll(); C( t.shouldAllow("file:///b.go","textDocument/didChange",1100,500), "b.go allowed after resetAll"); P(); } void t5(){ T(lastTimestamp); ws::LSPRequestThrottler t; C(t.lastTimestamp("file:///a.go","textDocument/didChange") == -1, "no record returns -1"); t.record("file:///a.go","textDocument/didChange",9999); C(t.lastTimestamp("file:///a.go","textDocument/didChange") == 9999, "correct timestamp"); C(t.lastTimestamp("file:///a.go","textDocument/hover") == -1, "different method -1"); P(); } int main(){ std::cout << "Step 1920: LSPRequestThrottler\n"; t1(); t2(); t3(); t4(); t5(); std::cout << "\n" << p << "/" << (p+f) << " passed\n"; return f > 0 ? 1 : 0; }