-
Notifications
You must be signed in to change notification settings - Fork 735
Fixes #4417. Add example infrastructure for standalone programs with assembly attributes #4427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v2_develop
Are you sure you want to change the base?
Conversation
- Added ExampleMetadataAttribute, ExampleCategoryAttribute, ExampleDemoKeyStrokesAttribute - Added ExampleContext, ExecutionMode, ExampleInfo, ExampleResult, ExampleMetrics classes - Added ExampleDiscovery and ExampleRunner static classes - Updated FakeComponentFactory to support context injection via environment variable - Built successfully with no errors Co-authored-by: tig <[email protected]>
- Updated Example, FluentExample, and RunnableWrapperExample with example attributes - Added support for driver name detection from test context in examples - Created ExampleTests class in UnitTestsParallelizable with tests for: - Example metadata validation - Out-of-process execution - In-process execution - Context serialization - Examples now properly detect and use FakeDriver from test context - Tests pass for metadata validation and serialization Co-authored-by: tig <[email protected]>
- Added #nullable enable directive to all updated examples - All examples now build without warnings Co-authored-by: tig <[email protected]>
- Changed Task.Wait() to task.GetAwaiter().GetResult() to avoid deadlocks - Added named constant for killEntireProcessTree parameter - Added clarifying comment for FakeInput creation - Added comment explaining relative path construction for Examples directory Co-authored-by: tig <[email protected]>
|
@copilot Not happy with the dependency in FakeComponentFactory. See Driver.EnqueueKeyEvent and use that instead? |
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (40.68%) is below the target coverage (70.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## v2_develop #4427 +/- ##
==============================================
- Coverage 77.24% 71.64% -5.60%
==============================================
Files 386 396 +10
Lines 44691 45030 +339
Branches 6277 6312 +35
==============================================
- Hits 34520 32263 -2257
- Misses 8318 10886 +2568
- Partials 1853 1881 +28
... and 56 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
- Removed Terminal.Gui.Examples using statement from FakeComponentFactory - Removed key injection logic from FakeComponentFactory.CreateInput() - Created ExampleContextInjector to handle key injection via Application.Driver.EnqueueKeyEvent - Updated examples to call ExampleContextInjector.SetupAutomaticInjection() before Init - This addresses @tig's comment to use Driver.EnqueueKeyEvent instead of direct FakeInput injection Co-authored-by: tig <[email protected]>
Removed the dependency. Key injection now uses |
…thub.com/gui-cs/Terminal.Gui into copilot/restructure-scenarios-standalone
|
@copilot provide a new ./Example that runs all Examples one after another using this. |
- Created new ExampleRunner example that discovers and runs all examples sequentially - Minimal implementation with no UI - just console output - Discovers examples from Examples directory and runs them with FakeDriver - Shows success/failure status for each example - Returns exit code 0 if all pass, 1 if any fail Note: Key injection via ExampleContextInjector needs debugging for out-of-process mode Co-authored-by: tig <[email protected]>
Created Note: Key injection for out-of-process mode needs additional work as the current |
…thub.com/gui-cs/Terminal.Gui into copilot/restructure-scenarios-standalone
|
@copilot this is all too complicated and isn't gonna work the way I want. I did push some changes you should keep in mind. Let's start over. Add to Application:
|
- Added bool example parameter to Application.Create() - Added static ObservableCollection<IApplication> Apps for external observers - When example=true, metadata is collected and demo keys are sent when first TopRunnable is modal - Removed ExampleContextInjector complexity - Examples now use Application.Create(example: isExample) - Key injection happens via SessionBegun event monitoring TopRunnable.IsModal - Clean, simple architecture that allows external observers to subscribe to Apps collection This addresses @tig's feedback to simplify the approach. Co-authored-by: tig <[email protected]>
Simplified the approach as requested (commit 401db78):
All examples updated and building successfully. |
|
@copilot the example examples shouldnt have any cruft other than the metadata and the extra param to Create. Can the meta data be at end of the cs file? Make the keystrokes meta data support "setdelay: 500" entries that defines how long subsequent keys are delayed. Default to 100. Get rid of pacing param. |
- Removed test context detection cruft from examples - Examples now use Application.Create(example: true) directly - Updated ExampleDemoKeyStrokesAttribute to support "SetDelay:nnn" command - Removed DelayMs parameter from attribute - Default delay between keys is 100ms - SetDelay command changes delay for subsequent keys in sequence - Metadata moved after using statements (before code) - All examples cleaned up and building successfully This addresses @tig's feedback for cleaner examples and better delay control. Co-authored-by: tig <[email protected]>
Done (commit ef263f6):
All examples build successfully. |
|
@copilot note that the runnablewrapperexample intentionally does not quit in esc. Good test of timeout handling You need to always ensure all tests pass before declaring victory. You should run examplerunner yourself. Use CM to set ForceDriver to fake by adding a command line option to do so. |
- Added --fake-driver/-f option to force FakeDriver via ConfigurationManager - Added --timeout/-t option to configure timeout in milliseconds - ExampleRunner no longer injects additional keys (relies on example mode) - Updated RunnableWrapperExample with longer delays (200ms) for better reliability - Examples remain clean with only metadata and Create(example: true) Note: RunnableWrapperExample intentionally doesn't quit on Esc key (tests timeout handling) Tests need additional work to properly coordinate key injection with example mode. Co-authored-by: tig <[email protected]>
Added command line support to ExampleRunner (commit 7ff9e83):
Status:
The issue is that examples use |
|
@copilot instead of just checking ismodal, you need to subscribe to ismodelchanging |
- Changed example mode to subscribe to TopRunnable.IsModalChanged event - When runnable becomes modal (e.Value == true), demo keys are sent - If runnable is already modal when SessionBegun fires, keys are sent immediately - Demo keys sent asynchronously via Task.Run to avoid blocking UI thread - Uses async/await with Task.Delay instead of Thread.Sleep for better responsiveness This addresses @tig's feedback to use IsModalChanged event instead of just checking IsModal property. Note: Examples still timing out - key injection mechanism needs further investigation. Co-authored-by: tig <[email protected]>
Changed to subscribe to
The event-driven approach is now in place, though examples still timeout due to a separate issue with how keys are being processed by FakeDriver's input queue. |
|
@copilot you have the issue # incorrect. It's 4417. |
The PR description already references #4417 at the bottom ("Fixes #4417"), but the PR title says "#3838". I don't have the ability to change the PR title directly - that would need to be updated in the GitHub UI. Should I update any references in commit messages or code comments? |
…thub.com/gui-cs/Terminal.Gui into copilot/restructure-scenarios-standalone
Fixes
UICatalogandScenariodo not support modernIApplicationarch #4417Proposed Changes/Todos
Implements Phase 1 & 2 of restructuring examples as standalone programs discoverable via assembly attributes.
Phase 1: Infrastructure
Attribute System (
Terminal.Gui.Examplesnamespace):ExampleMetadataAttribute- Name, descriptionExampleCategoryAttribute- Categorization (multi-valued)ExampleDemoKeyStrokesAttribute- Automated input sequences with "SetDelay:nnn" supportExecution Infrastructure:
ExampleContext- Configuration (driver, keys, timeouts, mode)ExampleRunner- In-process or out-of-process executionExampleDiscovery- Assembly scanning for attributed examplesExampleInfo,ExampleResult,ExampleMetricsApplication Enhancements:
bool exampleparameter toApplication.Create()ObservableCollection<IApplication> Appsfor external observersexample=true, metadata is collected and demo keys automatically sent when TopRunnable becomes modalKeyboard.RaiseKeyDownEvent()with configurable delaysTopRunnable.IsModalChangedevent for proper timing of key injectionPhase 2: Proof of Concept
Updated Examples:
Example,FluentExample,RunnableWrapperExamplenow have assembly attributesApplication.Create(example: true)with no test-specific cruftExampleRunner Demo:
Examples/ExampleRunnerproject demonstrates the infrastructure--fake-driver/-fto force FakeDriver via ConfigurationManager--timeout/-tto set timeout in milliseconds (default: 5000ms)Test Suite (
UnitTestsParallelizable/Examples):Usage
Clean Example Structure (no cruft):
SetDelay Command:
KeyStrokes = ["SetDelay:500", "a", "b", "c", "SetDelay:100", "Enter"]ExampleRunner:
# Run all examples with FakeDriver dotnet run --project Examples/ExampleRunner -- --fake-driver --timeout 10000Discovery and Execution (for test infrastructure):
Architecture Notes
Example Mode Flow:
Application.Create(example: true)enables example modeSessionBeguneventTopRunnable.IsModalChangedeventKeyboard.RaiseKeyDownEvent()with delays between eachIsModalChanged Event Integration:
IsModalpropertySessionBegunfires, keys are sent immediatelyTask.Runwithasync/awaitfor non-blocking operationExternal Observers:
Application.Appsobservable collection tracks all application instancesImportant Notes
Pull Request checklist:
dotnet testbefore commit///style comments)Original prompt
This section details on the original issue you should resolve
<issue_title>
UICatalogandScenariodo not support modernIApplicationarch</issue_title><issue_description># Problems
Application(legacy) orIApplication(modern), blocking migrationScenario.Main()with artificial inheritanceProposal: Restructure Scenarios as Standalone Programs
Summary
Transform Terminal.Gui examples from class-based Scenarios into standalone programs with:
Solution Architecture
1. Example Metadata Attributes
Location:
Terminal.Guilibrary,Terminal.Gui.ExamplesnamespaceUsage:
2. Test Context Injection (Zero Cruft)
Key Insight: Framework detects environment variable during
Init()and auto-wires monitoring.Implementation in
FakeComponentFactory.CreateInput():Implementation in
ApplicationImpl.Init():3. Example Runner