Skip to content

Converged naming, import and demo conventions, and fixed four defects it surfaced. - #138

Merged
AlexSkrypnyk merged 14 commits into
mainfrom
feature/converge-conventions
Jul 29, 2026
Merged

Converged naming, import and demo conventions, and fixed four defects it surfaced.#138
AlexSkrypnyk merged 14 commits into
mainfrom
feature/converge-conventions

Conversation

@AlexSkrypnyk

@AlexSkrypnyk AlexSkrypnyk commented Jul 29, 2026

Copy link
Copy Markdown
Member

Summary

An idempotent consistency pass that unifies conventions which had drifted as the codebase grew. Every source, test and playground file was read in full and mapped before any change, so each decision below rests on a measured count rather than an impression.

Convergences backed by a project rule or a clear dominant majority were applied directly. The judgment calls were put to a human and answered, and their outcomes are included here. Two questions turned out not to be rename decisions at all and became follow-up issues instead: #139 and #140.

Along the way the pass surfaced four genuine defects, all of which predate this branch. They are described under Defects fixed below.

Changes

Conventions converged

  1. Import ordering (45 files) - sorted use statements alphabetically across src/, tests/ and playground/; the dominant convention was already case-insensitive alphabetical in 190 of 235 files with two or more imports. Worth recording for future passes: the sort is case-INsensitive, so org\bovigo correctly precedes PHPUnit. A byte-order sort would flip the 11 vfsStream test files backwards and thrash on the next run.
  2. Widget constructor seed value (10 files) - the nine widget constructors spelled the same seed value five ways ($buffer, $default, $current, $value, $point); they are now uniformly $default. Confirm and Suggest give up constructor promotion so the parameter can be named for what a caller passes while the property stays named for the live state it holds, and Rector is told to leave that pairing alone in Confirm.
  3. Test group attribute (34 files) - the #[Group] attribute followed two rival conventions, a directory name on 62 classes and a blanket tui on the rest, which meant no group could select a subsystem. The directory name now decides it everywhere. Tests at the root of Unit keep tui, matching the facade they cover at the root of src.
  4. Shared test themes (9 files) - one helper name meant three different themes across the suite and its body was copied into eight classes, two of which had silently drifted apart on their colour default. A BuildsThemesTrait now owns both shared themes.
  5. Data provider rows (2 files) - the 2 of 147 providers that yielded unkeyed rows now yield string-keyed rows, so a failing case names itself. This also let one provider narrow its documented return key type from the (int|string) union to string.
  6. Data provider docblocks (1 file) - two bare Data provider. docblocks now name the test they feed, matching the 21 siblings that use Data provider for testX()..
  7. Modal exception type (2 files) - Model\Modal was the one Model class rejecting a declaration with an SPL exception; it now throws the library's own FormException like its six siblings.
  8. Playground interrupt handling (3 files) - the 3 of 64 catch blocks missing the standard // Leave quietly on Ctrl-C. explanation now carry it. Behaviour was already identical in all 64.
  9. Playground newline conventions (2 files) - demo output terminators use PHP_EOL (77 of 78 siblings) and newlines inside single-quoted sample data use chr(10) (5 sibling sites), which keeps the project's single-quote rule. Line splitting and joining of rendered views deliberately keeps its literal "\n", since a view is joined that way on every platform.
  10. Demo vocabulary (30 files) - the table demo listed a blackberry and the option-group demo a rhubarb, neither in the reference vocabulary, and the first is also a brand name the reference bans outright. They become a plum and a cherry, which the reference already names as canonical select options. All 24 affected SVGs were regenerated and audited, and the pty recording anchor was moved with them.

Defects fixed

All four predate this branch.

  • Case folding beyond ASCII - the file picker matched and ordered user-visible filenames with byte-level strtolower/strcasecmp, which leave anything outside ASCII untouched, so a lowercase accented query never matched its uppercase entry. Every other widget folds the same kind of text through the mbstring-aware helper.
  • Unicode glyph in ASCII output - the grid preview and the summary line emitted the Unicode ellipsis whatever the display mode, so a terminal without Unicode was handed a glyph it cannot draw. A layout test asserted that glyph while building an ASCII theme, so it was encoding the bug.
  • Grid column sized short - a grid cell renders one line plus a there-is-more marker, but the column was measured from the raw value lines, so a value whose widest line is its first was sized short and clipped the marker. Rendering and measuring now share one preview method and cannot drift.
  • Width measured in bytes - a progress, rating or loading value is painted, so measuring its raw string counted escape sequences as columns: a rating measured 30 wide where it draws 9. Both the grid cell and the label/value row now measure visible width.

Deferred to follow-up issues

Verification

composer test and composer lint (PHPCS, PHPStan level 9, Rector) were run and green after every individual change, not just at the end. The suite grew from 2210 to 2215 tests as the four defects gained regression coverage. Playground scripts are not covered by the suite, so the changed demos were executed directly and their output confirmed, and both regenerated SVG sets were opened and visually checked.

Re-running the whole convergence produces zero further changes, so the result is idempotent.

Before / After

The largest class is import ordering. A representative file had Model\... hoisted above Input\... and PHPUnit above org\bovigo; after the pass both are sorted case-insensitively:

Before:                                          After:
┌───────────────────────────────────────────────┐┌───────────────────────────────────────────────┐
│ use DrevOps\Tui\Model\Field;                  ││ use DrevOps\Tui\Input\Hint;                   │
│ use DrevOps\Tui\Model\Panel;                  ││ use DrevOps\Tui\Input\ScopedKeyMap;           │
│ use DrevOps\Tui\Input\Hint;                   ││ use DrevOps\Tui\Model\Field;                  │
│ use DrevOps\Tui\Input\ScopedKeyMap;           ││ use DrevOps\Tui\Model\Panel;                  │
│ use PHPUnit\Framework\Attributes\CoversClass; ││ use org\bovigo\vfs\vfsStream;                 │
│ use org\bovigo\vfs\vfsStream;                 ││ use PHPUnit\Framework\Attributes\CoversClass; │
└───────────────────────────────────────────────┘└───────────────────────────────────────────────┘

And the grid cell, whose column was measured without the marker it renders:

Before: measured from the raw lines            After: measured from what the cell shows
┌──────────────────────┐                       ┌────────────────────────┐
│ Notes  Crisp and swe │ <- marker clipped     │ Notes  Crisp and sweet…│
└──────────────────────┘                       └────────────────────────┘

The dominant convention was already case-insensitive alphabetical ordering in 190 of 235 files with two or more imports. The 45 outliers hoisted a Model import above an alphabetically earlier namespace, most often placing Model above Input.
…ses.

Every other data provider in the suite yields string-keyed rows so a failing case names itself. Keying the last two also lets the annotated one narrow its return key type from the (int|string) union to string, matching every documented provider.
The other 21 documented providers in the suite open with "Data provider for testX()." naming the test they feed.
… bare.

The other 60 demos that catch an interrupt carry the same one-line explanation above their exit code.
Demo scripts terminate output with PHP_EOL and spell newlines inside single-quoted sample data as chr(10), which keeps the single-quote rule. The glyph gallery echoed a raw newline instead, and the output-text demo carried a double-quoted markdown sample. Line splitting and joining of rendered views keeps its literal newline, since a view is joined that way regardless of platform.
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change updates widget constructor naming and state initialization, adjusts Unicode-aware rendering and file filtering, changes a modal exception type, centralizes rendering test themes, reorganizes PHPUnit groups, and synchronizes documentation and playground examples.

Changes

Widget rendering and maintenance

Layer / File(s) Summary
Example data and generated asset inputs
docs/content/widgets/*, docs/util/*, playground/*
Fruit and disabled-option examples now use Plum and Cherry; newline handling and Ctrl-C comments were also updated.
Production API and rendering updates
src/Widget/*, src/Theme/DefaultTheme.php, src/Model/Modal.php, rector.php
Constructor defaults are named consistently, widget state initialization is explicit, filtering supports non-ASCII case folding, clipping follows Unicode mode, and hidden modal buttons raise FormException.
Shared test helpers and behavior coverage
tests/phpunit/Traits/*, tests/phpunit/Unit/Primitive/*, tests/phpunit/Unit/Render/*, tests/phpunit/Unit/Theme/*, tests/phpunit/Unit/Widget/FilePickerWidgetTest.php, tests/phpunit/Unit/Model/ModalTest.php
Shared theme builders replace duplicated helpers, rendering tests use plain themes where appropriate, and new assertions cover display-mode markers, Unicode filtering, and modal exceptions.
Test organization and import cleanup
tests/phpunit/Unit/*, src/*, playground/themes/*
PHPUnit group assignments, dataset names, provider documentation, and import ordering were updated without changing the associated test logic.

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

Possibly related PRs

  • drevops/tui#52: Both changes update widget rendering examples and SVG asset-generation inputs.
  • drevops/tui#59: Both changes update option-group examples and static-frame anchoring text.
  • drevops/tui#62: Both changes modify the exception raised for hidden modal buttons.

Suggested labels: A2

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.48% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main theme: standardized naming/import/demo conventions with a few fixes.
✨ 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 feature/converge-conventions

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

@github-actions

This comment has been minimized.

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.09%. Comparing base (372ea7e) to head (06178c7).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #138   +/-   ##
=======================================
  Coverage   99.09%   99.09%           
=======================================
  Files         119      119           
  Lines        4645     4650    +5     
=======================================
+ Hits         4603     4608    +5     
  Misses         42       42           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@AlexSkrypnyk AlexSkrypnyk added the Needs review Pull request needs a review from assigned developers label Jul 29, 2026
The nine widget constructors spelled the same seed value five ways: buffer, default, current, value and point. They all name one thing, the value a widget opens with, and every caller passes it positionally. Confirm and Suggest give up constructor promotion so the parameter can be named for what a caller passes while the property stays named for the live state it holds, and Rector is told to leave that pairing alone in Confirm.
Modal was the one Model class rejecting a declaration with an SPL exception; the other six throw the library's own 'FormException'. The constructor now documents the throw, as five of those siblings already do.
The file picker matched and ordered user-visible entry names with byte-level 'strtolower' and 'strcasecmp', which leave anything outside ASCII untouched, so a lowercase accented query never matched its uppercase entry. Every other widget folds the same kind of text through the mbstring-aware helper. A regression test covers a non-ASCII name.
The grid preview and the summary line both emitted the Unicode ellipsis whatever the display mode, so a terminal without Unicode was handed a glyph it cannot draw. The grid preview now falls back to three dots, and the summary line clips to the full width instead, which is what a table cell already does when it cannot spend a column on the marker. A layout test asserted the glyph while building an ASCII theme, so it was encoding the bug.
The group attribute followed two rival conventions: a directory name on 62 classes and a blanket 'tui' on the rest, which meant no group could select a subsystem. The directory name now decides it everywhere, so the theme, render, translation, primitive and remaining model suites are selectable on their own. Tests at the root of Unit keep 'tui', matching the facade they cover at the root of src. No configuration filtered on these names.
One helper name meant three different themes across the suite, and its body was copied into eight classes. Two of those copies had drifted apart: the output and progress primitive tests defaulted colour opposite ways, so the same call produced different themes. The trait now owns both shared themes, the output test states the colour it relies on rather than leaning on a default, and the conditional-indent helper is renamed for the one thing it varies.
The table demo listed a blackberry and the option-group demo a rhubarb, neither of which is in the reference vocabulary, and the first is also a brand name the reference bans outright. They become a plum and a cherry, which the reference already names as canonical select options. The screenshot specs, the pty recording anchor and the documentation code blocks carry the same values, so all 24 affected SVGs were regenerated and audited.
@github-actions

This comment has been minimized.

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Theme/DefaultTheme.php`:
- Around line 1586-1587: Update the grid sizing performed by
measureColumnBlock() and measureValueWidth() to include the width of the
multiline marker—three columns for the ASCII '...' fallback and one for the
Unicode ellipsis—when measuring the value block. Ensure multiline values reserve
space for the appended marker, and add an assertion covering sizing when the
first line is widest.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2a5ba032-0408-4aef-8692-67bbd1de6d87

📥 Commits

Reviewing files that changed from the base of the PR and between 372ea7e and 30e3d89.

⛔ Files ignored due to path filters (24)
  • docs/assets/widget-select-groups-dark-static-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-select-groups-dark-static-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-select-groups-dark-static-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-select-groups-dark-static.svg is excluded by !**/*.svg
  • docs/assets/widget-select-groups-light-static-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-select-groups-light-static-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-select-groups-light-static-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-select-groups-light-static.svg is excluded by !**/*.svg
  • docs/assets/widget-table-dark-animated-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-table-dark-animated-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-table-dark-animated-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-table-dark-animated.svg is excluded by !**/*.svg
  • docs/assets/widget-table-dark-static-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-table-dark-static-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-table-dark-static-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-table-dark-static.svg is excluded by !**/*.svg
  • docs/assets/widget-table-light-animated-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-table-light-animated-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-table-light-animated-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-table-light-animated.svg is excluded by !**/*.svg
  • docs/assets/widget-table-light-static-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-table-light-static-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-table-light-static-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-table-light-static.svg is excluded by !**/*.svg
📒 Files selected for processing (91)
  • docs/content/widgets/option-groups.mdx
  • docs/content/widgets/table.mdx
  • docs/util/render-widget-svgs.php
  • docs/util/update-assets.php
  • playground/02-widgets-select-groups.php
  • playground/02-widgets-table.php
  • playground/11-display-modes-glyph-gallery.php
  • playground/16-loading-data.php
  • playground/17-query-options.php
  • playground/18-output-text.php
  • playground/19-dynamic-options.php
  • playground/themes/OceanTheme.php
  • rector.php
  • src/Builder/FieldBuilder.php
  • src/Builder/Form.php
  • src/Engine/Engine.php
  • src/Model/Modal.php
  • src/Render/PanelController.php
  • src/Schema/SchemaGenerator.php
  • src/Schema/SchemaValidator.php
  • src/Testing/TuiTester.php
  • src/Theme/DefaultTheme.php
  • src/Tui.php
  • src/Widget/CalendarWidget.php
  • src/Widget/Capability/SelectionCapableTrait.php
  • src/Widget/ConfirmWidget.php
  • src/Widget/FilePickerWidget.php
  • src/Widget/NumberWidget.php
  • src/Widget/PasswordWidget.php
  • src/Widget/PauseWidget.php
  • src/Widget/RatingWidget.php
  • src/Widget/ReorderWidget.php
  • src/Widget/SearchWidget.php
  • src/Widget/SuggestWidget.php
  • src/Widget/TemplateWidget.php
  • src/Widget/TextWidget.php
  • src/Widget/TextareaWidget.php
  • src/Widget/ToggleWidget.php
  • src/Widget/WidgetFactory.php
  • tests/phpunit/Traits/BuildsThemesTrait.php
  • tests/phpunit/Unit/Builder/FormTest.php
  • tests/phpunit/Unit/Derive/DeriveTest.php
  • tests/phpunit/Unit/Engine/EngineConditionalTest.php
  • tests/phpunit/Unit/Input/HintTest.php
  • tests/phpunit/Unit/Input/KeyMapTest.php
  • tests/phpunit/Unit/Model/ButtonsTest.php
  • tests/phpunit/Unit/Model/DateBoundsTest.php
  • tests/phpunit/Unit/Model/ModalTest.php
  • tests/phpunit/Unit/Model/PanelTest.php
  • tests/phpunit/Unit/Model/TableSpecTest.php
  • tests/phpunit/Unit/Primitive/OutputTest.php
  • tests/phpunit/Unit/Primitive/ProgressTest.php
  • tests/phpunit/Unit/ProgressableTest.php
  • tests/phpunit/Unit/Render/AnsiTest.php
  • tests/phpunit/Unit/Render/BoxTest.php
  • tests/phpunit/Unit/Render/ExternalEditorTest.php
  • tests/phpunit/Unit/Render/MarkupTest.php
  • tests/phpunit/Unit/Render/NavigatorTest.php
  • tests/phpunit/Unit/Render/OverlayTest.php
  • tests/phpunit/Unit/Render/PanelControllerTest.php
  • tests/phpunit/Unit/Render/ScrollerTest.php
  • tests/phpunit/Unit/Render/TableTest.php
  • tests/phpunit/Unit/Render/TerminalControlTest.php
  • tests/phpunit/Unit/Render/TerminalTest.php
  • tests/phpunit/Unit/Schema/SchemaGeneratorTest.php
  • tests/phpunit/Unit/Testing/AllWidgetsFormTest.php
  • tests/phpunit/Unit/Testing/KeyEncoderTest.php
  • tests/phpunit/Unit/Testing/KeyStreamTest.php
  • tests/phpunit/Unit/Theme/BuiltinThemesTest.php
  • tests/phpunit/Unit/Theme/OutputRenderTest.php
  • tests/phpunit/Unit/Theme/ProgressRenderTest.php
  • tests/phpunit/Unit/Theme/ScaleRenderTest.php
  • tests/phpunit/Unit/Theme/ThemeConditionalIndentTest.php
  • tests/phpunit/Unit/Theme/ThemeFullscreenTest.php
  • tests/phpunit/Unit/Theme/ThemeLayoutTest.php
  • tests/phpunit/Unit/Theme/ThemeManagerTest.php
  • tests/phpunit/Unit/Theme/ThemeOptionsTest.php
  • tests/phpunit/Unit/Theme/ThemeRenderTest.php
  • tests/phpunit/Unit/Theme/ThemeTest.php
  • tests/phpunit/Unit/Translation/ChromeCatalogTest.php
  • tests/phpunit/Unit/Translation/TranslationRenderTest.php
  • tests/phpunit/Unit/Translation/TranslatorTest.php
  • tests/phpunit/Unit/TuiTest.php
  • tests/phpunit/Unit/Widget/CalendarWidgetTest.php
  • tests/phpunit/Unit/Widget/FilePickerWidgetTest.php
  • tests/phpunit/Unit/Widget/NumberWidgetTest.php
  • tests/phpunit/Unit/Widget/PasswordDisplayTest.php
  • tests/phpunit/Unit/Widget/PasswordWidgetTest.php
  • tests/phpunit/Unit/Widget/SelectWidgetTest.php
  • tests/phpunit/Unit/Widget/TextareaWidgetTest.php
  • tests/phpunit/Unit/Widget/WidgetFactoryTest.php

Comment thread src/Theme/DefaultTheme.php Outdated
A grid cell renders one line plus a there-is-more marker, but the column was measured from the raw value lines, so a value whose first line is its widest was sized short and clipped the marker. Rendering and measuring now share one preview method, which cannot drift. The gap predates the ASCII fallback, which only widened it from one column to three.
@github-actions

This comment has been minimized.

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Theme/DefaultTheme.php`:
- Line 2201: Update the width calculation in the surrounding table-rendering
method to use ANSI-aware width measurement for the rendered result of
columnValuePreview($field, $answers), replacing Strings::length() with
Ansi::width() while preserving the existing label and indentation calculation.
Add a regression case covering a colored progress, rating, or loading preview.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9ce8c289-71b1-47be-ba83-8e74cdc269e5

📥 Commits

Reviewing files that changed from the base of the PR and between 30e3d89 and 3e1ca29.

📒 Files selected for processing (2)
  • src/Theme/DefaultTheme.php
  • tests/phpunit/Unit/Theme/ThemeLayoutTest.php

Comment thread src/Theme/DefaultTheme.php Outdated
A progress, rating or loading value is painted, so measuring its raw string counted every escape sequence as a column: a rating measured 30 wide where it draws 9. Both the grid cell and the label/value row now measure visible width. The row path carried the same fault before the grid cell shared its preview.
@github-actions

Copy link
Copy Markdown
Code Coverage Report:
  2026-07-29 06:36:27

 Summary:
  Classes: 84.03% (100/119)
  Methods: 96.79% (1025/1059)
  Lines:   99.10% (4608/4650)

DrevOps\Tui\Answers\Answer
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Answers\Answers
  Methods: 100.00% (10/10)   Lines: 100.00% ( 21/ 21)
DrevOps\Tui\Answers\Provenance
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Answers\SummaryFormatter
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 22/ 22)
DrevOps\Tui\Answers\ValueFormatter
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  6/  6)
DrevOps\Tui\Builder\FieldBuilder
  Methods:  98.33% (59/60)   Lines:  98.70% (227/230)
DrevOps\Tui\Builder\Form
  Methods:  84.62% (11/13)   Lines:  95.45% ( 63/ 66)
DrevOps\Tui\Builder\LayoutGuard
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Builder\PanelBuilder
  Methods: 100.00% (25/25)   Lines: 100.00% ( 44/ 44)
DrevOps\Tui\Condition\CompositeCondition
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 19/ 19)
DrevOps\Tui\Condition\Condition
  Methods: 100.00% (10/10)   Lines: 100.00% ( 38/ 38)
DrevOps\Tui\Derive\Derive
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 10/ 10)
DrevOps\Tui\Derive\Deriver
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 13/ 13)
DrevOps\Tui\Derive\Transform
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Discovery\AbstractDiscover
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Discovery\Dotenv
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 19/ 19)
DrevOps\Tui\Discovery\JsonValue
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Discovery\PathExists
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  3/  3)
DrevOps\Tui\Discovery\Scan
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 20/ 20)
DrevOps\Tui\Engine\Engine
  Methods: 100.00% (24/24)   Lines: 100.00% (187/187)
DrevOps\Tui\Handler\HandlerRegistry
  Methods:  85.71% ( 6/ 7)   Lines:  95.45% ( 21/ 22)
DrevOps\Tui\Input\Binding
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Input\DefaultKeyMap
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 43/ 43)
DrevOps\Tui\Input\Hint
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  2/  2)
DrevOps\Tui\Input\Key
  Methods:  87.50% ( 7/ 8)   Lines:  63.64% (  7/ 11)
DrevOps\Tui\Input\KeyMap
  Methods: 100.00% (11/11)   Lines: 100.00% ( 61/ 61)
DrevOps\Tui\Input\KeyMapManager
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  8/  8)
DrevOps\Tui\Input\KeyParser
  Methods:  85.71% ( 6/ 7)   Lines:  98.95% ( 94/ 95)
DrevOps\Tui\Input\Scope
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 17/ 17)
DrevOps\Tui\Input\ScopedKeyMap
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% (  4/  4)
DrevOps\Tui\Input\VimKeyMap
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Model\Buttons
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Model\DateBounds
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 28/ 28)
DrevOps\Tui\Model\Field
  Methods:  90.91% (20/22)   Lines:  98.61% (142/144)
DrevOps\Tui\Model\FieldType
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 45/ 45)
DrevOps\Tui\Model\FilePickerConstraints
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 53/ 53)
DrevOps\Tui\Model\FormDefinition
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 31/ 31)
DrevOps\Tui\Model\Modal
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  2/  2)
DrevOps\Tui\Model\NumberBounds
  Methods:  83.33% ( 5/ 6)   Lines:  95.24% ( 20/ 21)
DrevOps\Tui\Model\Option
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Model\Panel
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  3/  3)
DrevOps\Tui\Model\SelectionBounds
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 23/ 23)
DrevOps\Tui\Model\TableSpec
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  9/  9)
DrevOps\Tui\Model\Template
  Methods: 100.00% (19/19)   Lines: 100.00% ( 67/ 67)
DrevOps\Tui\Model\Weekday
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Primitive\Output
  Methods: 100.00% (16/16)   Lines: 100.00% ( 20/ 20)
DrevOps\Tui\Primitive\Progress
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 28/ 28)
DrevOps\Tui\Primitive\ProgressReporter
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  2/  2)
DrevOps\Tui\Render\Ansi
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 22/ 22)
DrevOps\Tui\Render\Box
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Render\ExternalEditor
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 27/ 27)
DrevOps\Tui\Render\HelpSection
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Render\Markup
  Methods: 100.00% (10/10)   Lines: 100.00% ( 69/ 69)
DrevOps\Tui\Render\MarkupSegment
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Render\Navigator
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Render\Overlay
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 24/ 24)
DrevOps\Tui\Render\PanelController
  Methods:  98.11% (52/53)   Lines:  99.74% (377/378)
DrevOps\Tui\Render\Scroller
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 14/ 14)
DrevOps\Tui\Render\Table
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 64/ 64)
DrevOps\Tui\Render\Terminal
  Methods:  95.65% (22/23)   Lines:  96.97% ( 64/ 66)
DrevOps\Tui\Render\TerminalControl
  Methods: 100.00% (11/11)   Lines: 100.00% ( 11/ 11)
DrevOps\Tui\Render\Viewport
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Resolver\EnvNameResolver
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% (  5/  5)
DrevOps\Tui\Resolver\InputResolver
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 30/ 30)
DrevOps\Tui\Schema\AgentHelp
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 67/ 67)
DrevOps\Tui\Schema\DefaultResolver
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Schema\OptionsResolver
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  5/  5)
DrevOps\Tui\Schema\SchemaGenerator
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 46/ 46)
DrevOps\Tui\Schema\SchemaValidator
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 40/ 40)
DrevOps\Tui\Testing\ArrayKeyStream
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Testing\BufferedTerminal
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Testing\KeyEncoder
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 22/ 22)
DrevOps\Tui\Testing\TuiTester
  Methods: 100.00% (14/14)   Lines: 100.00% ( 36/ 36)
DrevOps\Tui\Testing\WidgetRunner
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  5/  5)
DrevOps\Tui\Theme\DefaultTheme
  Methods:  97.01% (130/134)   Lines:  99.27% (680/685)
DrevOps\Tui\Theme\DosTheme
  Methods:  81.25% (13/16)   Lines:  83.33% ( 15/ 18)
DrevOps\Tui\Theme\EmberTheme
  Methods:  66.67% ( 6/ 9)   Lines:  66.67% (  6/  9)
DrevOps\Tui\Theme\FrostTheme
  Methods:  66.67% ( 6/ 9)   Lines:  66.67% (  6/  9)
DrevOps\Tui\Theme\MidnightTheme
  Methods:  66.67% ( 6/ 9)   Lines:  66.67% (  6/  9)
DrevOps\Tui\Theme\MonoTheme
  Methods:  66.67% ( 6/ 9)   Lines:  66.67% (  6/  9)
DrevOps\Tui\Theme\Sgr
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Theme\ThemeManager
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  8/  8)
DrevOps\Tui\Translation\Translator
  Methods: 100.00% (18/18)   Lines: 100.00% ( 87/ 87)
DrevOps\Tui\Tui
  Methods: 100.00% (29/29)   Lines: 100.00% ( 99/ 99)
DrevOps\Tui\Utils\Strings
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 36/ 36)
DrevOps\Tui\Widget\AbstractWidget
  Methods:  95.00% (19/20)   Lines:  98.33% ( 59/ 60)
DrevOps\Tui\Widget\CalendarWidget
  Methods: 100.00% (13/13)   Lines: 100.00% ( 52/ 52)
DrevOps\Tui\Widget\Capability\CompletionCapableTrait
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Widget\Capability\FilterCapableTrait
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Widget\Capability\OptionsCapableTrait
  Methods: 100.00% (10/10)   Lines: 100.00% ( 36/ 36)
DrevOps\Tui\Widget\Capability\PagingCapableTrait
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Widget\Capability\PlaceholderCapableTrait
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Widget\Capability\QueryOptionsCapableTrait
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 35/ 35)
DrevOps\Tui\Widget\Capability\SearchCapableTrait
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  3/  3)
DrevOps\Tui\Widget\Capability\SelectionBoundedTrait
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Widget\Capability\SelectionCapableTrait
  Methods: 100.00% (13/13)   Lines: 100.00% ( 88/ 88)
DrevOps\Tui\Widget\Capability\TextEditCapableTrait
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 34/ 34)
DrevOps\Tui\Widget\ConfirmWidget
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 22/ 22)
DrevOps\Tui\Widget\FilePickerWidget
  Methods: 100.00% (33/33)   Lines: 100.00% (187/187)
DrevOps\Tui\Widget\MatchResult
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Widget\MatchTier
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  6/  6)
DrevOps\Tui\Widget\Matcher
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 73/ 73)
DrevOps\Tui\Widget\NumberWidget
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 36/ 36)
DrevOps\Tui\Widget\PasswordDisplay
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  5/  5)
DrevOps\Tui\Widget\PasswordWidget
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 46/ 46)
DrevOps\Tui\Widget\PauseWidget
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 11/ 11)
DrevOps\Tui\Widget\RatingWidget
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 25/ 25)
DrevOps\Tui\Widget\ReorderWidget
  Methods: 100.00% (11/11)   Lines: 100.00% ( 58/ 58)
DrevOps\Tui\Widget\SearchWidget
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Widget\SelectWidget
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% (  8/  8)
DrevOps\Tui\Widget\SuggestWidget
  Methods: 100.00% (19/19)   Lines: 100.00% ( 74/ 74)
DrevOps\Tui\Widget\TemplateWidget
  Methods: 100.00% (14/14)   Lines: 100.00% ( 63/ 63)
DrevOps\Tui\Widget\TextWidget
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 18/ 18)
DrevOps\Tui\Widget\TextareaWidget
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 49/ 49)
DrevOps\Tui\Widget\ToggleWidget
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 30/ 30)
DrevOps\Tui\Widget\WidgetFactory
  Methods: 100.00% (13/13)   Lines: 100.00% ( 59/ 59)

@AlexSkrypnyk AlexSkrypnyk changed the title Converged naming, import and demo-script conventions across the codebase. Converged naming, import and demo conventions, and fixed four defects it surfaced. Jul 29, 2026
@AlexSkrypnyk
AlexSkrypnyk merged commit 0a3bda7 into main Jul 29, 2026
12 checks passed
@AlexSkrypnyk
AlexSkrypnyk deleted the feature/converge-conventions branch July 29, 2026 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs review Pull request needs a review from assigned developers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant