Skip to content

feat(assertion): Add RegularExpressionValueComparer - #974

Merged
jeffjensen merged 1 commit into
mainfrom
973-regular-expression-value-comparer
Sep 9, 2026
Merged

feat(assertion): Add RegularExpressionValueComparer#974
jeffjensen merged 1 commit into
mainfrom
973-regular-expression-value-comparer

Conversation

@jeffjensen

@jeffjensen jeffjensen commented Sep 9, 2026

Copy link
Copy Markdown
Member

Add a ValueComparer that reads the expected dataset value as a regular expression and passes when it matches the actual value in its entirety (Matcher.matches(), the same whole-value rule as String.matches()), for verifying columns whose format a test controls but whose exact content it does not - database-generated ids, UUID columns, or timestamps rendered into a text column. Wrapping the pattern in .* opts into a partial match.

Null handling mirrors the sibling comparers: both null match, exactly one null does not. An invalid pattern raises DatabaseUnitException naming the row and column, consistent with IsActualEqualToExpectedJsonValueComparer.

The comparer adds no dependency beyond java.util.regex, so it is also exposed as the ValueComparers.regularExpressionValueComparer constant.

  • Cover the comparer with RegularExpressionValueComparerTest: null handling, whole-value versus substring and prefix matches, character classes and quantifiers, alternation, escaped metacharacters, inline flags, case sensitivity, empty and zero-width patterns, non-string actual values, invalid-pattern reporting, and the compare() fail-message path.
  • Exercise it end to end through the assert pipeline in DbUnitValueComparerAssertIT.
  • Document it in valuecomparer.adoc.

Refs: 973

Claude-Session: https://claude.ai/code/session_01LaCA8dcNX7whN1143ZZwYJ

Summary by Sourcery

Add regular-expression value comparison for validating controlled data formats without requiring exact generated values.

New Features:

  • Add a regular-expression value comparer that matches expected patterns against entire actual values, with explicit support for partial matching through permissive patterns.
  • Expose the comparer through the ValueComparers convenience constants.

Bug Fixes:

  • Report invalid regular expressions as DatabaseUnitException instances containing the affected row and column.

Enhancements:

  • Define null handling and string conversion consistently with existing value comparers.
  • Provide a descriptive failure message when values do not match their expected regular expressions.

Documentation:

  • Document regular-expression value comparison and its whole-value matching behavior.

Tests:

  • Add unit and integration coverage for regex matching, null handling, pattern features, invalid expressions, failure messages, and assertion-pipeline usage.

Summary by CodeRabbit

  • New Features

    • Added regular expression value comparison for dataset assertions.
    • Expected values are matched against the entire actual value by default; use .* for partial matches.
    • Invalid regular expressions now produce clear comparison errors with row and column context.
    • Supports null values, numeric conversions, quantifiers, character classes, alternation, flags, and escaping.
  • Documentation

    • Added guidance for configuring and using regular expression comparisons.

@jeffjensen jeffjensen linked an issue Sep 9, 2026 that may be closed by this pull request
@sourcery-ai

sourcery-ai Bot commented Sep 9, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a reusable regular-expression ValueComparer that converts dataset values to strings, requires whole-value matches by default, preserves sibling null semantics, reports invalid patterns with row and column context, and is exposed, documented, and covered by unit and end-to-end tests.

Sequence diagram for regular expression value comparison

sequenceDiagram
    participant AssertPipeline
    participant RegularExpressionValueComparer
    participant DataType
    participant Pattern
    participant Matcher

    AssertPipeline->>RegularExpressionValueComparer: isExpected(expectedTable, actualTable, rowNum, columnName, dataType, expectedValue, actualValue)
    alt both values null
        RegularExpressionValueComparer-->>AssertPipeline: true
    else exactly one value null
        RegularExpressionValueComparer-->>AssertPipeline: false
    else non-null values
        RegularExpressionValueComparer->>DataType: asString(expectedValue)
        DataType-->>RegularExpressionValueComparer: regex
        RegularExpressionValueComparer->>DataType: asString(actualValue)
        DataType-->>RegularExpressionValueComparer: actualValueString
        RegularExpressionValueComparer->>Pattern: compile(regex)
        Pattern-->>RegularExpressionValueComparer: pattern
        RegularExpressionValueComparer->>Matcher: matches()
        Matcher-->>RegularExpressionValueComparer: whole-value result
        RegularExpressionValueComparer-->>AssertPipeline: true or false
    end
Loading

File-Level Changes

Change Details Files
Implement a whole-value regular-expression comparer with null handling and contextual invalid-pattern errors.
  • Convert expected and actual values to strings and evaluate with Matcher.matches().
  • Treat two nulls as equal and exactly one null as unequal.
  • Wrap PatternSyntaxException in DatabaseUnitException containing row and column details.
  • Provide a comparer-specific failure phrase and debug logging.
src/main/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparer.java
Expose the regular-expression comparer through the shared comparer registry.
  • Add the regularExpressionValueComparer singleton constant.
  • Document its whole-value matching behavior and 3.6.0 availability in the API metadata.
src/main/java/org/dbunit/assertion/comparer/value/ValueComparers.java
Add focused unit and integration coverage for regex matching behavior.
  • Test nulls, whole-value versus partial matching, regex syntax/features, flags, escaping, empty matches, non-string values, invalid patterns, and comparison failure messages.
  • Exercise successful and failing comparisons through the assert pipeline.
src/test/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparerTest.java
src/test/java/org/dbunit/assertion/DbUnitValueComparerAssertIT.java
Document and announce the new comparer.
  • Describe usage and matching semantics in the value comparer documentation.
  • Record the feature in the project change log.
src/site/asciidoc/datacomparisons/valuecomparer.adoc
src/changes/changes.xml

Assessment against linked issues

Issue Objective Addressed Explanation
#973 Add a RegularExpressionValueComparer that treats the expected value as a regular expression, converts the actual value to a string, and requires a whole-value match using Matcher.matches(), with support for null handling and invalid-pattern reporting.
#973 Expose the comparer through the ValueComparers regularExpressionValueComparer constant without adding a new dependency.
#973 Document the new comparer in valuecomparer.adoc and add a corresponding changes.xml entry, with unit and integration coverage.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 39 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 11f69745-7851-4f63-b275-8674fc2024f1

📥 Commits

Reviewing files that changed from the base of the PR and between 54dba96 and 430ec86.

📒 Files selected for processing (4)
  • src/changes/changes.xml
  • src/main/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparer.java
  • src/site/asciidoc/datacomparisons/valuecomparer.adoc
  • src/test/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparerTest.java

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 50ac8d8c-4f47-43cd-9b73-fca3ffc1118d

📥 Commits

Reviewing files that changed from the base of the PR and between fbd4d0f and 54dba96.

📒 Files selected for processing (6)
  • src/changes/changes.xml
  • src/main/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparer.java
  • src/main/java/org/dbunit/assertion/comparer/value/ValueComparers.java
  • src/site/asciidoc/datacomparisons/valuecomparer.adoc
  • src/test/java/org/dbunit/assertion/DbUnitValueComparerAssertIT.java
  • src/test/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparerTest.java

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Adds RegularExpressionValueComparer with whole-value matching, null handling, invalid-pattern reporting, public access through ValueComparers, documentation, changelog coverage, and unit and integration tests.

Changes

Regular expression value comparison

Layer / File(s) Summary
Regular expression matching behavior
src/main/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparer.java, src/test/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparerTest.java
The comparer converts values to strings, applies full-value regular-expression matching, handles null values, reports invalid patterns with row and column context, and defines comparison failure text. Tests cover matching rules, conversions, errors, and comparison messages.
Public API and integration
src/main/java/org/dbunit/assertion/comparer/value/ValueComparers.java, src/test/java/org/dbunit/assertion/DbUnitValueComparerAssertIT.java, src/site/asciidoc/datacomparisons/valuecomparer.adoc, src/changes/changes.xml
Adds ValueComparers.regularExpressionValueComparer, validates passing and failing assertions, and documents the new comparison type and 3.6.0-SNAPSHOT changelog entry.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 54dba

This adds an opt-in regular-expression dataset comparer with documented whole-value matching behavior and clear invalid-pattern errors. Matching and failure paths are covered, and no merge-blocking product risk is evident.

Sequence Diagram(s)

sequenceDiagram
  participant TestOrCaller
  participant ValueComparers
  participant RegularExpressionValueComparer
  participant DataType
  participant Pattern
  TestOrCaller->>ValueComparers: select regularExpressionValueComparer
  TestOrCaller->>RegularExpressionValueComparer: compare expected pattern and actual value
  RegularExpressionValueComparer->>DataType: convert values to strings
  RegularExpressionValueComparer->>Pattern: compile and match expected pattern
  Pattern-->>RegularExpressionValueComparer: match result
  RegularExpressionValueComparer-->>TestOrCaller: comparison result or DatabaseUnitException
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.88% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 41 functions across 4 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding RegularExpressionValueComparer. It matches the implementation, public API, tests, and documentation changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 4.88% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 41 functions across 4 files. (2 skipped: 2 unsupported.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 973-regular-expression-value-comparer

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.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/main/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparer.java" line_range="105-106" />
<code_context>
+        final String regex = DataType.asString(expectedValue);
+        final String actualValueString = DataType.asString(actualValue);
+        final Pattern pattern = compilePattern(rowNum, columnName, regex);
+        final Matcher matcher = pattern.matcher(actualValueString);
+        final boolean isMatching = matcher.matches();
+        log.debug("isMatching: regex={}, actualValueString={}, isMatching={}",
+                regex, actualValueString, isMatching);
</code_context>
<issue_to_address>
**issue (bug_risk):** Wrapping a pattern in `.*` does not provide a general partial match when the actual value contains a line terminator, because Java regex `.` excludes line terminators unless DOTALL is enabled; a pattern such as `.*foo.*` therefore fails for an actual value containing `foo` across or adjacent to a newline despite the documentation promising that this form matches part of the value.

**Triggers:** When the actual database value contains a newline or another line terminator and callers use the documented `.*pattern.*` form.

**Suggested fix:** Document the line-terminator limitation and suggest `(?s:.*pattern.*)`, or enable DOTALL for the wrapper semantics if universal partial matching is intended.
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: src/main/java/org/dbunit/assertion/comparer/value/RegularExpressionValueComparer.java:106


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Add a ValueComparer that reads the expected dataset value as a regular
expression and passes when it matches the actual value in its entirety
(Matcher.matches(), the same whole-value rule as String.matches()), for
verifying columns whose format a test controls but whose exact content it
does not - database-generated ids, UUID columns, or timestamps rendered
into a text column. Wrapping the pattern in .* opts into a partial match.

Null handling mirrors the sibling comparers: both null match, exactly one
null does not. An invalid pattern raises DatabaseUnitException naming the
row and column, consistent with IsActualEqualToExpectedJsonValueComparer.

The comparer adds no dependency beyond java.util.regex, so it is also
exposed as the ValueComparers.regularExpressionValueComparer constant.

* Cover the comparer with RegularExpressionValueComparerTest: null
  handling, whole-value versus substring and prefix matches, character
  classes and quantifiers, alternation, escaped metacharacters, inline
  flags, case sensitivity, empty and zero-width patterns, non-string
  actual values, invalid-pattern reporting, and the compare() fail-message
  path.
* Exercise it end to end through the assert pipeline in
  DbUnitValueComparerAssertIT.
* Document it in valuecomparer.adoc.

Refs: 973

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LaCA8dcNX7whN1143ZZwYJ
@jeffjensen
jeffjensen force-pushed the 973-regular-expression-value-comparer branch from 54dba96 to 430ec86 Compare September 9, 2026 02:17

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sourcery assessment

Approved.

@jeffjensen
jeffjensen merged commit b8f0069 into main Sep 9, 2026
29 checks passed
@jeffjensen
jeffjensen deleted the 973-regular-expression-value-comparer branch September 9, 2026 02:27
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.

Add regular-expression ValueComparer

1 participant