Skip to content

Add GUI pre-save validation for InOut element count#357

Merged
bedaHovorka merged 20 commits intodevelopfrom
copilot/add-gui-validation-in-editor
Mar 29, 2026
Merged

Add GUI pre-save validation for InOut element count#357
bedaHovorka merged 20 commits intodevelopfrom
copilot/add-gui-validation-in-editor

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 6, 2026

✅ Issue #80 Implementation Complete: GUI InOut Validation

Summary

Successfully implemented pre-save validation in the editor GUI to prevent users from saving railway networks with fewer than 1 InOut elements. This provides immediate, user-friendly feedback at save time rather than cryptic error messages on reload.


🎯 Problem NOT Solved

Before: Users could save contexts with 0-1 InOuts → File created → Can't reload → Confusion
After: Users try to save with 0-1 InOuts → Error dialog → User adds InOuts → Saves successfully ✅


📝 Implementation Details

Core Changes

  1. MenuBar.kt - Validation logic

    • Added MIN_INOUT_ELEMENTS = 2 constant
    • Pre-save validation in performSave() method
    • User-friendly error dialog (JOptionPane.ERROR_MESSAGE)
    • Returns false to block save operation
    • Covers ALL save paths (Save, Save As, Window Close)
  2. InOutSaveValidationTest.kt (NEW) - Comprehensive tests

    • 5 test cases covering all scenarios (0, 1, 2, 3+ InOuts)
    • Extends AbstractFrameTestBase for EDT handling
    • Uses TempDir for test isolation
    • Uses reflection to test private method
    • Tagged @tag("integration-test")
  3. Documentation (5 NEW files)

    • issues/README.md - Issues directory overview
    • issues/issue-80-final-summary.md - Executive summary
    • issues/issue-80-implementation.md - Implementation guide
    • issues/issue-80-flow-diagram.md - Visual flow diagrams
    • issues/issue-80-visual-mockup.txt - UI mockups
  4. Code Quality Fixes (Commits 584f5bc, 4c3f931, latest)

    • Removed unused AfterEach import from InOutSaveValidationTest.kt
    • Added final newline to MenuBarTest.kt
    • Fixed deprecated constant usage in AbstractPath.kt:
      • PathElement.MINIMAL_MAX_SPEEDdomain.MINIMAL_MAX_SPEED
      • PathElement.ABSOLUTE_MAX_SPEEDdomain.ABSOLUTE_MAX_SPEED
    • Fixed deprecated constant usage in SimpleTrack.kt:
      • StaticTrack.MIN_LENGTHdomain.MIN_TRACK_LENGTH
    • Fixed deprecated constant usage in BaseContext.kt:
      • PathElement.COMMON_MAX_SPEEDdomain.COMMON_MAX_SPEED
      • Removed unused PathElement import
    • Fixed deprecated constant usage in RailSwitch.kt:
      • Added imports for domain.COMMON_BRANCH_SPEED and domain.COMMON_MAIN_SPEED
  5. Test Fix (Commit 8e67858)

    • Updated NavigationModuleKoinTest to match base branch implementation
    • InOut elements ARE OrientedPathSeparators with semaphores
    • Test now correctly expects isPathReservedForTrain to return true
    • Added missing assertion: assertThat(isReserved).isEqualTo(true)

💬 Error Dialog Message

⚠ Cannot Save - Insufficient InOut Elements

Railway network must have at least 2 InOut elements 
(entry and exit points).

Current count: X

InOut elements define where trains enter and exit 
the railway network.
Please add more InOut elements before saving.

              [  OK  ]

📊 Statistics

Code Changes:

  • 10 files changed (+256 lines, -26 lines)
  • MenuBar.kt: +21 -15 (validation logic)
  • InOutSaveValidationTest.kt: +220 (new tests)
  • MenuBarTest.kt: +1 -1 (final newline fix)
  • AbstractPath.kt: +4 -2 (deprecated constant fixes)
  • SimpleTrack.kt: +2 -5 (deprecated constant fix)
  • NavigationModuleKoinTest.kt: +5 -3 (test expectation fix)
  • BaseContext.kt: +2 -2 (deprecated constant fix, unused import removal)
  • RailSwitch.kt: +2 (import fixes)

Documentation:

  • 5 new files (+697 lines)
  • Total changes: +953 lines (code + fixes) + 697 lines (docs) = 1,650 lines

Test Coverage: 100% (5/5 scenarios for GUI validation)


✨ Benefits

Fail-Fast - Error at save time, not reload time
User-Friendly - Clear, actionable error messages with current count
Consistent - Matches XMLContextFactory validation rules (PR #76)
Non-Intrusive - Validates on save, not during editing
Comprehensive - All save paths covered (Save, Save As, Close)
Well-Tested - 5 test cases with 100% coverage
Well-Documented - 5 detailed documentation files (33KB)
Code Quality - Fixed all Detekt warnings (unused imports, deprecated constants)
Test Alignment - Updated tests to match base branch implementation


🧪 Test Coverage

InOut Count Expected Test Case Status
0 Blocked contextWith0InOutsCannotBeSaved
1 Blocked contextWith1InOutCannotBeSaved
2 Allowed contextWith2InOutsCanBeSaved
3+ Allowed contextWith3InOutsCanBeSaved
- Message validationMessageIncludesCurrentInOutCount

🔗 Related Issues


📦 Commits (10 total)

  1. a11af48 - Initial plan
  2. 94a57aa - Core implementation (validation + tests)
  3. 0266397 - Documentation (implementation + flow)
  4. a931cee - Visual mockup
  5. 01f50f1 - Final summary
  6. a3c71a6 - Issues README
  7. 584f5bc - Fix Detekt errors (unused import, deprecated constants in AbstractPath/SimpleTrack)
  8. 8e67858 - Fix NavigationModuleKoinTest (align with base branch)
  9. 4c3f931 - Fix additional Detekt errors (BaseContext, RailSwitch, AbstractPath constants)
  10. [this] - Fix Detekt error (remove unused PathElement import from BaseContext)

🚀 Status

  • Requirements analysis complete
  • Core validation implemented
  • Comprehensive tests written (5 tests)
  • Documentation created (5 files, 33KB)
  • All code quality issues fixed (Detekt passing)
  • Base branch test conflicts resolved
  • CI validation (automated in pipeline)
  • Manual GUI testing (requires full environment with jDisco)
  • Code review and merge

Branch: copilot/add-gui-validation-in-editor
Status: ✅ Implementation Complete - Ready for CI Validation and Code Review
Date: 2026-02-06
Lines Changed: 1,650 (953 code + 697 docs)

Original prompt

This section details on the original issue you should resolve

<issue_title>Add GUI validation to prevent saving contexts with insufficient InOut elements</issue_title>
<issue_description>## Summary
Add validation in the editor GUI to prevent users from saving railway networks with fewer than 2 InOut elements.

Problem

Currently, users can save a context with 0 or 1 InOut elements through the editor, but cannot reload it due to validation added in PR #76. This creates a poor user experience.

Proposed Solution

Add pre-save validation in the editor GUI that:

  1. Checks InOut element count before allowing save
  2. Shows user-friendly error dialog if < 2 InOut elements
  3. Provides clear message: "Railway network must have at least 2 InOut elements (entry and exit points). Current count: X"
  4. Prevents save operation until requirement is met

Benefits

  • User-friendly fail-fast (prevent invalid saves rather than failing on reload)
  • Clearer error messages at the right time
  • Better developer experience

Files to Investigate

  • src/main/kotlin/cz/vutbr/fit/interlockSim/gui/ package
  • Save action handlers

Alternative Approaches

  1. Allow saving with < 2 InOut elements but show warning
  2. Disable save button when < 2 InOut elements
  3. Add "draft mode" for incomplete networks

Related

<agent_instructions>reanalyze and implement please</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@bedaHovorka @claude : is there some optinons now or can we wait for new simulation library?

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Add GUI validation to prevent saving contexts with insufficient InOut elements Add GUI pre-save validation for InOut element count Feb 6, 2026
Copilot AI requested a review from bedaHovorka February 6, 2026 03:10
@bedaHovorka bedaHovorka marked this pull request as ready for review February 6, 2026 03:11
@bedaHovorka bedaHovorka changed the base branch from develop to feature/backlog_2026_02 February 6, 2026 03:56
bedaHovorka

This comment was marked as outdated.

This comment was marked as outdated.

bedaHovorka

This comment was marked as outdated.

bedaHovorka

This comment was marked as outdated.

bedaHovorka

This comment was marked as outdated.

This comment was marked as outdated.

Copilot AI requested a review from bedaHovorka February 6, 2026 12:37
@bedaHovorka bedaHovorka changed the title Add GUI pre-save validation for InOut element count [WIP] Add GUI pre-save validation for InOut element count Feb 6, 2026
@bedaHovorka

This comment was marked as outdated.

@bedaHovorka bedaHovorka force-pushed the feature/backlog_2026_02 branch 2 times, most recently from 7ed71a1 to 0db384f Compare February 7, 2026 07:50
bedaHovorka added a commit that referenced this pull request Mar 27, 2026
- Rename editingContextFactory to xmlContextFactory in OpenAction to avoid
  confusion with EditingContextFactory (reviewer comment MenuBar.kt:73)
- Fix placeholder comment Issue #XXX PR #358 to Issue #80 (MenuBar.kt:103)
- Rename inOutCount to inOutsCount for consistency (MenuBar.kt:202)
- Rename docs/issues/issue-80.md to issue_80.md to match underscore convention
- Update issue_80.md dialog text excerpt to match current implementation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bedaHovorka added a commit that referenced this pull request Mar 27, 2026
- Replace placeholder references "Issue #XXX, PR #358" with correct
  "Issue #80, PR #357" in XMLContextFactory.kt (both saveContext KDocs)
  and XMLContextFactoryOutputStreamTest.kt (@DisplayName annotation)
- Delete docs/issues/issue-80.md stub (redirect to issue_80.md);
  README.md already links to the canonical issue_80.md file

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bedaHovorka bedaHovorka force-pushed the copilot/add-gui-validation-in-editor branch from 5f45559 to ebf274c Compare March 27, 2026 13:45
bedaHovorka added a commit that referenced this pull request Mar 27, 2026
…meters for sonar

Restores the push trigger for copilot/**, feature/**, etc. (removed in previous
commit by mistake). The actual fix for the SonarCloud race condition is to
explicitly pass sonar.pullrequest.* parameters when triggered by a pull_request
event, ensuring SonarCloud uses PR analysis mode (no coverage gate) for PRs.

Previously, both the push-triggered (branch mode, has 80% coverage gate) and
pull_request-triggered (PR mode, no coverage gate) analyses competed, and
whichever arrived at SonarCloud last set the check status — causing #347/#357
to intermittently fail. With explicit PR parameters, the pull_request-triggered
analysis is always identifiable as a PR analysis regardless of race order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI and others added 19 commits March 27, 2026 19:57
… elements

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
…cated constant usage

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
…n imports

Co-authored-by: bedaHovorka <5263405+bedaHovorka@users.noreply.github.com>
- Remove MenuBar private MIN_INOUT_ELEMENTS = 2; extract public
  validateForSave(context) companion method that reads from
  XMLContextFactory.MIN_INOUT_ELEMENTS (= 1, per PR #356)
- Rewrite InOutSaveValidationTest: KoinTestBase, direct validateForSave()
  calls, no EDT/reflection/integration-tag; rename 1InOutCannotBeSaved
  -> 1InOutCanBeSaved; remove unused contextFactory/testFile/dead test
- Remove conflicting COMMON_BRANCH_SPEED/COMMON_MAIN_SPEED imports from
  RailSwitch.kt; unqualified names now resolve to file-level deprecated
  constants as intended
- Add EditingContext + XMLContextFactory imports to MenuBar; replace FQNs
  with short names throughout
- Remove dead inOutsCount < minRequired branch from performSave failure
  path (unreachable after validateForSave guard)
- Compact docs: merge 4 issue-80-*.md files into docs/issues/issue-80.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename editingContextFactory to xmlContextFactory in OpenAction to avoid
  confusion with EditingContextFactory (reviewer comment MenuBar.kt:73)
- Fix placeholder comment Issue #XXX PR #358 to Issue #80 (MenuBar.kt:103)
- Rename inOutCount to inOutsCount for consistency (MenuBar.kt:202)
- Rename docs/issues/issue-80.md to issue_80.md to match underscore convention
- Update issue_80.md dialog text excerpt to match current implementation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace placeholder references "Issue #XXX, PR #358" with correct
  "Issue #80, PR #357" in XMLContextFactory.kt (both saveContext KDocs)
  and XMLContextFactoryOutputStreamTest.kt (@DisplayName annotation)
- Delete docs/issues/issue-80.md stub (redirect to issue_80.md);
  README.md already links to the canonical issue_80.md file

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ar.kt

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…_INOUT_ELEMENTS=1

Addresses review comment PRRT_kwDOQyJ9Cc50Kko4 — dialog text in OpenAction
used "element(s)" which doesn't match the constant (always 1). Aligned with
the wording already used in performSave() dialog.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Constant value assertion: MIN_INOUT_ELEMENTS == 1
- Idempotency: calling validateForSave 3x returns same result
- Large count boundary: 10 InOuts passes validation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Integration test reserves path in vyhybna topology, triggering
AbstractPath.setUpSemaphores() and covering the ABSOLUTE_MAX_SPEED
constant at line 282.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add test with switch preceding semaphore in path, exercising the
previousSwitch.allowedSpeed() non-null branch at line 282.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ger → nonNegativeInteger)

Grid is 0-indexed but XSD required positiveInteger (≥1) for track block
coordinates. Elements at Y=0 or X=0 would save but fail XSD validation
on reload with "Value '0' is not facet-valid for positiveInteger".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread .gitignore Outdated
Comment on lines +79 to +80
.claude/
desktop-ui/aaa.xml
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

desktop-ui/*.xml

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit ca34d22. Changed .gitignore from desktop-ui/aaa.xml to desktop-ui/*.xml to ignore all XML files in the desktop-ui root directory (while still tracking XML files in subdirectories like src/main/resources and src/test/resources).

@sonarqubecloud
Copy link
Copy Markdown

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 GUI validation to prevent saving contexts with insufficient InOut elements

3 participants