Skip to content

Add validate() probe to ValidatingBuilder#316

Merged
alexander-yevsyukov merged 16 commits into
masterfrom
claude/wonderful-hellman-f8ec72
Jul 6, 2026
Merged

Add validate() probe to ValidatingBuilder#316
alexander-yevsyukov merged 16 commits into
masterfrom
claude/wonderful-hellman-f8ec72

Conversation

@alexander-yevsyukov

@alexander-yevsyukov alexander-yevsyukov commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator

What

Adds a default probe method to io.spine.validation.ValidatingBuilder:

default List<ConstraintViolation> validate()

It builds the current content via buildPartial() and, when the result is a
ValidatableMessage, unwraps its Optional<ValidationError> into the returned
list; a message that does not support validation is treated as valid. An empty
list means the content is valid.

The method is a non-throwing, non-mutating probe of the builder's current
content — including content that is already invalid. It sits between the two
existing options:

Method Validates? On invalid content
build() yes throws ValidationException
buildPartial() no returns a possibly-invalid message
validate() (new) yes returns the violations, throws nothing

Why

Complements the tryAlter {} entity extension designed in core-jvm
PR #1642
(de-event-sourcing Phase A), which needs to check a builder's content for
validity in place without either throwing or handing back a message. Implements
the D9 amendment of ADR 0001. Requested by @armiol in
SpineEventEngine/core-jvm#1642 (comment)

How it works

The generated ValidatableMessage.validate(parentPath, parentName) already
folds in ValidatorRegistry.validate(this), so buildPartial() +
ValidatableMessage.validate() checks exactly what generated build() checks —
no more, no less. It deliberately does not route through
Validate.violationsOf(), which adds Any-unpacking logic irrelevant to a
builder.

Tests

  • ValidatingBuilderSpec (jvm-runtime) — unit specs with minimal stubs
    covering every branch of validate(): a valid ValidatableMessage → empty
    list; an invalid one → violations returned without throwing; a product that
    does not implement ValidatableMessage → treated as valid.
  • ValidatingBuilderSpec (tests/validating) — the same valid/invalid paths
    against the real generated InterestRate builder (a (min) constraint),
    plus a check that probing leaves the builder content intact.
  • JavaMessageSmokeTest (tests/validating) — smoke coverage for validate()
    on the generated CardNumber builder.

Notes for reviewers

  • Version bumped 2.0.0-SNAPSHOT.446 → .447; docs/dependencies/* are the
    regenerated reports (version/timestamp churn only).
  • The developer-docs page runtime-library.md, which mirrors the interface
    body, is updated to include the new method.
  • docs/content/** was touched but no links were added or changed, so
    check-links has no bearing on this diff.

Bundled maintenance

Beyond the validate() change, this branch also carries routine SDK
maintenance the author chose to keep together rather than split out:

  • Toolchain migration — latest Base (2.0.0-SNAPSHOT.391) and CoreJvm
    compiler (2.0.0-SNAPSHOT.080), Protobuf 4.35.0, Gradle wrapper 9.6.1.
  • Config sync.agents/ restructure, refreshed dependency reports, and
    two new CI workflows (revalidate-versions, secret-scan).
  • Example alignment — the hello-validation docs submodule
    (docs/_examples) is advanced to force Protobuf 4.35.0, matching the
    migrated compiler's gencode; this fixes the Build embedded code check.

Verification: full ./gradlew build passes; :docs:buildExamples
(embedded-code) passes after the submodule alignment; the version-increment
guard and remaining CI checks are green.

🤖 Generated with Claude Code

alexander-yevsyukov and others added 3 commits July 5, 2026 22:08
Add a default `validate()` method to `io.spine.validation.ValidatingBuilder`
that probes the builder's current content and returns any constraint
violations without throwing or mutating the builder. It builds the content
via `buildPartial()` and, when the result is a `ValidatableMessage`, unwraps
its `ValidationError` into the returned list; a message that does not support
validation is treated as valid. An empty list means the content is valid.

This gives callers a non-throwing counterpart to `build()` (which throws
`ValidationException`) that, unlike `buildPartial()`, does not skip validation
or hand back a possibly invalid message. It complements the `tryAlter {}`
entity extension from core-jvm PR #1642 (de-event-sourcing Phase A) and
implements the D9 amendment of ADR 0001. Requested by @armiol:
SpineEventEngine/core-jvm#1642 (comment)

Covered by stub-based unit tests (`ValidatingBuilderSpec`) and integration
tests against generated code (`JavaMessageSmokeTest`). The developer-docs
snippet mirroring the interface is updated to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 5, 2026 21:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a non-throwing validation probe to ValidatingBuilder so callers can check builder content validity (including already-invalid content) without throwing and without returning a potentially invalid message instance.

Changes:

  • Added ValidatingBuilder#validate() default method returning constraint violations (empty list = valid).
  • Added unit + integration tests covering valid/invalid cases and non-mutating behavior.
  • Updated runtime-library docs and bumped snapshot version / regenerated dependency reports.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
jvm-runtime/src/main/java/io/spine/validation/ValidatingBuilder.java Adds validate() API and Javadoc explaining non-throwing probe semantics.
jvm-runtime/src/test/kotlin/io/spine/validation/ValidatingBuilderSpec.kt New stub-based unit specs for validate() behavior and non-mutation.
tests/validating/src/test/kotlin/io/spine/test/JavaMessageSmokeTest.kt Adds integration coverage for validate() on generated Java builder.
docs/content/docs/validation/developer/runtime-library.md Updates developer docs page that mirrors the runtime contracts to include validate().
version.gradle.kts Bumps published snapshot version.
docs/dependencies/pom.xml Regenerated dependency report metadata version.
docs/dependencies/dependencies.md Regenerated dependency report content/version/timestamp churn.
.agents/tasks/validating-builder-validate.md Task plan / implementation notes (not part of published API).

Comment thread jvm-runtime/src/main/java/io/spine/validation/ValidatingBuilder.java Outdated
@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 12.35%. Comparing base (dd8c421) to head (17e536f).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master     #316      +/-   ##
============================================
+ Coverage     12.09%   12.35%   +0.25%     
- Complexity       82       84       +2     
============================================
  Files            82       82              
  Lines          2034     2040       +6     
  Branches        160      161       +1     
============================================
+ Hits            246      252       +6     
  Misses         1786     1786              
  Partials          2        2              
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

alexander-yevsyukov and others added 5 commits July 5, 2026 23:24
Address review feedback on PR #316: the interface-level Javadoc said
`validate()` checks validity "without building the message", but the
method calls `buildPartial()`, which does construct a message instance
(the caller just never receives it). Reword to "without obtaining the
built message". Also align abbreviation punctuation (`i.e.,`) with the
`e.g.,` used earlier in the same Javadoc block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 5, 2026 22:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 260 out of 267 changed files in this pull request and generated 2 comments.

Comment thread docs/project.md Outdated
Comment thread version.gradle.kts
Rewrite `ValidatingBuilderSpec` to probe the new `ValidatingBuilder.validate()`
method through a real generated validating type instead of hand-written
`AbstractMessage`/`Builder` stubs.

The spec now uses the generated `InterestRate` message (a single `float percent`
field constrained with `(min) > 0.0`) to cover the meaningful paths: valid
content yields no violations, invalid content returns the violations without
throwing, and probing leaves the builder content intact.

Because a generated `ValidatingBuilder` always builds a `ValidatableMessage`,
real generated types cannot reach the "message does not support validation"
fallback branch; that branch is defensive and no longer has a dedicated stub
test.

The spec moves to the `tests:validating` module: `jvm-runtime` depends on
`spine-base` and does not apply the `io.spine.validation` code generator, so it
cannot produce a generated `ValidatableMessage`/`ValidatingBuilder` to test
against — only a plugin-applied module such as `tests:validating` can.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@alexander-yevsyukov alexander-yevsyukov self-assigned this Jul 5, 2026
@alexander-yevsyukov alexander-yevsyukov moved this to 🏗 In progress in v2.0 Jul 5, 2026
Advance the `docs/_examples` submodule to the Protobuf runtime alignment
for the migrated CoreJvm compiler. Fixes the `Build embedded code` check,
where the generated `BankCard` failed to initialize because of a gencode
`4.35.0` / runtime `4.34.1` mismatch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 5, 2026 23:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 261 out of 268 changed files in this pull request and generated 2 comments.

`ValidatingBuilder.validate()` returns an empty list when `buildPartial()`
yields a message that does not implement `ValidatableMessage`. Real generated
builders always produce a `ValidatableMessage`, so this branch cannot be
reached from the `tests/validating` spec; exercise it here with a minimal
builder that delegates to a plain `Empty` product.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@alexander-yevsyukov alexander-yevsyukov moved this from 🏗 In progress to In Review in v2.0 Jul 6, 2026
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 6, 2026 00:48
@alexander-yevsyukov alexander-yevsyukov moved this from In Review to 🏗 In progress in v2.0 Jul 6, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 262 out of 269 changed files in this pull request and generated 3 comments.

Comment thread docs/content/docs/validation/developer/runtime-library.md Outdated
alexander-yevsyukov and others added 3 commits July 6, 2026 01:57
Extend the `jvm-runtime` unit spec so the `validate()` default method is
exercised for all three products it can encounter: a `ValidatableMessage`
that is valid, one that reports violations, and a message that does not
support validation. The builder stub now takes an arbitrary product, and a
minimal `ValidatableMessage` stub reports the configured violations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- `runtime-library.md`: state that `validate()` treats a product that does
  not implement `ValidatableMessage` as valid, matching the interface Javadoc
  and the unit tests.
- `ValidateUtilitySpec.kt`: bump the copyright header to 2026 for a file
  edited on this branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 6, 2026 01:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 262 out of 269 changed files in this pull request and generated 1 comment.

Comment thread jvm-runtime/src/main/java/io/spine/validation/ValidatingBuilder.java Outdated
Replace restrictive `which` clauses (no preceding comma) with `that` in the
interface Javadoc, per the repo grammar convention.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@alexander-yevsyukov alexander-yevsyukov moved this from 🏗 In progress to In Review in v2.0 Jul 6, 2026
@alexander-yevsyukov alexander-yevsyukov merged commit 9c12903 into master Jul 6, 2026
12 checks passed
@alexander-yevsyukov alexander-yevsyukov deleted the claude/wonderful-hellman-f8ec72 branch July 6, 2026 09:50
@github-project-automation github-project-automation Bot moved this from In Review to ✅ Done in v2.0 Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

3 participants