aglinxinyuan opened a new issue, #7862:
URL: https://github.com/apache/texera/issues/7862
### Task Summary
`common/pybuilder/src/main/scala/org/apache/texera/amber/pybuilder/EncodableInspector.scala`
is the largest free coverage gap in the repo — 50.0%, with 8 missed and 21
partial of 58 lines, and only 67 of 140 branch arms covered.
It is a macro-support class: every method takes `c.universe` types, so
nothing can be called from a plain unit test. Coverage exists only because the
spec drives macro expansion through a runtime `scala.tools.reflect.ToolBox`,
which loads the sbt-jacoco-instrumented copy. Any new test has to go through
that same door.
Traps worth knowing, because most of the 21 partials are not winnable and
the ones that are need a specific trick:
1. **`pyb"..."` can never be `tb.eval`'d.** It expands to the
`private[amber] PythonTemplateBuilder.fromInterpolated`, which the ToolBox's
synthetic `__wrapper` package cannot access — which is why the existing 12
tests can only assert on compile-error text. A test-side probe macro is what
turns those string proxies into direct assertions on the classifier's output.
2. **Corollary: do not delete or rewrite the existing `pyb`-based tests.** A
`PythonTemplateBuilder`-typed argument cannot be constructed inside a ToolBox
snippet at all (`val inner = pyb"abc"; probe(inner)` gives a `ToolBoxError`),
so the existing nested-builder test is the *only* thing covering the
`isPythonTemplateBuilderArg == true` arm. Add alongside them.
3. **Scala's `!=` on references compiles to a three-branch null-safe
equals**, and every such chain here sits behind an explicit `x != null` guard,
so the lhs-null and rhs-null arms are unreachable. That one fact is why nine of
the partial lines are permanently partial no matter what is tested.
4. **The `ExistentialType` arm is dead.** scalac never hands the inspector
one: `List[_]` and `List[T] forSome {type T}` both arrive as `TypeRef(List,
[Any])`, and even a hand-built `c.internal.existentialType` is stripped by the
`dealias.widen` at the top of the loop.
5. **`MethodSymbol <: TermSymbol`**, so `safeAccessed`'s second case can
never fire — anything that is a `MethodSymbol` and an accessor already matched
case 1.
6. **The lambda-body rule cuts against you here.** JaCoCo's
`SyntheticFilter` drops all six `$anonfun$typeHasEncodableString$*` methods, so
the eta-expanded bodies are worth zero. The lifted local `def loop` survives as
`loop$1` and *is* counted, which is the only reason lines 79-95 are trackable.
Confirm with `javap -p` rather than assuming either way — this differs between
files in this repo.
A safety defect is visible while working here and should be documented
rather than pinned: `@EncodableStringAnnotation` on a **trait** val is silently
ignored, because `safeAccessed` unconditionally hops accessor to `accessed`,
which is `NoSymbol` for a trait getter — and the annotation lives on the
getter, since a trait has no backing field.
### Task Type
- [ ] Refactor / Cleanup
- [ ] DevOps / Deployment / CI
- [x] Testing / QA
- [ ] Documentation
- [ ] Performance
- [ ] Other
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]