Fixes #4022 file dialog tests and bugfix for cancellation (#4024)

* Add class for detecting information about console in extensible way

* WIP - Create test for reordering

* Change Dictionary to List and preserve TreeBuilder order

* Add test to ensure branch expansion/status remains consistent despite reorder

* Cleanup code

* Fix regression when removed child was the selected one

* Revert "Add class for detecting information about console in extensible way"

This reverts commit 7e4253cf28.

* Code cleanup and enable nullable on Branch

* Remove color scheme and driver from Branch draw

* Add xunit context extensions

* Investigate codegen for xunit

* Getting closer to something that works

* Fix code generation

* Further explore code gen

* Generate all methods in single class for easier extensibility

* Simplify code gen by moving parameter creation to its own method

* Implement asserts A-I

* Add remaining assert calls that are not obsolete

* Fix unit test

* Roll back versions to be compatible with CI version of csharp

* Handle params and ref etc

* Fix null warning

* WIP - start to add integration tests for FileDialog

* Add ability to tab focus to specific control with simple one line delegate

* Clarify test criteria

* Add unit tests for Ok and other ways of canceling dialog

* Fix other buttons also triggering save

* Fix for linux environment tests

* Fix for linux again

* Fix application null race condition - add better way of knowing if stuff is finished

* Better fix for shutdown detection

* Add test that shows #4026 is not an issue

* Switch to `_fileSystem.Directory.GetLogicalDrives ()`

* Don't show duplicate MyDocuments etc
This commit is contained in:
Thomas Nind
2025-04-16 16:25:07 +01:00
committed by GitHub
parent e02d57675f
commit 8d3d039fb3
14 changed files with 946 additions and 101 deletions

View File

@@ -0,0 +1,197 @@
using System.IO.Abstractions;
using System.IO.Abstractions.TestingHelpers;
using System.Runtime.InteropServices;
using Terminal.Gui;
using TerminalGuiFluentTesting;
using TerminalGuiFluentTestingXunit;
using Xunit.Abstractions;
namespace IntegrationTests.FluentTests;
public class FileDialogFluentTests
{
private readonly TextWriter _out;
public FileDialogFluentTests (ITestOutputHelper outputHelper) { _out = new TestOutputWriter (outputHelper); }
private MockFileSystem CreateExampleFileSystem ()
{
// Optional: use Ordinal to simulate Linux-style case sensitivity
var mockFileSystem = new MockFileSystem (new Dictionary<string, MockFileData> ());
string testDir = mockFileSystem.Path.Combine ("test-dir");
string subDir = mockFileSystem.Path.Combine (testDir, "sub-dir");
string logsDir = "logs";
string emptyDir = "empty-dir";
// Add files
mockFileSystem.AddFile (mockFileSystem.Path.Combine (testDir, "file1.txt"), new MockFileData ("Hello, this is file 1."));
mockFileSystem.AddFile (mockFileSystem.Path.Combine (testDir, "file2.txt"), new MockFileData ("Hello, this is file 2."));
mockFileSystem.AddFile (mockFileSystem.Path.Combine (subDir, "nested-file.txt"), new MockFileData ("This is a nested file."));
mockFileSystem.AddFile (mockFileSystem.Path.Combine (logsDir, "log1.log"), new MockFileData ("Log entry 1"));
mockFileSystem.AddFile (mockFileSystem.Path.Combine (logsDir, "log2.log"), new MockFileData ("Log entry 2"));
// Create an empty directory
mockFileSystem.AddDirectory (emptyDir);
return mockFileSystem;
}
[Theory]
[ClassData (typeof (V2TestDrivers))]
public void CancelFileDialog_UsingEscape (V2TestDriver d)
{
var sd = new SaveDialog ( CreateExampleFileSystem ());
using var c = With.A (sd, 100, 20, d)
.ScreenShot ("Save dialog",_out)
.Escape()
.Stop ();
Assert.True (sd.Canceled);
}
[Theory]
[ClassData (typeof (V2TestDrivers))]
public void CancelFileDialog_UsingCancelButton_TabThenEnter (V2TestDriver d)
{
var sd = new SaveDialog (CreateExampleFileSystem ());
using var c = With.A (sd, 100, 20, d)
.ScreenShot ("Save dialog", _out)
.Focus <Button>(b=> b.Text == "_Cancel")
.Enter ()
.Stop ();
Assert.True (sd.Canceled);
}
[Theory]
[ClassData (typeof (V2TestDrivers))]
public void CancelFileDialog_UsingCancelButton_LeftClickButton (V2TestDriver d)
{
var sd = new SaveDialog (CreateExampleFileSystem ());
using var c = With.A (sd, 100, 20, d)
.ScreenShot ("Save dialog", _out)
.LeftClick <Button> (b => b.Text == "_Cancel")
.Stop ()
.WriteOutLogs (_out);
Assert.True (sd.Canceled);
}
[Theory]
[ClassData (typeof (V2TestDrivers))]
public void CancelFileDialog_UsingCancelButton_AltC (V2TestDriver d)
{
var sd = new SaveDialog (CreateExampleFileSystem ());
using var c = With.A (sd, 100, 20, d)
.ScreenShot ("Save dialog", _out)
.Send (Key.C.WithAlt)
.WriteOutLogs (_out)
.Stop ();
Assert.True (sd.Canceled);
}
[Theory]
[ClassData (typeof (V2TestDrivers))]
public void SaveFileDialog_UsingOkButton_Enter (V2TestDriver d)
{
var fs = CreateExampleFileSystem ();
var sd = new SaveDialog (fs);
using var c = With.A (sd, 100, 20, d)
.ScreenShot ("Save dialog", _out)
.LeftClick<Button> (b => b.Text == "_Save")
.WriteOutLogs (_out)
.Stop ();
Assert.False (sd.Canceled);
AssertIsFileSystemRoot (fs, sd);
}
[Theory]
[ClassData (typeof (V2TestDrivers))]
public void SaveFileDialog_UsingOkButton_AltS (V2TestDriver d)
{
var fs = CreateExampleFileSystem ();
var sd = new SaveDialog (fs);
using var c = With.A (sd, 100, 20, d)
.ScreenShot ("Save dialog", _out)
.Send (Key.S.WithAlt)
.WriteOutLogs (_out)
.Stop ();
Assert.False (sd.Canceled);
AssertIsFileSystemRoot (fs, sd);
}
[Theory]
[ClassData (typeof (V2TestDrivers))]
public void SaveFileDialog_UsingOkButton_TabEnter (V2TestDriver d)
{
var fs = CreateExampleFileSystem ();
var sd = new SaveDialog (fs);
using var c = With.A (sd, 100, 20, d)
.ScreenShot ("Save dialog", _out)
.Focus <Button> (b => b.Text == "_Save")
.Enter ()
.WriteOutLogs (_out)
.Stop ();
Assert.False (sd.Canceled);
AssertIsFileSystemRoot (fs,sd);
}
private void AssertIsFileSystemRoot (IFileSystem fs, SaveDialog sd)
{
var expectedPath =
RuntimeInformation.IsOSPlatform (OSPlatform.Windows) ?
$@"C:{fs.Path.DirectorySeparatorChar}" :
"/";
Assert.Equal (expectedPath, sd.FileName);
}
[Theory]
[ClassData (typeof (V2TestDrivers))]
public void SaveFileDialog_PressingPopTree_ShouldNotChangeCancel (V2TestDriver d)
{
var sd = new SaveDialog (CreateExampleFileSystem ()) { Modal = true };
using var c = With.A (sd, 100, 20, d)
.ScreenShot ("Save dialog", _out)
.AssertTrue (sd.Canceled)
.Focus<Button> (b => b.Text == "►►")
.Enter ()
.ScreenShot ("After pop tree", _out)
.AssertTrue (sd.Canceled)
.WriteOutLogs (_out)
.Stop ();
Assert.True(sd.Canceled);
}
[Theory]
[ClassData (typeof (V2TestDrivers))]
public void SaveFileDialog_PopTree_AndNavigate (V2TestDriver d)
{
var sd = new SaveDialog (CreateExampleFileSystem ()) { Modal = true };
using var c = With.A (sd, 100, 20, d)
.ScreenShot ("Save dialog", _out)
.AssertTrue (sd.Canceled)
.LeftClick <Button> (b => b.Text == "►►")
.ScreenShot ("After pop tree", _out)
.Focus <TreeView<IFileSystemInfo>> (_ => true)
.Right ()
.ScreenShot ("After expand tree", _out)
.Down ()
.ScreenShot ("After navigate down in tree", _out)
.Enter ()
.WaitIteration ()
.AssertFalse (sd.Canceled)
.AssertContains ("empty-dir", sd.FileName)
.WriteOutLogs (_out)
.Stop ();
Assert.False (sd.Canceled);
}
}

View File

@@ -1,5 +1,6 @@
using Terminal.Gui;
using TerminalGuiFluentTesting;
using TerminalGuiFluentTestingXunit;
using Xunit.Abstractions;
namespace IntegrationTests.FluentTests;
@@ -33,7 +34,6 @@ public class TreeViewFluentTests
bike = new ("Bike")
]
};
tv.AddObject (root);
using GuiTestContext context =
@@ -46,10 +46,15 @@ public class TreeViewFluentTests
.Then (() => Assert.Null (tv.GetObjectOnRow (1)))
.Right ()
.ScreenShot ("After expanding", _out)
.AssertEqual (root, tv.GetObjectOnRow (0))
.AssertEqual (car, tv.GetObjectOnRow (1))
.AssertEqual (lorry, tv.GetObjectOnRow (2))
.AssertEqual (bike, tv.GetObjectOnRow (3))
.AssertMultiple (
() =>
{
Assert.Equal (root, tv.GetObjectOnRow (0));
Assert.Equal (car, tv.GetObjectOnRow (1));
Assert.Equal (lorry, tv.GetObjectOnRow (2));
Assert.Equal (bike, tv.GetObjectOnRow (3));
})
.AssertIsAssignableFrom <ITreeNode>(tv.SelectedObject)
.Then (
() =>
{
@@ -59,10 +64,14 @@ public class TreeViewFluentTests
})
.WaitIteration ()
.ScreenShot ("After re-order", _out)
.AssertEqual (root, tv.GetObjectOnRow (0))
.AssertEqual (bike, tv.GetObjectOnRow (1))
.AssertEqual (car, tv.GetObjectOnRow (2))
.AssertEqual (lorry, tv.GetObjectOnRow (3))
.AssertMultiple (
() =>
{
Assert.Equal (root, tv.GetObjectOnRow (0));
Assert.Equal (bike, tv.GetObjectOnRow (1));
Assert.Equal (car, tv.GetObjectOnRow (2));
Assert.Equal (lorry, tv.GetObjectOnRow (3));
})
.WriteOutLogs (_out);
context.Stop ();
@@ -128,15 +137,19 @@ public class TreeViewFluentTests
.Add (tv)
.WaitIteration ()
.ScreenShot ("Initial State", _out)
.AssertEqual (root, tv.GetObjectOnRow (0))
.AssertEqual (car, tv.GetObjectOnRow (1))
.AssertEqual (mrA, tv.GetObjectOnRow (2))
.AssertEqual (mrB, tv.GetObjectOnRow (3))
.AssertEqual (lorry, tv.GetObjectOnRow (4))
.AssertEqual (mrC, tv.GetObjectOnRow (5))
.AssertEqual (bike, tv.GetObjectOnRow (6))
.AssertEqual (mrD, tv.GetObjectOnRow (7))
.AssertEqual (mrE, tv.GetObjectOnRow (8))
.AssertMultiple (
() =>
{
Assert.Equal (root, tv.GetObjectOnRow (0));
Assert.Equal (car, tv.GetObjectOnRow (1));
Assert.Equal (mrA, tv.GetObjectOnRow (2));
Assert.Equal (mrB, tv.GetObjectOnRow (3));
Assert.Equal (lorry, tv.GetObjectOnRow (4));
Assert.Equal (mrC, tv.GetObjectOnRow (5));
Assert.Equal (bike, tv.GetObjectOnRow (6));
Assert.Equal (mrD, tv.GetObjectOnRow (7));
Assert.Equal (mrE, tv.GetObjectOnRow (8));
})
.Then (
() =>
{
@@ -146,15 +159,19 @@ public class TreeViewFluentTests
})
.WaitIteration ()
.ScreenShot ("After re-order", _out)
.AssertEqual (root, tv.GetObjectOnRow (0))
.AssertEqual (bike, tv.GetObjectOnRow (1))
.AssertEqual (mrD, tv.GetObjectOnRow (2))
.AssertEqual (mrE, tv.GetObjectOnRow (3))
.AssertEqual (car, tv.GetObjectOnRow (4))
.AssertEqual (mrA, tv.GetObjectOnRow (5))
.AssertEqual (mrB, tv.GetObjectOnRow (6))
.AssertEqual (lorry, tv.GetObjectOnRow (7))
.AssertEqual (mrC, tv.GetObjectOnRow (8))
.AssertMultiple (
() =>
{
Assert.Equal (root, tv.GetObjectOnRow (0));
Assert.Equal (bike, tv.GetObjectOnRow (1));
Assert.Equal (mrD, tv.GetObjectOnRow (2));
Assert.Equal (mrE, tv.GetObjectOnRow (3));
Assert.Equal (car, tv.GetObjectOnRow (4));
Assert.Equal (mrA, tv.GetObjectOnRow (5));
Assert.Equal (mrB, tv.GetObjectOnRow (6));
Assert.Equal (lorry, tv.GetObjectOnRow (7));
Assert.Equal (mrC, tv.GetObjectOnRow (8));
})
.WriteOutLogs (_out);
context.Stop ();