Skip to content

test(dpp): improve coverage for data contract serialization and index validation#3438

Merged
QuantumExplorer merged 1 commit into
v3.1-devfrom
test/dpp-contract-serialization
Apr 7, 2026
Merged

test(dpp): improve coverage for data contract serialization and index validation#3438
QuantumExplorer merged 1 commit into
v3.1-devfrom
test/dpp-contract-serialization

Conversation

@QuantumExplorer
Copy link
Copy Markdown
Member

@QuantumExplorer QuantumExplorer commented Apr 7, 2026

Summary

Adds 100 tests across 3 files in rs-dpp covering real logic.

File New Tests What's covered
serialized_version/mod.rs 49 first_mismatch() for V0/V1, TryFromPlatformVersioned, accessors, Display
document_type/index/mod.rs 20 objects_are_conflicting(), ContestedIndexFieldMatch::matches(), Ord, IndexProperty errors
balances/credits.rs 31 to_signed() overflow, from_vec_bytes/to_vec_bytes round-trips, CreditOperation::merge

Test plan

  • cargo test -p dpp --lib passes
  • cargo fmt --all clean
  • CI

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Enhanced test coverage for credit conversion and serialization operations.
    • Expanded test cases for index conflict detection and field matching behavior.
    • Added comprehensive tests for data contract serialization and versioning.

… validation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added this to the v3.1.0 milestone Apr 7, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

This pull request adds comprehensive unit test coverage across three modules: credit conversion and serialization behavior, data contract index operations and field matching logic, and data contract serialization format handling. All changes are test-only additions with no modifications to public APIs or functional code.

Changes

Cohort / File(s) Summary
Credit Conversion & Serialization Tests
packages/rs-dpp/src/balances/credits.rs
Added 262 lines of tests covering to_signed() conversions with overflow expectations, to_unsigned() behavior for positive/negative values, byte round-trip serialization via to_vec_bytes()/from_vec_bytes(), constant validation, and CreditOperation::merge combinations including saturating-add scenarios.
Index Operations & Field Matching Tests
packages/rs-dpp/src/data_contract/document_type/index/mod.rs
Added 209 lines of tests for Index::objects_are_conflicting covering unique/non-unique properties and multi-property matching, ContestedIndexFieldMatch::matches() regex and type handling, ordering semantics across comparisons, and error cases for IndexProperty::try_from with invalid direction strings and malformed input.
Data Contract Serialization Format Tests
packages/rs-dpp/src/data_contract/serialized_version/mod.rs
Added 687 lines of tests validating DataContractInSerializationFormat::first_mismatch across version combinations, DataContractMismatch display output, accessor methods on serialization format, TryFromPlatformVersioned routing for version-specific conversions, and platform version serialization defaults.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~18 minutes

Poem

🐰 Hops of joy through test-filled code,
Each assertion lights the road,
Credits, contracts, indexes too—
A thousand tests to verify true! 🧪✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding comprehensive test coverage for data contract serialization and index validation across multiple modules in the DPP crate.
Docstring Coverage ✅ Passed Docstring coverage is 99.05% which is sufficient. The required threshold is 80.00%.

✏️ 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 test/dpp-contract-serialization

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.

@thepastaclaw
Copy link
Copy Markdown
Collaborator

thepastaclaw commented Apr 7, 2026

⏳ Review in progress (commit ec0d015)

Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (4)
packages/rs-dpp/src/balances/credits.rs (1)

444-457: Consider adding i64::MIN case for SignedCredits::to_unsigned().

You already test signed serialization with i64::MIN; adding the conversion edge here would fully lock down unsigned_abs() behavior.

Optional test addition
 #[test]
 fn signed_credits_to_unsigned_zero() {
     let sc: SignedCredits = 0;
     assert_eq!(sc.to_unsigned(), 0);
 }
+
+#[test]
+fn signed_credits_to_unsigned_min_i64() {
+    let sc: SignedCredits = i64::MIN;
+    assert_eq!(sc.to_unsigned(), (i64::MAX as u64) + 1);
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/rs-dpp/src/balances/credits.rs` around lines 444 - 457, Add a test
case covering the i64::MIN edge for SignedCredits::to_unsigned(): create a
SignedCredits value set to i64::MIN and assert that to_unsigned() returns
9223372036854775808u64 (2^63), so the test verifies the method handles the
i64::MIN overflow edge correctly; update the existing
signed_credits_to_unsigned_returns_abs test (or add a new test) to include this
SignedCredits::MIN assertion referencing SignedCredits::to_unsigned().
packages/rs-dpp/src/data_contract/document_type/index/mod.rs (2)

1436-1465: Consider consolidating with existing error tests.

These tests duplicate coverage from lines 1056-1077 (test_index_property_try_from_empty_map_error, test_index_property_try_from_multiple_entries_error, test_index_property_try_from_invalid_sort_order_error) but add error message verification.

Rather than having separate tests, consider enhancing the existing tests to include the error message assertions. This reduces duplication while preserving the improved coverage.

Example consolidation for empty map test
 #[test]
 fn test_index_property_try_from_empty_map_error() {
     let map: BTreeMap<String, String> = BTreeMap::new();
     let result = IndexProperty::try_from(map);
     assert!(result.is_err());
+    let err_msg = format!("{}", result.unwrap_err());
+    assert!(err_msg.contains("empty"));
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/rs-dpp/src/data_contract/document_type/index/mod.rs` around lines
1436 - 1465, Remove the three duplicate tests
(test_index_property_try_from_unknown_direction,
test_index_property_try_from_empty_map,
test_index_property_try_from_three_entries_error) and instead add the
error-message assertions into the existing tests
test_index_property_try_from_invalid_sort_order_error,
test_index_property_try_from_empty_map_error, and
test_index_property_try_from_multiple_entries_error respectively; locate the
IndexProperty::try_from invocation in each existing test, capture the Err with
format!("{}", result.unwrap_err()), and assert the appropriate substring ("up"
for invalid direction, "empty" for empty map, "more than one" for multiple
entries) so coverage is preserved without duplicating test cases.

1262-1277: Test name and comment may cause confusion between "null" and "missing".

The test name test_objects_are_conflicting_both_null_values_not_conflicting and comment mention "null values," but the test actually verifies behavior for missing properties (keys not present in the map). In platform_value, a missing key and a key with Value::Null may behave differently depending on Value::get_optional_from_map semantics.

Consider renaming to test_objects_are_conflicting_both_missing_properties_not_conflicting for clarity, or add a separate test that explicitly uses Value::Null to verify both scenarios.

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

In `@packages/rs-dpp/src/data_contract/document_type/index/mod.rs` around lines
1262 - 1277, The test named
test_objects_are_conflicting_both_null_values_not_conflicting is misleading
because it checks missing properties, not Value::Null; update the test to either
rename it to
test_objects_are_conflicting_both_missing_properties_not_conflicting (update the
function name and any comments) to reflect that it uses absent keys, or add a
new test that constructs ValueMap entries with Value::Null and asserts
objects_are_conflicting behavior for nulls; locate the test and related helpers
(objects_are_conflicting, make_index, ValueMap, Value::Null) and ensure both
missing-key and explicit-Value::Null cases are covered and clearly named.
packages/rs-dpp/src/data_contract/serialized_version/mod.rs (1)

913-1120: Optional: Consider extracting test fixture builders.

The conversion tests contain repeated DataContractV0 and DataContractV1 struct initialization (lines 917-925, 940-948, 961-969, 986-1003, 1016-1033, 1046-1063, 1079-1087, 1102-1110). You could reduce duplication with parameterized helper functions:

♻️ Optional refactor
fn make_data_contract_v0(id: Identifier, owner_id: Identifier, version: u32) -> DataContractV0 {
    DataContractV0 {
        id,
        config: DataContractConfig::V0(DataContractConfigV0::default()),
        version,
        owner_id,
        schema_defs: None,
        document_types: BTreeMap::new(),
        metadata: None,
    }
}

fn make_data_contract_v1(id: Identifier, owner_id: Identifier, version: u32, config: DataContractConfig) -> DataContractV1 {
    DataContractV1 {
        id,
        config,
        version,
        owner_id,
        schema_defs: None,
        document_types: BTreeMap::new(),
        created_at: None,
        updated_at: None,
        created_at_block_height: None,
        updated_at_block_height: None,
        created_at_epoch: None,
        updated_at_epoch: None,
        groups: BTreeMap::new(),
        tokens: BTreeMap::new(),
        keywords: vec![],
        description: None,
    }
}

Then use:

let v0 = make_data_contract_v0(
    Identifier::from([10u8; 32]),
    Identifier::from([20u8; 32]),
    1
);

However, the current explicit approach aids test readability, so this refactor is purely optional.

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

In `@packages/rs-dpp/src/data_contract/serialized_version/mod.rs` around lines 913
- 1120, Tests repeat verbose DataContractV0/DataContractV1 construction; extract
small fixture builders to reduce duplication: add helper functions like
make_data_contract_v0(id: Identifier, owner_id: Identifier, version: u32) ->
DataContractV0 and make_data_contract_v1(id: Identifier, owner_id: Identifier,
version: u32, config: DataContractConfig) -> DataContractV1 and replace repeated
inline structs in tests (e.g., try_from_platform_versioned_data_contract_v0_*,
try_from_platform_versioned_data_contract_v1_*,
try_from_platform_versioned_data_contract_*) with calls to these helpers to keep
the same field defaults (config default, None fields, empty BTreeMap/vec) while
improving readability and avoiding duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/rs-dpp/src/balances/credits.rs`:
- Around line 444-457: Add a test case covering the i64::MIN edge for
SignedCredits::to_unsigned(): create a SignedCredits value set to i64::MIN and
assert that to_unsigned() returns 9223372036854775808u64 (2^63), so the test
verifies the method handles the i64::MIN overflow edge correctly; update the
existing signed_credits_to_unsigned_returns_abs test (or add a new test) to
include this SignedCredits::MIN assertion referencing
SignedCredits::to_unsigned().

In `@packages/rs-dpp/src/data_contract/document_type/index/mod.rs`:
- Around line 1436-1465: Remove the three duplicate tests
(test_index_property_try_from_unknown_direction,
test_index_property_try_from_empty_map,
test_index_property_try_from_three_entries_error) and instead add the
error-message assertions into the existing tests
test_index_property_try_from_invalid_sort_order_error,
test_index_property_try_from_empty_map_error, and
test_index_property_try_from_multiple_entries_error respectively; locate the
IndexProperty::try_from invocation in each existing test, capture the Err with
format!("{}", result.unwrap_err()), and assert the appropriate substring ("up"
for invalid direction, "empty" for empty map, "more than one" for multiple
entries) so coverage is preserved without duplicating test cases.
- Around line 1262-1277: The test named
test_objects_are_conflicting_both_null_values_not_conflicting is misleading
because it checks missing properties, not Value::Null; update the test to either
rename it to
test_objects_are_conflicting_both_missing_properties_not_conflicting (update the
function name and any comments) to reflect that it uses absent keys, or add a
new test that constructs ValueMap entries with Value::Null and asserts
objects_are_conflicting behavior for nulls; locate the test and related helpers
(objects_are_conflicting, make_index, ValueMap, Value::Null) and ensure both
missing-key and explicit-Value::Null cases are covered and clearly named.

In `@packages/rs-dpp/src/data_contract/serialized_version/mod.rs`:
- Around line 913-1120: Tests repeat verbose DataContractV0/DataContractV1
construction; extract small fixture builders to reduce duplication: add helper
functions like make_data_contract_v0(id: Identifier, owner_id: Identifier,
version: u32) -> DataContractV0 and make_data_contract_v1(id: Identifier,
owner_id: Identifier, version: u32, config: DataContractConfig) ->
DataContractV1 and replace repeated inline structs in tests (e.g.,
try_from_platform_versioned_data_contract_v0_*,
try_from_platform_versioned_data_contract_v1_*,
try_from_platform_versioned_data_contract_*) with calls to these helpers to keep
the same field defaults (config default, None fields, empty BTreeMap/vec) while
improving readability and avoiding duplication.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 20149d65-b118-4971-a5a3-9107d90bac3c

📥 Commits

Reviewing files that changed from the base of the PR and between 8a83981 and ec0d015.

📒 Files selected for processing (3)
  • packages/rs-dpp/src/balances/credits.rs
  • packages/rs-dpp/src/data_contract/document_type/index/mod.rs
  • packages/rs-dpp/src/data_contract/serialized_version/mod.rs

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 7, 2026

Codecov Report

❌ Patch coverage is 99.87294% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 80.74%. Comparing base (8a83981) to head (ec0d015).
⚠️ Report is 2 commits behind head on v3.1-dev.

Files with missing lines Patch % Lines
packages/rs-dpp/src/balances/credits.rs 99.38% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           v3.1-dev    #3438      +/-   ##
============================================
+ Coverage     80.66%   80.74%   +0.08%     
============================================
  Files          2852     2852              
  Lines        285371   286158     +787     
============================================
+ Hits         230190   231071     +881     
+ Misses        55181    55087      -94     
Components Coverage Δ
dpp 73.74% <99.87%> (+0.45%) ⬆️
drive 82.49% <ø> (ø)
drive-abci 86.70% <ø> (ø)
sdk 36.55% <ø> (ø)
dapi-client 79.06% <ø> (ø)
platform-version ∅ <ø> (∅)
platform-value 90.79% <ø> (ø)
platform-wallet 76.09% <ø> (ø)
drive-proof-verifier 55.26% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@QuantumExplorer QuantumExplorer merged commit 4ec4157 into v3.1-dev Apr 7, 2026
41 checks passed
@QuantumExplorer QuantumExplorer deleted the test/dpp-contract-serialization branch April 7, 2026 12: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.

2 participants