Skip to content

fix: execute example module tests via surefire + junit-jupiter-engine - #297

Merged
AndreasIgel merged 1 commit into
java-helpers:mainfrom
igel-devin-ai:devin/example-junit-fix
Sep 22, 2026
Merged

AndreasIgel merged 1 commit into
java-helpers:mainfrom
igel-devin-ai:devin/example-junit-fix

Conversation

@igel-devin-ai

Copy link
Copy Markdown
Collaborator

Summary

The example module declared test sources but never executed them: mvn test ran 0 tests because the module only depended on junit-jupiter (the API artifact) and had no Surefire plugin configured.

  • Add junit-jupiter-engine test dependency so JUnit Platform has a discoverable engine
  • Configure maven-surefire-plugin (${plugin.maven.surefire.version} = 3.6.0) for the module

After this change mvn -pl example test executes all 6 test classes (28+ assertions, 0 failures).

Split out of #296 per review feedback.

Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@AndreasIgel
AndreasIgel merged commit 5cc3c14 into java-helpers:main Sep 22, 2026
6 of 7 checks passed
devin-ai-integration Bot added a commit to igel-devin-ai/simple-builders-devin-fork that referenced this pull request Sep 25, 2026
- branch predated java-helpers#297 and its pom revert dropped the merged surefire /
  junit-jupiter-engine setup; pom restored to upstream so the example
  tests keep running
- javadoc: state explicitly that @SimpleBuilderFor is not @inherited

Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
AndreasIgel pushed a commit that referenced this pull request Sep 30, 2026
…#293) (#296)

* feat: add @SimpleBuilderFor for generating builders of external types (#293)

Introduce @SimpleBuilderFor on a holder class to generate builders for
types that cannot carry @SimpleBuilder themselves (e.g. third-party
library classes). The builders are generated in the holder's package,
configured via the annotation's options attribute and compiler options.

- New @SimpleBuilderFor annotation in core with Class<?>[] value and
  optional SimpleBuilder.Options options
- BuilderProcessor expands holders into generation targets; builder
  name collisions and @Ignore4BuilderGeneration targets are skipped
  with warnings on the holder
- Explicitly declared types always get a builder, even outside
  builderGenerationPackages (contradictory config warns)
- Builders generated in the same round are now trusted and exempt
  from builderUsagePackages - a self-generated builder is always used
- Member selection (constructors, setters, getters) now respects
  member accessibility from the generated builder's package, so
  generated code only calls members it may legally call
- Clear compile-time diagnostics when no accessible constructor or
  no accessible target type exists
- Jackson module defaults to the generated builder's package
- Example module: holder + external type + test; also enable surefire
  so the module's tests actually execute (they silently ran 0 before)
- Tests: SimpleBuilderForTest with 12 cases; updated scope tests for
  the trusted-builder semantics and the new round-start log line

* refactor: address review - split round-start log lines, derive builder package from reporting element, tighten docs

* refactor: fix sonar findings - dedupe message literal, split loop exits, concrete map types

* refactor: extract per-element planning to reduce cognitive complexity

* refactor: move conditional inside getPackageName call (sonar S9358)

* feat: allow @SimpleBuilderFor on package-info.java

* fix: keep builderUsagePackages filter ahead of generated-builder lookup

Generated-in-round builders must honor the usage scope like any other
candidate: restoring the original resolve() ordering — usage-scope check
first, then the registered-builder lookup. The Map-based registration
(registerGeneratedBuilders) stays, since @SimpleBuilderFor targets need
their builder names resolved in non-default packages.

* refactor: address review - package-info examples, explicit declaration wins, API cleanup

- Example + docs now declare @SimpleBuilderFor on package-info.java
  (holder class renamed to ExternalBuildersProvider in javadoc examples)
- @Ignore4BuilderGeneration on an explicitly listed target no longer
  suppresses generation: the external type's own annotations are not
  consulted; docs and test updated accordingly
- Round-start logging counts both element kinds identically; the
  'nothing found' message only appears when both are empty
- resolveExternalConfiguration(Element) locates the annotation mirror
  itself; the unreachable orElseThrow guard is dropped
- BuilderScopeResolver offers a single
  registerGeneratedBuilders(Map<TypeName,TypeName>) entry point
- builderPackageOf always returns a concrete package (the reporting
  element's package), so the builder-package slot in ProcessingContext
  never carries a null sentinel; getBuilderPackageName/
  isMemberAccessibleFromBuilderPackage simplified

* refactor: TypeName returns and drop redundant empty-round log line

- builderTypeName now returns TypeName instead of a qualified-name String;
  plannedBuilderNames is Set<TypeName> and the direct-target call site
  passes the type's own package (no null sentinel)
- drop 'No elements to process.' — the unconditional 'Found N ...' counts
  already report empty rounds

* refactor: group per-target state into ProcessingTarget record

Introduce ProcessingTarget (configuration + builderPackage) as the
documented holder for per-target processing state. ProcessingContext now
carries a single field instead of two loosely related ones, set once via
initProcessingTarget before extraction. The record's javadoc explains
why the builder package is captured explicitly (not derivable for
@SimpleBuilderFor targets).

* refactor: move generated-builder registrations into GeneratedBuilders holder

The target->builder-name mapping now lives in a dedicated GeneratedBuilders
registry (analysis package) with add/find/clear helpers and javadoc
documenting why the builder TypeName is stored explicitly (holder-package
builders for @SimpleBuilderFor). BuilderScopeResolver owns it and exposes
it via generatedBuilders(); mutations clear the resolution cache through
an onChange callback.

* refactor: review follow-ups on naming, attribute reading, and registry API

- renames: planGenerationOfAnnotatedElement, planGenerationOfTypeByHolder,
  alreadyPlannedBuilders (with comment explaining its conflict-detection
  role), results, resolveSimpleBuilderForConfiguration
- attribute reading moved to JavaLangAnalyser.findAnnotationAttribute;
  also tolerates a non-list 'value' attribute value
- GeneratedBuilders is now a pure holder keyed by TypeName
  (add/findBuilder/clear, add returns whether it was a new registration);
  BuilderScopeResolver gained registerGeneratedBuilder and
  resetGeneratedBuilders which also drop the resolution cache - replaces
  the onChange callback

* fix: address Sonar findings

- Objects.requireNonNull on holder/element at entry points - Sonar's
  null analysis flagged getSimpleName() derefs after the defensive
  null-check in findAnnotation propagated 'may be null' upstream
- lambdas replaced by context::isMemberAccessibleFromBuilderPackage
  method references
- dropped unused annotatedType parameter from isMethodRelevantForBuilder

* refactor: follow-up on review comments

- rename targets to results in extractExternalTargetTypes
- drop the non-list 'value' tolerance - javac always delivers Class<?>[]
  attributes as a list, single-value declarations included
- rename to resolveHolderConfiguration - 'For' in the name was misleading

* refactor: address remaining review comments

- warn when the 'value' attribute of @SimpleBuilderFor cannot be read,
  instead of returning silently
- javadoc on options(): spell out the UNSET default resolution
  (compiler argument, then built-in default per Options member)

* docs: link CONFIGURATION.md sections from javadoc

- SimpleBuilderFor: link 'Generating Builders for External Types' and
  'Compiler Options' sections
- JacksonAnnotationEnhancer: fix stale CONFIGURATION.md link (file moved
  to docs/, repo moved to java-helpers)

* fix: rebase onto upstream main and restore example test harness

- branch predated #297 and its pom revert dropped the merged surefire /
  junit-jupiter-engine setup; pom restored to upstream so the example
  tests keep running
- javadoc: state explicitly that @SimpleBuilderFor is not @inherited

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants