93 lines
3.8 KiB
C++
93 lines
3.8 KiB
C++
|
|
// Step 1919: LSPCapabilityNegotiator
|
||
|
|
// Tracks per-source capability sets; gates routing on capability support.
|
||
|
|
//
|
||
|
|
// t1: registerSource and supports
|
||
|
|
// t2: shouldRoute blocks unsupported method; passes unknown methods
|
||
|
|
// t3: capabilitiesFor returns sorted capability list
|
||
|
|
// t4: sourcesSupporting finds all sources with a given capability
|
||
|
|
// t5: unregistered source supports nothing; shouldRoute passes unknown sources
|
||
|
|
|
||
|
|
#include "LSPCapabilityNegotiator.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(registerSource_and_supports);
|
||
|
|
ws::LSPCapabilityNegotiator n;
|
||
|
|
n.registerSource("gopls", {"hoverProvider","definitionProvider","referencesProvider"});
|
||
|
|
C( n.supports("gopls","hoverProvider"), "gopls has hover");
|
||
|
|
C( n.supports("gopls","definitionProvider"), "gopls has definition");
|
||
|
|
C(!n.supports("gopls","completionProvider"), "gopls lacks completion");
|
||
|
|
C(!n.supports("tsserver","hoverProvider"), "unregistered lacks anything");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
void t2(){
|
||
|
|
T(shouldRoute_blocks_unsupported_passes_unknown);
|
||
|
|
ws::LSPCapabilityNegotiator n;
|
||
|
|
n.registerSource("gopls", {"hoverProvider","definitionProvider"});
|
||
|
|
n.registerSource("tsserver", {"hoverProvider","completionProvider"});
|
||
|
|
// gopls supports hover → route
|
||
|
|
C( n.shouldRoute("gopls", "textDocument/hover"), "gopls routes hover");
|
||
|
|
// gopls lacks completion → block
|
||
|
|
C(!n.shouldRoute("gopls", "textDocument/completion"), "gopls blocks completion");
|
||
|
|
// tsserver supports completion → route
|
||
|
|
C( n.shouldRoute("tsserver", "textDocument/completion"), "tsserver routes completion");
|
||
|
|
// unknown method passes through for all sources
|
||
|
|
C( n.shouldRoute("gopls", "workspace/symbol"), "unknown method passes");
|
||
|
|
C( n.shouldRoute("tsserver", "workspace/symbol"), "unknown method passes ts");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
void t3(){
|
||
|
|
T(capabilitiesFor_returns_list);
|
||
|
|
ws::LSPCapabilityNegotiator n;
|
||
|
|
n.registerSource("gopls", {"hoverProvider","definitionProvider","referencesProvider"});
|
||
|
|
auto caps = n.capabilitiesFor("gopls");
|
||
|
|
C(caps.size() == 3, "three caps");
|
||
|
|
C(n.capabilitiesFor("missing").empty(), "missing source empty");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
void t4(){
|
||
|
|
T(sourcesSupporting_finds_all);
|
||
|
|
ws::LSPCapabilityNegotiator n;
|
||
|
|
n.registerSource("gopls", {"hoverProvider","definitionProvider"});
|
||
|
|
n.registerSource("tsserver", {"hoverProvider","completionProvider"});
|
||
|
|
n.registerSource("pylsp", {"hoverProvider","referencesProvider"});
|
||
|
|
auto hover = n.sourcesSupporting("hoverProvider");
|
||
|
|
C(hover.size() == 3, "three hover sources");
|
||
|
|
auto def = n.sourcesSupporting("definitionProvider");
|
||
|
|
C(def.size() == 1, "one definition source");
|
||
|
|
C(def[0] == "gopls", "gopls for definition");
|
||
|
|
C(n.sourcesSupporting("renameProvider").empty(), "none for rename");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
void t5(){
|
||
|
|
T(unregistered_source_behavior);
|
||
|
|
ws::LSPCapabilityNegotiator n;
|
||
|
|
// unregistered source: supports() returns false
|
||
|
|
C(!n.supports("unknown","hoverProvider"), "unregistered lacks caps");
|
||
|
|
// unregistered source: known method requires capability → shouldRoute false
|
||
|
|
// because supports() returns false for the required cap
|
||
|
|
C(!n.shouldRoute("unknown","textDocument/hover"), "unregistered blocked on known method");
|
||
|
|
// unregistered source: unknown method → passes through
|
||
|
|
C( n.shouldRoute("unknown","$/custom"), "unknown method passes for unregistered");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(){
|
||
|
|
std::cout << "Step 1919: LSPCapabilityNegotiator\n";
|
||
|
|
t1(); t2(); t3(); t4(); t5();
|
||
|
|
std::cout << "\n" << p << "/" << (p+f) << " passed\n";
|
||
|
|
return f > 0 ? 1 : 0;
|
||
|
|
}
|