Skip to content

Add comprehensive tests for ComplexFormComponent creation#2204

Draft
myieye wants to merge 12 commits intodevelopfrom
claude/add-complex-form-tests-B7DRq
Draft

Add comprehensive tests for ComplexFormComponent creation#2204
myieye wants to merge 12 commits intodevelopfrom
claude/add-complex-form-tests-B7DRq

Conversation

@myieye
Copy link
Collaborator

@myieye myieye commented Mar 11, 2026

Summary

This PR adds three new test cases to validate the behavior of ComplexFormComponent creation in the CRDT system, and cleans up related code comments.

Key Changes

  • Added three new test methods to ComplexFormComponentTests:

    • ReusingEntityId_ForDifferentComponent_Throws: Validates that reusing the same entity ID for different components throws an exception
    • IdempotentCreate_ReturnsExistingId_NotNewlyProvidedId: Verifies that creating a duplicate component returns the existing ID rather than the newly provided one
    • Create_WithBetweenComponentsLackingIds_PositionsCorrectly: Tests that components without CRDT entity IDs (from LibLCM) are correctly positioned using property-based lookup
  • Added helper methods to support the new tests:

    • CreateEntry(string headword): Creates a new entry with the given headword
    • GetEntry(Guid id): Retrieves an entry by ID
    • ComponentWithoutId(Guid, Guid): Creates a component without a CRDT entity ID to simulate LibLCM data
  • Cleaned up code:

    • Removed TODO comments from CrdtMiniLcmApi.CreateComplexFormComponent that documented these test cases
    • Simplified the NewApi() method to directly return the fixture API
    • Added necessary using statements for test support classes

Notable Implementation Details

The tests validate important edge cases in the component creation logic:

  • Entity ID uniqueness constraints
  • Idempotent behavior based on component properties rather than provided IDs
  • Proper handling of positioning when between-components lack CRDT IDs (property-based resolution)

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f

claude added 2 commits March 11, 2026 16:51
Tests cover:
- Reusing a Harmony entity ID for a different component relationship throws
- Changing a property ID (e.g. ComponentEntryId) produces a new entity ID
- Idempotent create returns existing entity's ID, not newly provided one
- BetweenPosition works with components lacking CRDT IDs (as from LibLCM)

Remove the corresponding TODO comments from CrdtMiniLcmApi.cs.

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
Remove ChangingPropertyId_ProducesNewEntityId (trivially implied by
the idempotent create test's contrapositive). Strip comments that
restate what the code already shows.

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
@github-actions github-actions bot added the 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related label Mar 11, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 11, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: df5696a0-8295-4868-8a40-d3832782c875

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/add-complex-form-tests-B7DRq
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 2026

UI unit Tests

  1 files  ±0   54 suites  ±0   27s ⏱️ +2s
140 tests ±0  140 ✅ ±0  0 💤 ±0  0 ❌ ±0 
207 runs  ±0  207 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 6480148. ± Comparison against base commit 3702ec6.

♻️ This comment has been updated with latest results.

@argos-ci
Copy link

argos-ci bot commented Mar 11, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Mar 13, 2026, 1:27 PM

claude added 10 commits March 12, 2026 10:22
- ReusingEntityId: Harmony doesn't throw on duplicate entity IDs (no-op),
  so the test documents the real pitfall — mutating a property without
  resetting the ID returns the original entity with stale properties.
  This is what EntrySync guards against with `after.Id = Guid.NewGuid()`.
- Create_WithoutPresetId: documents the LibLCM path where MaybeId is null
  and the system assigns a new entity ID.
- BetweenComponents: improved variable naming for readability.

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
…tests

- CrdtMiniLcmApi: Always assign a new Guid for the entity ID, matching
  FwData behavior and eliminating the Harmony duplicate-ID pitfall that
  the sync code previously had to work around.
- Base class: Add CreateComplexFormComponent_ChangingPropertyAndCreatingAgain_CreatesBoth
  to verify that mutating a property and creating again produces two
  distinct components (the sync diff's remove+add pattern).
- CRDT subclass: Replace obsolete ReusingEntityId test with
  Create_AlwaysAssignsNewEntityId verifying the provided ID is never used.

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
CrdtMiniLcmApi.CreateComplexFormComponent:
- Add throw when caller provides an entity ID matching an existing
  component — this documents that the ID is internal and should never
  be reused (Harmony would silently no-op the duplicate).
- Add explanatory comments on the Guid.NewGuid() assignment.

Tests reorganized to cover all 4 original TODO comments:
1. Create_WithExistingEntityId_Throws (CRDT) — reusing an already-created
   component throws, documenting that entity IDs are internal.
2. Create_ChangingProperty_ProducesNewEntityId (CRDT) — mutating a property
   and creating again produces distinct Harmony entities (the sync diff
   remove+add pattern).
3. Create_AlwaysAssignsNewEntityId (CRDT) — the provided ID is never used.
4. CreateComplexFormComponent_WithBetweenComponentsLackingIds_PositionsCorrectly
   (base) — BetweenPosition anchors without entity IDs are resolved by
   property lookup, as they'd arrive from LibLCM.

Also moves BetweenPosition test from CRDT subclass to base (FwData
supports between positioning too).

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
- Remove redundant `is not null` guard — existing.MaybeId is always
  non-null in CRDT, so equality alone suffices.
- Add Create_DuplicateByProperties_WithDifferentEntityId_ReturnsExisting
  to document that two calls with the same properties but different entity
  IDs (the normal case) are idempotent.

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
Sync can be interrupted and replayed, so the same object (with the same
entity ID) may be passed to CreateComplexFormComponent again. Instead of
throwing, we rely on the property-based match to find and return the
existing component — same as any other duplicate-by-properties call.

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
Order is [MiniLcmInternal] and its representation differs between
implementations (FwData uses sequential ints, CRDT uses doubles).
Asserting on raw Order values breaks in FwData because inserting
between A and B shifts B's Order, making the stale captured value
incorrect. Instead, read the entry back and verify the component
sequence — this tests the actual observable behavior.

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
- Remove unused createdA, createdB, insertedBetween variables
- Use Equal instead of ContainInOrder for exact sequence assertion

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
EntrySync's ComplexFormsDiffApi.Add and ComplexFormComponentsDiffApi.Add
both set after.Id = Guid.NewGuid() before calling CreateComplexFormComponent.
This is dead code: CRDT always generates its own ID, and FwData ignores the
ID entirely. Remove both assignments and their comments.

Also remove Create_WithExistingEntityId_IsIdempotent from the CRDT tests —
it duplicates CreateComplexFormComponent_UsingTheSameComponentWithNullSenseDoesNothing
in the shared base class (both test: create, create again → get same thing back).

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
Documents that passing the exact returned object back (same internal
entity ID) is idempotent — a distinct scenario from creating with
fresh FromEntries inputs, since sync interruptions can replay the
same object.

https://claude.ai/code/session_01Dz9V2fkKzPgAkSpFP2NE5f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants