Symptom
A @RenderedValue function declared outside the test class — an extension function in an object, or a top-level function — renders the call words in the report sentence instead of being replaced by the function's return value. No exception is thrown. A member function/extension declared in the test class works fine.
Repro
object Helpers { @RenderedValue fun KensaTest.foo(p: String) = "x-$p" }, used with(Helpers) { given(somethingWith(foo("a"))) }. Sentence renders something with foo a instead of something with x-a.
Root cause
The compiler plugin captures the value for @RenderedValue functions regardless of where they're declared, but the parser only classifies a call as @RenderedValue if the function is found by reflecting findAllRelatedClasses → MethodParser.prepareMethods() (core/.../parse/MethodParser.kt:158,84). That set is the test class + @Sources classes + super/interfaces, gated by sourceCode.existsFor. An externally-declared function isn't in it, so no rendered-value token is emitted, the captured value is never looked up, and the call renders as prose.
@Sources(Helpers::class) is the intended way to widen the set but currently does not rescue this case: SourceCode.loadCharStream derives the source path from the class FQN (dev/kensa/example/Helpers.kt), so when the object/class lives in a differently-named file its source isn't found, existsFor returns false, and findAllRelatedClasses drops it (Reflect.kt:73,76).
Fix direction
- Preferred: let classification consult the captured-invocation set (works for any declaration location, no
@Sources needed).
- Or: discover
@RenderedValue methods from @Sources classes reflectively, without gating that discovery on source availability.
Only member @RenderedValue functions/extensions are currently tested.
Symptom
A
@RenderedValuefunction declared outside the test class — an extension function in anobject, or a top-level function — renders the call words in the report sentence instead of being replaced by the function's return value. No exception is thrown. A member function/extension declared in the test class works fine.Repro
object Helpers { @RenderedValue fun KensaTest.foo(p: String) = "x-$p" }, usedwith(Helpers) { given(somethingWith(foo("a"))) }. Sentence renderssomething with foo ainstead ofsomething with x-a.Root cause
The compiler plugin captures the value for
@RenderedValuefunctions regardless of where they're declared, but the parser only classifies a call as@RenderedValueif the function is found by reflectingfindAllRelatedClasses→MethodParser.prepareMethods()(core/.../parse/MethodParser.kt:158,84). That set is the test class +@Sourcesclasses + super/interfaces, gated bysourceCode.existsFor. An externally-declared function isn't in it, so no rendered-value token is emitted, the captured value is never looked up, and the call renders as prose.@Sources(Helpers::class)is the intended way to widen the set but currently does not rescue this case:SourceCode.loadCharStreamderives the source path from the class FQN (dev/kensa/example/Helpers.kt), so when the object/class lives in a differently-named file its source isn't found,existsForreturns false, andfindAllRelatedClassesdrops it (Reflect.kt:73,76).Fix direction
@Sourcesneeded).@RenderedValuemethods from@Sourcesclasses reflectively, without gating that discovery on source availability.Only member
@RenderedValuefunctions/extensions are currently tested.