mirror of
https://github.com/logos-co/logos-cpp-sdk.git
synced 2026-08-31 09:41:06 +00:00
* Add per-event documentation + getPluginEvents introspection Mirror the per-method documentation pipeline for events. Events (declared in a universal module's logos_events: section) now carry a description parsed from their /// doc comments, and are introspectable at runtime via a new getPluginEvents framework call. - lidl_ast: EventDecl gains a description field. - impl_header_parser: capture the event's doc comment (previously discarded) and an optional metadata.json events[].description. - lidl_gen_provider: generated universal provider emits getEvents() override, mirroring getMethods() (name/signature/ parameters/description; no returnType/isInvokable — events are void). - logos_provider_object: default-empty virtual getEvents() so the legacy provider path and QtProviderObject inherit empty. - module_proxy / qt_provider_object: intercept getPluginEvents next to the getPluginMethods special-case. - docs: spec + README event-documentation notes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add unit tests for event documentation + getEvents generation Address review feedback (#71): cover the event-introspection paths that previously only had method-side tests. - impl_header_parser test: assert metadata.json events[].description is parsed; new documented_events fixture asserts `///` doc-comment capture on a logos_events: block (multi-line joined with \n, adjacent-only, plain // ignored). - lidl_gen_provider test: assert the generated dispatch contains getEvents() emitting each event's name/signature/parameters and an escaped description, and that events carry no returnType/isInvokable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fold event introspection into getMethods() to keep the provider ABI stable The previous approach added a getEvents() virtual to LogosProviderObject, which inserted a new vtable slot and shifted every later slot — an ABI break that would misdispatch virtual calls whenever an old and new host/module were mixed across the in-process plugin boundary. Instead, report events INSIDE the existing getMethods() call: it now returns the module's whole interface, with each entry tagged type "method" or "event" (events omit returnType/isInvokable). The provider vtable is therefore byte-for-byte unchanged, so old/new hosts and modules stay binary-compatible — a new host reading an old module sees no event entries (zero events), and an old host reading a new module just ignores the "type" field (cosmetic). An entry with no "type" is treated as a method. - logos_provider_object.h: remove the getEvents() virtual; document that getMethods() carries both, and why. - generator (lidl_gen_provider): emit events as type "event" entries inside getMethods(); tag methods type "method"; no getEvents() output. - module_proxy / qt_provider_object: getPluginMethods()/getPluginEvents() are now type-filtered views of getMethods(), plus a new getPluginInterface() returning the whole list. (These are name- dispatched Q_INVOKABLEs, not vtable surface — adding them is safe.) - tests: generator asserts events fold into getMethods() tagged "event"; ModuleProxy asserts the three filtered views; parser tests unchanged. - docs: spec/project/docs/README updated, incl. an ABI rationale note. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
463 lines
16 KiB
C++
463 lines
16 KiB
C++
#include <gtest/gtest.h>
|
|
#include "lidl_gen_provider.h"
|
|
#include "lidl_gen_client.h"
|
|
|
|
static ModuleDecl makeTestModule()
|
|
{
|
|
ModuleDecl m;
|
|
m.name = "test_module";
|
|
m.version = "1.0.0";
|
|
m.description = "Test module";
|
|
|
|
// Method: std::string greet(const std::string& name) → tstr
|
|
{
|
|
MethodDecl md;
|
|
md.name = "greet";
|
|
md.returnType = { TypeExpr::Primitive, "tstr", {} };
|
|
ParamDecl p; p.name = "name"; p.type = { TypeExpr::Primitive, "tstr", {} };
|
|
md.params.append(p);
|
|
m.methods.append(md);
|
|
}
|
|
// Method: bool isValid() → bool
|
|
{
|
|
MethodDecl md;
|
|
md.name = "isValid";
|
|
md.returnType = { TypeExpr::Primitive, "bool", {} };
|
|
m.methods.append(md);
|
|
}
|
|
// Method: int64_t getCount() → int
|
|
{
|
|
MethodDecl md;
|
|
md.name = "getCount";
|
|
md.returnType = { TypeExpr::Primitive, "int", {} };
|
|
m.methods.append(md);
|
|
}
|
|
// Method: std::vector<std::string> getNames() → [tstr]
|
|
{
|
|
MethodDecl md;
|
|
md.name = "getNames";
|
|
TypeExpr elem = { TypeExpr::Primitive, "tstr", {} };
|
|
md.returnType = { TypeExpr::Array, "", { elem } };
|
|
m.methods.append(md);
|
|
}
|
|
// Method: void doNothing() → void
|
|
{
|
|
MethodDecl md;
|
|
md.name = "doNothing";
|
|
md.returnType = { TypeExpr::Primitive, "void", {} };
|
|
m.methods.append(md);
|
|
}
|
|
return m;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Provider header generation
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(LidlGenProvider, HeaderContainsClassName)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_TRUE(h.contains("TestModuleProviderObject"));
|
|
EXPECT_TRUE(h.contains("TestModulePlugin"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderIncludesImplHeader)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_TRUE(h.contains("#include \"test_module_impl.h\""));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderIncludesFrameworkHeaders)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_TRUE(h.contains("#include \"logos_provider_object.h\""));
|
|
EXPECT_TRUE(h.contains("#include \"interface.h\""));
|
|
EXPECT_TRUE(h.contains("#include \"logos_types.h\""));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderHasPluginMetadata)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_TRUE(h.contains("Q_PLUGIN_METADATA"));
|
|
EXPECT_TRUE(h.contains("Q_INTERFACES(PluginInterface LogosProviderPlugin)"));
|
|
EXPECT_TRUE(h.contains("Q_OBJECT"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderHasLogosMacro)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_TRUE(h.contains("LOGOS_PROVIDER(TestModuleProviderObject, \"test_module\", \"1.0.0\")"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderHasWrapperMethods)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_TRUE(h.contains("QString greet("));
|
|
EXPECT_TRUE(h.contains("bool isValid("));
|
|
EXPECT_TRUE(h.contains("int getCount("));
|
|
EXPECT_TRUE(h.contains("QStringList getNames("));
|
|
EXPECT_TRUE(h.contains("void doNothing("));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderConvertsStringParams)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
// greet should convert QString→std::string and back
|
|
EXPECT_TRUE(h.contains(".toStdString()"));
|
|
EXPECT_TRUE(h.contains("QString::fromStdString("));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderHasStringVecHelpers)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
// getNames returns [tstr], so helpers should be generated
|
|
EXPECT_TRUE(h.contains("lidlToQStringList"));
|
|
EXPECT_TRUE(h.contains("lidlToStdStringVector"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderHasImplMember)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_TRUE(h.contains("TestModuleImpl m_impl"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderHasCreateProviderObject)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_TRUE(h.contains("createProviderObject()"));
|
|
EXPECT_TRUE(h.contains("new TestModuleProviderObject()"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderPluginReturnsCorrectName)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_TRUE(h.contains("return QStringLiteral(\"test_module\")"));
|
|
EXPECT_TRUE(h.contains("return QStringLiteral(\"1.0.0\")"));
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// No string vec helpers when not needed
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(LidlGenProvider, NoStringVecHelpersWhenNotNeeded)
|
|
{
|
|
ModuleDecl m;
|
|
m.name = "simple";
|
|
m.version = "1.0.0";
|
|
MethodDecl md;
|
|
md.name = "getFlag";
|
|
md.returnType = { TypeExpr::Primitive, "bool", {} };
|
|
m.methods.append(md);
|
|
|
|
QString h = lidlMakeProviderHeader(m, "SimpleImpl", "simple_impl.h");
|
|
EXPECT_FALSE(h.contains("lidlToQStringList"));
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Dispatch generation
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(LidlGenProvider, DispatchContainsCallMethod)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("::callMethod(const QString& methodName, const QVariantList& args)"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, DispatchHasMethodChecks)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("if (methodName == \"greet\")"));
|
|
EXPECT_TRUE(d.contains("if (methodName == \"isValid\")"));
|
|
EXPECT_TRUE(d.contains("if (methodName == \"getCount\")"));
|
|
EXPECT_TRUE(d.contains("if (methodName == \"getNames\")"));
|
|
EXPECT_TRUE(d.contains("if (methodName == \"doNothing\")"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, DispatchVoidReturnsTrueVariant)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
// doNothing is void, dispatch should return QVariant(true)
|
|
EXPECT_TRUE(d.contains("return QVariant(true)"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, DispatchHasUnknownMethodWarning)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("unknown method"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, DispatchContainsGetMethods)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("::getMethods()"));
|
|
EXPECT_TRUE(d.contains("QJsonArray methods"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, DispatchGetMethodsHasAllMethods)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("\"greet\""));
|
|
EXPECT_TRUE(d.contains("\"isValid\""));
|
|
EXPECT_TRUE(d.contains("\"getCount\""));
|
|
EXPECT_TRUE(d.contains("\"getNames\""));
|
|
EXPECT_TRUE(d.contains("\"doNothing\""));
|
|
}
|
|
|
|
TEST(LidlGenProvider, DispatchGetMethodsHasSignature)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("\"signature\""));
|
|
EXPECT_TRUE(d.contains("greet(QString)"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, DispatchGetMethodsHasReturnType)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("\"returnType\""));
|
|
}
|
|
|
|
TEST(LidlGenProvider, DispatchGetMethodsHasParameters)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("\"parameters\""));
|
|
}
|
|
|
|
TEST(LidlGenProvider, DispatchIncludesGlueHeader)
|
|
{
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("#include \"test_module_qt_glue.h\""));
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Events in provider header
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(LidlGenProvider, EventEmitters)
|
|
{
|
|
ModuleDecl m;
|
|
m.name = "evented";
|
|
m.version = "1.0.0";
|
|
EventDecl ed;
|
|
ed.name = "onUpdate";
|
|
ParamDecl p; p.name = "data"; p.type = { TypeExpr::Primitive, "tstr", {} };
|
|
ed.params.append(p);
|
|
m.events.append(ed);
|
|
|
|
QString h = lidlMakeProviderHeader(m, "EventedImpl", "evented_impl.h");
|
|
// The provider class still gains a protected `emit<EventName>(...)`
|
|
// helper per declared event (callable from custom provider code,
|
|
// unused by the standard impl flow which goes via the typed
|
|
// `logos_events:` path).
|
|
EXPECT_TRUE(h.contains("emitOnupdate"));
|
|
EXPECT_TRUE(h.contains("emitEvent(\"onUpdate\""));
|
|
// Events declared in ModuleDecl.events flow through the
|
|
// `_logos_codegen_::maybeSetEmitEvent` SFINAE helper invoked from
|
|
// the generated `onInit`. There is no constructor-based wiring — the
|
|
// old `m_impl.emitEvent = …` path was removed along with the legacy
|
|
// `std::function emitEvent` member it supported.
|
|
EXPECT_TRUE(h.contains("_logos_codegen_::maybeSetEmitEvent(m_impl"));
|
|
EXPECT_TRUE(h.contains("emitEvent(QString::fromStdString(name)"));
|
|
EXPECT_FALSE(h.contains("m_impl.emitEvent ="));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderIncludesNlohmannConversionForJsonMapReturn)
|
|
{
|
|
ModuleDecl m;
|
|
m.name = "jm";
|
|
m.version = "1.0.0";
|
|
MethodDecl md;
|
|
md.name = "getPayload";
|
|
md.returnType = { TypeExpr::Map, "", { { TypeExpr::Primitive, "tstr", {} },
|
|
{ TypeExpr::Primitive, "any", {} } } };
|
|
md.jsonReturn = true;
|
|
m.methods.append(md);
|
|
|
|
QString h = lidlMakeProviderHeader(m, "JmImpl", "jm_impl.h");
|
|
EXPECT_TRUE(h.contains("#include <nlohmann/json.hpp>"));
|
|
EXPECT_TRUE(h.contains("nlohmannToQVariant"));
|
|
EXPECT_TRUE(h.contains("auto _result = m_impl.getPayload("));
|
|
EXPECT_TRUE(h.contains("return nlohmannToQVariant(_result).toMap()"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderUsesToListForJsonListReturn)
|
|
{
|
|
ModuleDecl m;
|
|
m.name = "jl";
|
|
m.version = "1.0.0";
|
|
MethodDecl md;
|
|
md.name = "getItems";
|
|
md.returnType = { TypeExpr::Array, "", { { TypeExpr::Primitive, "any", {} } } };
|
|
md.jsonReturn = true;
|
|
m.methods.append(md);
|
|
|
|
QString h = lidlMakeProviderHeader(m, "JlImpl", "jl_impl.h");
|
|
EXPECT_TRUE(h.contains("return nlohmannToQVariant(_result).toList()"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, NoNlohmannBlockWithoutJsonReturnMethods)
|
|
{
|
|
ModuleDecl m = makeTestModule();
|
|
QString h = lidlMakeProviderHeader(m, "TestModuleImpl", "test_module_impl.h");
|
|
EXPECT_FALSE(h.contains("nlohmann/json.hpp"));
|
|
EXPECT_FALSE(h.contains("nlohmannToQVariant"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, HeaderIncludesNlohmannAndStdResultForResultReturn)
|
|
{
|
|
ModuleDecl m;
|
|
m.name = "resmod";
|
|
m.version = "1.0.0";
|
|
MethodDecl md;
|
|
md.name = "getResult";
|
|
md.returnType = { TypeExpr::Primitive, "result", {} };
|
|
md.resultReturn = true;
|
|
m.methods.append(md);
|
|
|
|
QString h = lidlMakeProviderHeader(m, "ResModImpl", "resmod_impl.h");
|
|
EXPECT_TRUE(h.contains("#include <nlohmann/json.hpp>"));
|
|
EXPECT_TRUE(h.contains("nlohmannToQVariant"));
|
|
EXPECT_TRUE(h.contains("#include \"logos_result.h\""));
|
|
EXPECT_TRUE(h.contains("stdResultToQt"));
|
|
EXPECT_TRUE(h.contains("auto _result = m_impl.getResult("));
|
|
EXPECT_TRUE(h.contains("return stdResultToQt(_result)"));
|
|
}
|
|
|
|
TEST(LidlGenProvider, StdResultMethodHasLogosResultReturnType)
|
|
{
|
|
ModuleDecl m;
|
|
m.name = "resmod2";
|
|
m.version = "1.0.0";
|
|
MethodDecl md;
|
|
md.name = "doWork";
|
|
md.returnType = { TypeExpr::Primitive, "result", {} };
|
|
md.resultReturn = true;
|
|
m.methods.append(md);
|
|
|
|
QString h = lidlMakeProviderHeader(m, "ResModImpl2", "resmod2_impl.h");
|
|
EXPECT_TRUE(h.contains("LogosResult doWork("));
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Empty module
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(LidlGenProvider, EmptyModuleGeneratesValidCode)
|
|
{
|
|
ModuleDecl m;
|
|
m.name = "empty";
|
|
m.version = "0.0.1";
|
|
|
|
QString h = lidlMakeProviderHeader(m, "EmptyImpl", "empty_impl.h");
|
|
EXPECT_TRUE(h.contains("EmptyProviderObject"));
|
|
EXPECT_TRUE(h.contains("EmptyPlugin"));
|
|
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("::callMethod("));
|
|
EXPECT_TRUE(d.contains("::getMethods()"));
|
|
// There is no separate getEvents(): events (when present) ride inside
|
|
// getMethods(), so the provider vtable never gains a slot.
|
|
EXPECT_FALSE(d.contains("::getEvents()"));
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Event introspection generation — events are folded INTO getMethods() (each
|
|
// tagged type "event"), not a separate getEvents() vtable method. This keeps
|
|
// LogosProviderObject's vtable layout stable across SDK versions.
|
|
// ---------------------------------------------------------------------------
|
|
|
|
static ModuleDecl makeEventModule()
|
|
{
|
|
ModuleDecl m;
|
|
m.name = "evt_module";
|
|
m.version = "1.0.0";
|
|
|
|
// Documented event with two params (multi-line description).
|
|
{
|
|
EventDecl ed;
|
|
ed.name = "userLoggedIn";
|
|
ed.description = "Auth done.\nToken issued.";
|
|
ParamDecl p1; p1.name = "userId"; p1.type = { TypeExpr::Primitive, "tstr", {} };
|
|
ParamDecl p2; p2.name = "token"; p2.type = { TypeExpr::Primitive, "tstr", {} };
|
|
ed.params.append(p1);
|
|
ed.params.append(p2);
|
|
m.events.append(ed);
|
|
}
|
|
// Undocumented, no-arg event.
|
|
{
|
|
EventDecl ed;
|
|
ed.name = "tick";
|
|
m.events.append(ed);
|
|
}
|
|
return m;
|
|
}
|
|
|
|
TEST(LidlGenProvider, GetMethodsContainsEventsTaggedEvent)
|
|
{
|
|
auto m = makeEventModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
// No separate getEvents() override is generated…
|
|
EXPECT_FALSE(d.contains("::getEvents()"));
|
|
// …instead events appear inside getMethods(), each tagged type "event".
|
|
EXPECT_TRUE(d.contains("::getMethods()"));
|
|
EXPECT_TRUE(d.contains("QStringLiteral(\"event\")"));
|
|
EXPECT_TRUE(d.contains("\"userLoggedIn\""));
|
|
EXPECT_TRUE(d.contains("\"tick\""));
|
|
}
|
|
|
|
TEST(LidlGenProvider, GetMethodsEventHasSignatureAndParams)
|
|
{
|
|
auto m = makeEventModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
// Event signature is computed from its params (tstr → QString).
|
|
EXPECT_TRUE(d.contains("userLoggedIn(QString,QString)"));
|
|
EXPECT_TRUE(d.contains("\"userId\""));
|
|
EXPECT_TRUE(d.contains("\"token\""));
|
|
}
|
|
|
|
TEST(LidlGenProvider, GetMethodsEventEmitsDescription)
|
|
{
|
|
auto m = makeEventModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
// The multi-line description is emitted with its newline escaped (\n).
|
|
EXPECT_TRUE(d.contains("Auth done.\\nToken issued."));
|
|
}
|
|
|
|
TEST(LidlGenProvider, EventEntriesHaveNoReturnType)
|
|
{
|
|
// An events-only module: events are void, so no returnType/isInvokable key
|
|
// is emitted anywhere (those belong to methods only).
|
|
auto m = makeEventModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_FALSE(d.contains("\"returnType\""));
|
|
EXPECT_FALSE(d.contains("\"isInvokable\""));
|
|
}
|
|
|
|
TEST(LidlGenProvider, MethodEntriesTaggedMethod)
|
|
{
|
|
// A module with methods: each getMethods() entry is tagged type "method".
|
|
auto m = makeTestModule();
|
|
QString d = lidlMakeProviderDispatch(m);
|
|
EXPECT_TRUE(d.contains("QStringLiteral(\"method\")"));
|
|
}
|