Index: duchain/builders/usebuilder.cpp =================================================================== --- duchain/builders/usebuilder.cpp +++ duchain/builders/usebuilder.cpp @@ -87,7 +87,12 @@ const DeclarationPointer d = ev.lastDeclaration(); if (d) { UseBuilderBase::newUse(m_editor->findRange(n), d); - ev.setContext(d->internalContext()); + auto context = d->internalContext(); + // Setting invalid context doesn’t make sense and just causes fail in helpers.cpp’s context assert + // TODO: maybe visitClassName() & co. needs this too? + if(context) { + ev.setContext(context); + } } else { break; } Index: duchain/tests/duchain.h =================================================================== --- duchain/tests/duchain.h +++ duchain/tests/duchain.h @@ -166,6 +166,7 @@ void include2(); void extend(); void problemOnInvalidMixin(); + void rspecIncludeIsNormalFunction(); }; } Index: duchain/tests/duchain.cpp =================================================================== --- duchain/tests/duchain.cpp +++ duchain/tests/duchain.cpp @@ -28,6 +28,8 @@ #include #include +#include + // Ruby #include #include @@ -1829,6 +1831,25 @@ testProblems(top, list); } +/** + * Test that rspec’s expectation “include” is handled as normal expectation function and not as a module inclusion. + */ +void TestDUChain::rspecIncludeIsNormalFunction() { + QByteArray code("Then(\"nyaw\") { |string| expect.to include string }"); + TopDUContext *top = parse(code, "rspecIncludeIsNormalFunction"); + QVERIFY(top); + DUChainReleaser releaser(top); + DUChainWriteLocker lock; + + KDevelop::DUContext *childContext = top->childContexts().first(); + KDevelop::Declaration *declaration = childContext->localDeclarations().first(); + qDebug() << declaration->comment(); + + Declaration *dec1 = top->localDeclarations().at(0); + QVERIFY(dec1->type()); + QCOMPARE(dec1->type()->qualifiedIdentifier(), QualifiedIdentifier("Fixnum")); +} + //END: Include & Extend }