Skip to content

Use Locale.ROOT with String.format which does or could render numbers#2320

Open
Vampire wants to merge 1 commit intomasterfrom
vampire/fix-number-rendering
Open

Use Locale.ROOT with String.format which does or could render numbers#2320
Vampire wants to merge 1 commit intomasterfrom
vampire/fix-number-rendering

Conversation

@Vampire
Copy link
Member

@Vampire Vampire commented Mar 13, 2026

Summary by CodeRabbit

  • Chores
    • Standardized string formatting to be locale-independent across the framework, ensuring consistent user-facing messages (errors, timeouts, iteration and mock names, snapshots, diagnostics, and logs) regardless of the system locale.

Copy link
Member Author

Vampire commented Mar 13, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8967b05a-fe56-44fa-bf74-f3391df2c4c6

📥 Commits

Reviewing files that changed from the base of the PR and between d166ea1 and ccbd6f6.

📒 Files selected for processing (30)
  • spock-core/src/main/java/org/spockframework/compiler/ErrorReporter.java
  • spock-core/src/main/java/org/spockframework/compiler/InvalidSpecCompileException.java
  • spock-core/src/main/java/org/spockframework/compiler/SpecRewriter.java
  • spock-core/src/main/java/org/spockframework/compiler/WhereBlockRewriter.java
  • spock-core/src/main/java/org/spockframework/mock/runtime/ByteBuddyMockFactory.java
  • spock-core/src/main/java/org/spockframework/mock/runtime/MockInteraction.java
  • spock-core/src/main/java/org/spockframework/runtime/DataVariablesIterationNameProvider.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedSetEqualityComparisonRenderer.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedStringComparisonRenderer.java
  • spock-core/src/main/java/org/spockframework/runtime/InvalidSpecException.java
  • spock-core/src/main/java/org/spockframework/runtime/SafeIterationNameProvider.java
  • spock-core/src/main/java/org/spockframework/runtime/SpockExecutionException.java
  • spock-core/src/main/java/org/spockframework/runtime/SpockRuntime.java
  • spock-core/src/main/java/org/spockframework/runtime/extension/ExtensionException.java
  • spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java
  • spock-core/src/main/java/org/spockframework/runtime/model/TextPosition.java
  • spock-core/src/main/java/org/spockframework/util/Assert.java
  • spock-core/src/main/java/org/spockframework/util/InternalSpockError.java
  • spock-core/src/main/java/org/spockframework/util/IoUtil.java
  • spock-core/src/main/java/org/spockframework/util/VersionNumber.java
  • spock-core/src/main/java/spock/config/ConfigurationException.java
  • spock-core/src/main/java/spock/lang/Snapshotter.java
  • spock-core/src/main/java/spock/mock/AutoAttachExtension.java
  • spock-core/src/main/java/spock/util/concurrent/AsyncConditions.java
  • spock-core/src/main/java/spock/util/concurrent/BlockingVariable.java
  • spock-core/src/main/java/spock/util/concurrent/PollingConditions.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/DelegatingInterceptor.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockDefinition.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockMockPostprocessor.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpyDefinition.java
✅ Files skipped from review due to trivial changes (20)
  • spock-core/src/main/java/org/spockframework/util/VersionNumber.java
  • spock-core/src/main/java/org/spockframework/util/IoUtil.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedSetEqualityComparisonRenderer.java
  • spock-core/src/main/java/org/spockframework/runtime/SpockExecutionException.java
  • spock-core/src/main/java/org/spockframework/compiler/InvalidSpecCompileException.java
  • spock-core/src/main/java/org/spockframework/util/InternalSpockError.java
  • spock-core/src/main/java/spock/util/concurrent/AsyncConditions.java
  • spock-core/src/main/java/org/spockframework/runtime/extension/ExtensionException.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/DelegatingInterceptor.java
  • spock-core/src/main/java/org/spockframework/runtime/model/TextPosition.java
  • spock-core/src/main/java/org/spockframework/runtime/SafeIterationNameProvider.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedStringComparisonRenderer.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpyDefinition.java
  • spock-core/src/main/java/org/spockframework/runtime/DataVariablesIterationNameProvider.java
  • spock-core/src/main/java/org/spockframework/runtime/SpockRuntime.java
  • spock-core/src/main/java/spock/mock/AutoAttachExtension.java
  • spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java
  • spock-core/src/main/java/org/spockframework/compiler/ErrorReporter.java
  • spock-core/src/main/java/spock/config/ConfigurationException.java
  • spock-core/src/main/java/org/spockframework/mock/runtime/MockInteraction.java
🚧 Files skipped from review as they are similar to previous changes (7)
  • spock-core/src/main/java/spock/util/concurrent/BlockingVariable.java
  • spock-core/src/main/java/org/spockframework/runtime/InvalidSpecException.java
  • spock-core/src/main/java/org/spockframework/compiler/WhereBlockRewriter.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockMockPostprocessor.java
  • spock-core/src/main/java/org/spockframework/util/Assert.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockDefinition.java
  • spock-core/src/main/java/spock/lang/Snapshotter.java

📝 Walkthrough

Walkthrough

This PR standardizes string formatting to use Locale.ROOT (locale-independent) across many String.format/printf call sites, with a few deliberate specifier adjustments; no public APIs or control-flow semantics were changed.

Changes

Cohort / File(s) Summary
Compiler / Spec rewriting
spock-core/src/main/java/org/spockframework/compiler/ErrorReporter.java, spock-core/src/main/java/org/spockframework/compiler/InvalidSpecCompileException.java, spock-core/src/main/java/org/spockframework/compiler/SpecRewriter.java, spock-core/src/main/java/org/spockframework/compiler/WhereBlockRewriter.java
Replaced String.format usages with Locale.ROOT for compiler error messages, internal feature naming, and data-table validation; one message tightened a numeric specifier.
Mocking / Interaction
spock-core/src/main/java/org/spockframework/mock/runtime/ByteBuddyMockFactory.java, spock-core/src/main/java/org/spockframework/mock/runtime/MockInteraction.java
Mock class name generation and MockInteraction.toString now pass Locale.ROOT to formatting for deterministic output.
Iteration & Naming Providers
spock-core/src/main/java/org/spockframework/runtime/DataVariablesIterationNameProvider.java, spock-core/src/main/java/org/spockframework/runtime/SafeIterationNameProvider.java
Iteration index and fallback name formatting switched to Locale.ROOT.
Comparison Renderers
spock-core/src/main/java/org/spockframework/runtime/FailedSetEqualityComparisonRenderer.java, spock-core/src/main/java/org/spockframework/runtime/FailedStringComparisonRenderer.java
Renderers updated to use Locale.ROOT for stable numeric/edit-distance formatting.
Exceptions & Runtime
spock-core/src/main/java/org/spockframework/runtime/InvalidSpecException.java, spock-core/src/main/java/org/spockframework/runtime/SpockExecutionException.java, spock-core/src/main/java/org/spockframework/runtime/extension/ExtensionException.java, spock-core/src/main/java/org/spockframework/runtime/SpockRuntime.java, spock/config/ConfigurationException.java
Exception message construction and withArgs-like methods now format via Locale.ROOT.
Utilities & Model
spock-core/src/main/java/org/spockframework/util/Assert.java, spock-core/src/main/java/org/spockframework/util/InternalSpockError.java, spock-core/src/main/java/org/spockframework/util/IoUtil.java, spock-core/src/main/java/org/spockframework/util/VersionNumber.java, spock-core/src/main/java/org/spockframework/runtime/model/TextPosition.java
Utility toString and error messages switched to Locale.ROOT; IoUtil.checkSameSize message made locale-independent.
Timeouts & Extensions
spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java, spock-core/src/main/java/org/spockframework/mock/AutoAttachExtension.java
Timeout messages, logs, and AutoAttach field/line messages now use Locale.ROOT; AutoAttach adjusted a format specifier from %s to %d for line numbers.
Concurrency utils
spock-core/src/main/java/spock/util/concurrent/AsyncConditions.java, spock-core/src/main/java/spock/util/concurrent/BlockingVariable.java, spock-core/src/main/java/spock/util/concurrent/PollingConditions.java
Await/timeout messages updated to use Locale.ROOT; PollingConditions changed Locale.ENGLISH→Locale.ROOT in one place and removed an explicit locale in another.
Snapshot / Special cases
spock-core/src/main/java/spock/lang/Snapshotter.java
Validation error message now uses Locale.ROOT; snapshot filename String.format calls were left using platform default per change.
Spring mock integration
spock-spring/src/main/java/org/spockframework/spring/mock/DelegatingInterceptor.java, spock-spring/src/main/java/org/spockframework/spring/mock/SpockDefinition.java, spock-spring/src/main/java/org/spockframework/spring/mock/SpockMockPostprocessor.java, spock-spring/src/main/java/org/spockframework/spring/mock/SpyDefinition.java
Validation and mock-description messages updated to use Locale.ROOT for deterministic formatting.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • AndreasTu

Poem

🐰 I hopped through code with careful cheer,
Replacing locales far and near,
Locale.ROOT now lights the way,
So messages look the same each day —
🥕✨ uniform across the sphere

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.66% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main purpose of the changeset: using Locale.ROOT with String.format for number rendering across multiple files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch vampire/fix-number-rendering

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link

greptile-apps bot commented Mar 13, 2026

Greptile Summary

This PR systematically adds Locale.ROOT to every String.format call in spock-core and spock-spring that renders a number (integer or floating-point), preventing locale-sensitive decimal/grouping separators from appearing in machine-generated messages (e.g., error text, version strings, iteration names, timeout messages) when the JVM is running under a non-English locale such as Turkish, Arabic, or German.

Key aspects of the change:

  • Locale.ROOT additions: All String.format calls using %d, %f, %1.2f, or similar numeric specifiers now explicitly pass Locale.ROOT, making output locale-independent.
  • Locale.ENGLISHLocale.ROOT in PollingConditions.java: Locale.ROOT is more appropriate than Locale.ENGLISH for machine-generated messages; both produce the same numeric output in practice.
  • Locale.ROOT removals in Snapshotter.java (lines 299, 301): Two format strings that use only %s had Locale.ROOT removed — locale has no effect on %s formatting, so this is a correct cleanup.
  • Format specifier corrections in AutoAttachExtension.java and WhereBlockRewriter.java: %s changed to %d when formatting int values (field.getLine(), row.size()), which is more type-appropriate and enables the locale-aware path.
  • All Locale imports are correctly handled — files with java.util.* wildcard imports needed no new explicit import statement; files with targeted imports received an explicit import java.util.Locale; line.

Confidence Score: 5/5

  • This PR is safe to merge — all changes are mechanical, well-scoped, and verified to be correct.
  • Every change follows a single, clear rule: add Locale.ROOT when numbers are formatted, omit it when only strings are substituted. The direction of changes in Snapshotter.java (removing a previously-unnecessary Locale.ROOT) and the %s→%d specifier corrections in AutoAttachExtension.java and WhereBlockRewriter.java are also correct. All Locale imports are properly resolved via existing wildcard imports or newly-added explicit ones. No behavioral regressions are possible because Locale.ROOT and the default locale produce identical output for the integer and fixed-point float format strings used here on any English-based locale, while correctly differing only on non-English locales (which is exactly the fix being applied).
  • No files require special attention.

Important Files Changed

Filename Overview
spock-core/src/main/java/org/spockframework/compiler/WhereBlockRewriter.java Adds Locale.ROOT and corrects format specifiers from %s to %d for row sizes in a compile error message; correct change.
spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java Adds Locale.ROOT to two String.format calls: one rendering timeout seconds as a float and one building a thread section header string with a thread ID integer; correct changes.
spock-core/src/main/java/spock/lang/Snapshotter.java Adds Locale.ROOT to the snapshotId-length error message (%d), while correctly removing Locale.ROOT from two format calls that use only %s specifiers (locale-independent); the Locale import is still retained for other usages in the file.
spock-core/src/main/java/spock/mock/AutoAttachExtension.java Adds Locale.ROOT and correctly changes %s to %d for field.getLine() (an int) in two exception messages; functionally equivalent but type-appropriate improvement.
spock-core/src/main/java/spock/util/concurrent/PollingConditions.java Replaces Locale.ENGLISH with Locale.ROOT in the first format call (rendering float/int), and removes locale from the second format call that only uses %s — both changes are correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["String.format call site"] --> B{Format string\ncontains numbers?}
    B -- "Yes (%d, %f, %e, etc.)" --> C["Use String.format(Locale.ROOT, ...)"]
    B -- "No (only %s, %b, %c)" --> D["Use String.format(...) — no locale needed"]
    C --> E[Consistent output\nregardless of JVM locale]
    D --> F[Locale-independent\nstring substitution]
    E --> G["Machine messages, error text,\nversion strings, debug output"]
    F --> G
    style C fill:#2d8a4e,color:#fff
    style D fill:#2d6ca8,color:#fff
    style E fill:#1a5c33,color:#fff
    style F fill:#1a4a7a,color:#fff
Loading

Last reviewed commit: f03bda4

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java (2)

136-142: Inconsistent locale handling with printf calls.

This method formats numbers with %1.2f but doesn't use Locale.ROOT, unlike the updated String.format call at line 126. For consistency with the PR's objective, consider updating these printf calls.

♻️ Suggested fix for consistency
   private void logUnsuccessfulInterrupt(String methodName, long now, long timeoutAt, long waitMillis, int unsuccessfulAttempts) {
-    System.err.printf(
+    System.err.printf(Locale.ROOT,
       "[spock.lang.Timeout] Method '%s' has not stopped after timing out %1.2f seconds ago - interrupting. Next try in %1.2f seconds.\n%n",
       methodName,
       TimeUtil.toSeconds(Duration.ofNanos(now - timeoutAt)),
       waitMillis / 1000d
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java`
around lines 136 - 142, The System.err.printf call in logUnsuccessfulInterrupt
formats floats without a fixed locale; update the call to use Locale.ROOT
(similar to the String.format change) so numeric formatting is consistent across
locales—locate the logUnsuccessfulInterrupt method and replace the
System.err.printf invocation with a variant that supplies Locale.ROOT while
preserving the same format string and argument order.

154-160: Inconsistent locale handling with printf call.

Same issue as logUnsuccessfulInterrupt - this method formats %1.2f without Locale.ROOT.

♻️ Suggested fix for consistency
   private void logMethodTimeout(String methodName, double timeoutSeconds) {
-    System.err.printf(
+    System.err.printf(Locale.ROOT,
       "[spock.lang.Timeout] Method '%s' timed out after %1.2f seconds.%n",
       methodName,
       timeoutSeconds
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java`
around lines 154 - 160, logMethodTimeout uses System.err.printf with a
floating-point format without specifying Locale, causing locale-dependent
formatting; update logMethodTimeout to call System.err.printf with Locale.ROOT
as the first argument (mirroring logUnsuccessfulInterrupt) so the %1.2f is
always formatted consistently, and ensure java.util.Locale is available/imported
if needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@spock-core/src/main/java/spock/util/concurrent/PollingConditions.java`:
- Around line 201-203: The code mixes locale-sensitive numeric formatting: some
numeric formats use Locale.ROOT (e.g., the String.format call that formats
elapsedTime/attempts) while other printf/String.format usages still rely on the
default locale when formatting "%1.2f". Locate the printf/String.format calls
that format numbers with "%1.2f" (the ones that reference
elapsedTime/attempts-style values) and change them to use Locale.ROOT (e.g.,
String.format(Locale.ROOT, ...) or printf(Locale.ROOT, ...)) so all numeric
formatting in PollingConditions uses Locale.ROOT consistently.

---

Nitpick comments:
In
`@spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java`:
- Around line 136-142: The System.err.printf call in logUnsuccessfulInterrupt
formats floats without a fixed locale; update the call to use Locale.ROOT
(similar to the String.format change) so numeric formatting is consistent across
locales—locate the logUnsuccessfulInterrupt method and replace the
System.err.printf invocation with a variant that supplies Locale.ROOT while
preserving the same format string and argument order.
- Around line 154-160: logMethodTimeout uses System.err.printf with a
floating-point format without specifying Locale, causing locale-dependent
formatting; update logMethodTimeout to call System.err.printf with Locale.ROOT
as the first argument (mirroring logUnsuccessfulInterrupt) so the %1.2f is
always formatted consistently, and ensure java.util.Locale is available/imported
if needed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ec1fca92-9b83-4e75-8810-2aa66d783fb0

📥 Commits

Reviewing files that changed from the base of the PR and between 9c6342c and f03bda4.

📒 Files selected for processing (30)
  • spock-core/src/main/java/org/spockframework/compiler/ErrorReporter.java
  • spock-core/src/main/java/org/spockframework/compiler/InvalidSpecCompileException.java
  • spock-core/src/main/java/org/spockframework/compiler/SpecRewriter.java
  • spock-core/src/main/java/org/spockframework/compiler/WhereBlockRewriter.java
  • spock-core/src/main/java/org/spockframework/mock/runtime/ByteBuddyMockFactory.java
  • spock-core/src/main/java/org/spockframework/mock/runtime/MockInteraction.java
  • spock-core/src/main/java/org/spockframework/runtime/DataVariablesIterationNameProvider.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedSetEqualityComparisonRenderer.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedStringComparisonRenderer.java
  • spock-core/src/main/java/org/spockframework/runtime/InvalidSpecException.java
  • spock-core/src/main/java/org/spockframework/runtime/SafeIterationNameProvider.java
  • spock-core/src/main/java/org/spockframework/runtime/SpockExecutionException.java
  • spock-core/src/main/java/org/spockframework/runtime/SpockRuntime.java
  • spock-core/src/main/java/org/spockframework/runtime/extension/ExtensionException.java
  • spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java
  • spock-core/src/main/java/org/spockframework/runtime/model/TextPosition.java
  • spock-core/src/main/java/org/spockframework/util/Assert.java
  • spock-core/src/main/java/org/spockframework/util/InternalSpockError.java
  • spock-core/src/main/java/org/spockframework/util/IoUtil.java
  • spock-core/src/main/java/org/spockframework/util/VersionNumber.java
  • spock-core/src/main/java/spock/config/ConfigurationException.java
  • spock-core/src/main/java/spock/lang/Snapshotter.java
  • spock-core/src/main/java/spock/mock/AutoAttachExtension.java
  • spock-core/src/main/java/spock/util/concurrent/AsyncConditions.java
  • spock-core/src/main/java/spock/util/concurrent/BlockingVariable.java
  • spock-core/src/main/java/spock/util/concurrent/PollingConditions.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/DelegatingInterceptor.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockDefinition.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockMockPostprocessor.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpyDefinition.java

Comment on lines +201 to +203
String msg = String.format(Locale.ROOT, "Condition not satisfied after %1.2f seconds and %d attempts", elapsedTime / 1000d, attempts);
if (timeoutMessage != null) {
msg = String.format(Locale.ENGLISH, "%s: %s", msg, GroovyRuntimeUtil.invokeClosure(timeoutMessage, testException));
msg = String.format("%s: %s", msg, GroovyRuntimeUtil.invokeClosure(timeoutMessage, testException));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

LGTM on these lines, but inconsistent locale handling elsewhere in the file.

Lines 201-203 are correct: Locale.ROOT is properly used for the numeric formatting on line 201, and line 203 only uses %s specifiers.

However, the printf calls at lines 137-142 and 155-159 format numbers using %1.2f without Locale.ROOT, which is inconsistent with this PR's objective.

,

🔧 Suggested fixes for consistency

At lines 137-142:

-    System.err.printf(
-      "[spock.lang.Timeout] Method '%s' has not stopped after timing out %1.2f seconds ago - interrupting. Next try in %1.2f seconds.\n%n",
+    System.err.printf(Locale.ROOT,
+      "[spock.lang.Timeout] Method '%s' has not stopped after timing out %1.2f seconds ago - interrupting. Next try in %1.2f seconds.%n",
       methodName,

At lines 155-159:

-    System.err.printf(
-      "[spock.lang.Timeout] Method '%s' timed out after %1.2f seconds.%n",
+    System.err.printf(Locale.ROOT,
+      "[spock.lang.Timeout] Method '%s' timed out after %1.2f seconds.%n",
       methodName,

Note: The suggested fixes reference TimeoutInterceptor.java, not this file. Commenting here as this is the only changed segment.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spock-core/src/main/java/spock/util/concurrent/PollingConditions.java` around
lines 201 - 203, The code mixes locale-sensitive numeric formatting: some
numeric formats use Locale.ROOT (e.g., the String.format call that formats
elapsedTime/attempts) while other printf/String.format usages still rely on the
default locale when formatting "%1.2f". Locate the printf/String.format calls
that format numbers with "%1.2f" (the ones that reference
elapsedTime/attempts-style values) and change them to use Locale.ROOT (e.g.,
String.format(Locale.ROOT, ...) or printf(Locale.ROOT, ...)) so all numeric
formatting in PollingConditions uses Locale.ROOT consistently.

@codecov
Copy link

codecov bot commented Mar 13, 2026

Codecov Report

❌ Patch coverage is 73.17073% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.17%. Comparing base (8d380cc) to head (ccbd6f6).

Files with missing lines Patch % Lines
...rg/spockframework/spring/mock/SpockDefinition.java 0.00% 2 Missing ⚠️
.../org/spockframework/spring/mock/SpyDefinition.java 0.00% 2 Missing ⚠️
...ava/org/spockframework/compiler/ErrorReporter.java 50.00% 1 Missing ⚠️
...pockframework/runtime/SpockExecutionException.java 0.00% 1 Missing ⚠️
...org/spockframework/runtime/model/TextPosition.java 0.00% 1 Missing ⚠️
.../src/main/java/org/spockframework/util/Assert.java 50.00% 0 Missing and 1 partial ⚠️
...main/java/spock/config/ConfigurationException.java 50.00% 1 Missing ⚠️
...ckframework/spring/mock/DelegatingInterceptor.java 0.00% 1 Missing ⚠️
...kframework/spring/mock/SpockMockPostprocessor.java 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##             master    #2320      +/-   ##
============================================
+ Coverage     82.16%   82.17%   +0.01%     
- Complexity     4822     4823       +1     
============================================
  Files           472      472              
  Lines         15036    15036              
  Branches       1905     1905              
============================================
+ Hits          12354    12356       +2     
  Misses         1989     1989              
+ Partials        693      691       -2     
Files with missing lines Coverage Δ
...ramework/compiler/InvalidSpecCompileException.java 66.66% <100.00%> (ø)
...java/org/spockframework/compiler/SpecRewriter.java 94.17% <100.00%> (ø)
...rg/spockframework/compiler/WhereBlockRewriter.java 94.77% <100.00%> (ø)
...ckframework/mock/runtime/ByteBuddyMockFactory.java 91.66% <100.00%> (ø)
...g/spockframework/mock/runtime/MockInteraction.java 81.96% <100.00%> (ø)
...rk/runtime/DataVariablesIterationNameProvider.java 100.00% <100.00%> (ø)
...k/runtime/FailedSetEqualityComparisonRenderer.java 96.55% <100.00%> (ø)
...mework/runtime/FailedStringComparisonRenderer.java 94.87% <100.00%> (ø)
...g/spockframework/runtime/InvalidSpecException.java 100.00% <100.00%> (ø)
...ckframework/runtime/SafeIterationNameProvider.java 100.00% <100.00%> (ø)
... and 20 more

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Vampire Vampire force-pushed the vampire/fix-number-rendering branch from f03bda4 to 50f48e6 Compare March 13, 2026 16:00
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java`:
- Line 139: In TimeoutInterceptor.java (class TimeoutInterceptor), the format
string used when logging the timeout message includes both a literal "\n" and
"%n", causing double newlines; update the format string in the logging/format
call (the string starting with "[spock.lang.Timeout] Method '%s'...") to use a
single platform-specific line separator (prefer %n) and remove the redundant
"\n" so the message ends with only "%n".

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3807fb9a-fe8a-4524-b5b7-e599d74fea64

📥 Commits

Reviewing files that changed from the base of the PR and between f03bda4 and 50f48e6.

📒 Files selected for processing (30)
  • spock-core/src/main/java/org/spockframework/compiler/ErrorReporter.java
  • spock-core/src/main/java/org/spockframework/compiler/InvalidSpecCompileException.java
  • spock-core/src/main/java/org/spockframework/compiler/SpecRewriter.java
  • spock-core/src/main/java/org/spockframework/compiler/WhereBlockRewriter.java
  • spock-core/src/main/java/org/spockframework/mock/runtime/ByteBuddyMockFactory.java
  • spock-core/src/main/java/org/spockframework/mock/runtime/MockInteraction.java
  • spock-core/src/main/java/org/spockframework/runtime/DataVariablesIterationNameProvider.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedSetEqualityComparisonRenderer.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedStringComparisonRenderer.java
  • spock-core/src/main/java/org/spockframework/runtime/InvalidSpecException.java
  • spock-core/src/main/java/org/spockframework/runtime/SafeIterationNameProvider.java
  • spock-core/src/main/java/org/spockframework/runtime/SpockExecutionException.java
  • spock-core/src/main/java/org/spockframework/runtime/SpockRuntime.java
  • spock-core/src/main/java/org/spockframework/runtime/extension/ExtensionException.java
  • spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java
  • spock-core/src/main/java/org/spockframework/runtime/model/TextPosition.java
  • spock-core/src/main/java/org/spockframework/util/Assert.java
  • spock-core/src/main/java/org/spockframework/util/InternalSpockError.java
  • spock-core/src/main/java/org/spockframework/util/IoUtil.java
  • spock-core/src/main/java/org/spockframework/util/VersionNumber.java
  • spock-core/src/main/java/spock/config/ConfigurationException.java
  • spock-core/src/main/java/spock/lang/Snapshotter.java
  • spock-core/src/main/java/spock/mock/AutoAttachExtension.java
  • spock-core/src/main/java/spock/util/concurrent/AsyncConditions.java
  • spock-core/src/main/java/spock/util/concurrent/BlockingVariable.java
  • spock-core/src/main/java/spock/util/concurrent/PollingConditions.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/DelegatingInterceptor.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockDefinition.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockMockPostprocessor.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpyDefinition.java
🚧 Files skipped from review as they are similar to previous changes (18)
  • spock-core/src/main/java/org/spockframework/runtime/SpockRuntime.java
  • spock-core/src/main/java/spock/lang/Snapshotter.java
  • spock-core/src/main/java/org/spockframework/runtime/model/TextPosition.java
  • spock-core/src/main/java/org/spockframework/util/VersionNumber.java
  • spock-core/src/main/java/org/spockframework/runtime/DataVariablesIterationNameProvider.java
  • spock-core/src/main/java/org/spockframework/compiler/SpecRewriter.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockMockPostprocessor.java
  • spock-core/src/main/java/org/spockframework/runtime/SafeIterationNameProvider.java
  • spock-core/src/main/java/spock/config/ConfigurationException.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedStringComparisonRenderer.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/SpockDefinition.java
  • spock-core/src/main/java/spock/util/concurrent/AsyncConditions.java
  • spock-core/src/main/java/org/spockframework/runtime/FailedSetEqualityComparisonRenderer.java
  • spock-core/src/main/java/org/spockframework/compiler/InvalidSpecCompileException.java
  • spock-core/src/main/java/org/spockframework/util/Assert.java
  • spock-core/src/main/java/org/spockframework/compiler/ErrorReporter.java
  • spock-spring/src/main/java/org/spockframework/spring/mock/DelegatingInterceptor.java
  • spock-core/src/main/java/org/spockframework/mock/runtime/ByteBuddyMockFactory.java

private void logUnsuccessfulInterrupt(String methodName, long now, long timeoutAt, long waitMillis, int unsuccessfulAttempts) {
System.err.printf(
Locale.ROOT,
"[spock.lang.Timeout] Method '%s' has not stopped after timing out %1.2f seconds ago - interrupting. Next try in %1.2f seconds.\n%n",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Minor: Redundant newline characters.

The format string has both \n (literal newline) and %n (platform-specific line separator) at the end, resulting in double newlines in the output.

🔧 Suggested fix
-      "[spock.lang.Timeout] Method '%s' has not stopped after timing out %1.2f seconds ago - interrupting. Next try in %1.2f seconds.\n%n",
+      "[spock.lang.Timeout] Method '%s' has not stopped after timing out %1.2f seconds ago - interrupting. Next try in %1.2f seconds.%n",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"[spock.lang.Timeout] Method '%s' has not stopped after timing out %1.2f seconds ago - interrupting. Next try in %1.2f seconds.\n%n",
"[spock.lang.Timeout] Method '%s' has not stopped after timing out %1.2f seconds ago - interrupting. Next try in %1.2f seconds.%n",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java`
at line 139, In TimeoutInterceptor.java (class TimeoutInterceptor), the format
string used when logging the timeout message includes both a literal "\n" and
"%n", causing double newlines; update the format string in the logging/format
call (the string starting with "[spock.lang.Timeout] Method '%s'...") to use a
single platform-specific line separator (prefer %n) and remove the redundant
"\n" so the message ends with only "%n".

@Vampire Vampire force-pushed the vampire/fix-number-rendering branch from 50f48e6 to d166ea1 Compare March 19, 2026 16:28
@testlens-app

This comment has been minimized.

@Vampire Vampire force-pushed the vampire/fix-number-rendering branch from d166ea1 to ccbd6f6 Compare March 21, 2026 21:35
@testlens-app
Copy link

testlens-app bot commented Mar 21, 2026

✅ All tests passed ✅

🏷️ Commit: ccbd6f6
▶️ Tests: 4235 executed
⚪️ Checks: 61/61 completed


Learn more about TestLens at testlens.app.

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.

1 participant