Skip to content

Feat/key regex match - #60

Closed
nil-malh wants to merge 8 commits into
mainfrom
feat/key-regex-match
Closed

nil-malh wants to merge 8 commits into
mainfrom
feat/key-regex-match

Conversation

@nil-malh

@nil-malh nil-malh commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

📝 Description

This PR introduces a configurable KeyMatchStrategy enum in ktestify-core that allows expectedRecordKey to be matched using strategies other than exact equality: CONTAINS, STARTS_WITH, ENDS_WITH, and REGEX.

Previously, expectedRecordKey was hardcoded to String.equals() in five locations: the fetch-time pre-filter (KafkaRecordFetcher.passesKeyFilter()) and four assertion-time matchers (KeyRecordMatcher, FileKeyRecordMatcher, AvroKeyRecordMatcher, AvroFileKeyRecordMatcher). This made it impossible to validate dynamically generated keys (UUIDs, prefixed keys, etc.) without knowing the exact value upfront.

The new KeyMatchStrategy enum encapsulates the comparison logic in a single matches(expected, actual) method. It flows through both layers identically to how expectedRecordKey already flows: ConsumerContext (fetch-time filter) and MatchContext (assertion). The default is EXACT, preserving full backward compatibility.

Resolves #46


🔄 Type of Change

  • ✨ New feature — non-breaking change that adds functionality

✅ Pre-Merge Checklist

Code Quality

  • My code follows the Palantir Java Format style (passes mvn spotless:check)
  • I have added or updated Javadoc on public types and methods

Tests

  • I have added unit tests that cover the new / changed behaviour
  • All existing and new tests pass locally (mvn verify)
  • JaCoCo line coverage ≥ 70 % is maintained
  • Tests using Testcontainers are isolated and do not leave containers running

Licensing

  • Apache 2.0 license header has been added to every new source file (using spotless)

🧪 How to Test Locally

# 1. Build and run all tests (requires Docker for Testcontainers)
mvn verify

# 2. Check code style
mvn spotless:check

# 3. Run only the new strategy tests
mvn test -Dtest=KeyMatchStrategyTest
mvn test -Dtest=KeyRecordMatcherTest

📸 Screenshots / Logs

All tests pass:

mvn spotless:check test  →  BUILD SUCCESS
KeyMatchStrategyTest     →  30+ parameterized cases (5 strategies + fromString parsing)
KeyRecordMatcherTest     →  10 new strategy cases added to existing suite

📚 Additional Context

Files Changed

New file:

  • match/KeyMatchStrategy.java : Enum with EXACT, CONTAINS, STARTS_WITH, ENDS_WITH, REGEX. Includes fromString() for parsing DataTable values (case-insensitive, tolerant of hyphens/underscores/spaces, defaults to EXACT).

Modified (main):

File Change
io/kafka/ConsumerContext.java Added keyMatchStrategy field + builder method (defaults to EXACT)
io/kafka/KafkaRecordFetcher.java passesKeyFilter() uses strategy.matches() instead of equals()
io/kafka/AbstractKafkaConsumer.java buildMatchContext() propagates keyMatchStrategy to MatchContext
match/MatchContext.java Added keyMatchStrategy field with @Builder.Default = EXACT
match/impl/KeyRecordMatcher.java Uses strategy.matches()
match/impl/FileKeyRecordMatcher.java Uses strategy.matches()
match/impl/AvroKeyRecordMatcher.java Uses strategy.matches()
match/impl/AvroFileKeyRecordMatcher.java Uses strategy.matches()

Modified (test):

File Change
match/KeyMatchStrategyTest.java New — 30+ cases covering all strategies and fromString() parsing
match/impl/KeyRecordMatcherTest.java Added KeyStrategies nested class with 10 strategy tests
match/impl/MatcherTestSupport.java Added ctxWithKeyAndStrategy() helper

Backward Compatibility

The default strategy is EXACT everywhere. Existing feature files and code paths that do not set keyMatchStrategy behave exactly as before. No breaking changes.

@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

📋 Unreleased Changelog Preview

This is what the next release notes will look like based on commits in this PR.

Changelog

All notable changes to this project will be documented in this file.

[Unreleased]

✨ Features

  • Introduce key matching strategies for record assertions

Generated by git-cliff


🔄 Run #149 · Thu, 01 Oct 2026 17:22:35 GMT

@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Results

Metric Count
✅ Passed 784
❌ Failed 0
⏭️ Skipped 0
📊 Total 784

✅ Coverage

Type Coverage Covered / Total
📏 Lines 84.3% 1918 / 2276
🌿 Branches 74.1% 625 / 844
🔧 Methods 85.1% 400 / 470

🔄 CI run #168 · Thu, 01 Oct 2026 17:26:43 GMT

nil-malh and others added 5 commits October 6, 2026 19:46
* fix: fixed an issue where a NullPointerException was thrown on unset environment variables

* fix: close URLClassLoader in PluginRegistry to prevent file handle leak

* fix: add missing schemas directory default to reference.conf

* fix: harden XML parsers against XXE attacks in XMLUtils

* fix: enforce error taxonomy and add missing exception constructors

* fix: correct over-suppression of CHILD_NODELIST_LENGTH in XMLUtils

* fix: fixed an issue where a SchemaRegistryClient was instantiated at each call instead of being cached

* chore: fixed some tests

* (feat/bug-fixes) style: spotless

* fix: improve byte buffer handling in AvroDeserializer

* fix: include cause in ConsumerException for better error handling

* fix: handle null values in record matchers and improve logging

* fix: enhance security in SAXParserFactory and improve documentation

* style: update comments for consistency in punctuation

* test: add ClasspathTestPlugin for lifecycle call assertions

* refactor: enhance plugin loading and shutdown logic

* fix: improve handling of empty records in AttributeRecordMatcher

* feat: add AvroJson and AvroLogicalTypesSerializationTest for JSON conversion of Avro logical types

* feat: enhance DynamicVariableFactory for thread-safety and case-insensitivity

* fix: improve getLine method to handle null content and out-of-bounds indices

* refactor: enhance timeout handling and improve documentation in KafkaRecordFetcher

* feat: added two new MatchResult noRecords and nullValue

* style: improve comments

* test: add TombstoneMatcherTest to verify tombstone handling across matchers

* refactor: extract null value message to constant in MatchResult

* style: spotless

* fix: null pointer exception on empty TimestampVariable when format is null

* ci: update CI workflow to use reusable Maven CI and add manual integration test option

* (feat/bug-fixes) style: spotless

* ci: fix workflow paths in CI and dependency review configurations

* fix: update dependency review workflow path

* style: spotless

* test: rename integration tests with *ITTests

* test: rename integration tests with *ITTests

* ci: enable integration tests by default in CI workflow

* deps: bump ktestify-parent version from 1.0.4 to 1.0.5

* feat: introduce FetchTimeoutException for clearer timeout handling

* style: spotless
# Conflicts:
#	src/main/java/io/github/ktestify/match/impl/AvroFileKeyRecordMatcher.java
#	src/main/java/io/github/ktestify/match/impl/AvroKeyRecordMatcher.java
#	src/main/java/io/github/ktestify/match/impl/FileKeyRecordMatcher.java
#	src/main/java/io/github/ktestify/match/impl/KeyRecordMatcher.java
@nil-malh nil-malh closed this Oct 6, 2026
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.

[Feature]: Support multiple recordKey matching options in assertions

1 participant