first unit tests

This commit is contained in:
Charlie Kindel
2020-06-07 21:44:03 -06:00
parent fcb71c09e4
commit 8730ac6f37
9 changed files with 2416 additions and 7 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,440 @@
//
// MockDriver.cs: A mock ConsoleDriver for unit tests.
//
// Authors:
// Charlie Kindel (github.com/tig)
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using NStack;
namespace Terminal.Gui {
public class MockDriver : ConsoleDriver, IMainLoopDriver {
int cols, rows;
public override int Cols => cols;
public override int Rows => rows;
// The format is rows, columns and 3 values on the last column: Rune, Attribute and Dirty Flag
int [,,] contents;
bool [] dirtyLine;
void UpdateOffscreen ()
{
int cols = Cols;
int rows = Rows;
contents = new int [rows, cols, 3];
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
contents [r, c, 0] = ' ';
contents [r, c, 1] = MakeColor (ConsoleColor.Gray, ConsoleColor.Black);
contents [r, c, 2] = 0;
}
}
dirtyLine = new bool [rows];
for (int row = 0; row < rows; row++)
dirtyLine [row] = true;
}
static bool sync = false;
public MockDriver ()
{
cols = MockConsole.WindowWidth;
rows = MockConsole.WindowHeight; // - 1;
UpdateOffscreen ();
}
bool needMove;
// Current row, and current col, tracked by Move/AddCh only
int ccol, crow;
public override void Move (int col, int row)
{
ccol = col;
crow = row;
if (Clip.Contains (col, row)) {
MockConsole.CursorTop = row;
MockConsole.CursorLeft = col;
needMove = false;
} else {
MockConsole.CursorTop = Clip.Y;
MockConsole.CursorLeft = Clip.X;
needMove = true;
}
}
public override void AddRune (Rune rune)
{
if (Clip.Contains (ccol, crow)) {
if (needMove) {
//MockConsole.CursorLeft = ccol;
//MockConsole.CursorTop = crow;
needMove = false;
}
contents [crow, ccol, 0] = (int)(uint)rune;
contents [crow, ccol, 1] = currentAttribute;
contents [crow, ccol, 2] = 1;
dirtyLine [crow] = true;
} else
needMove = true;
ccol++;
//if (ccol == Cols) {
// ccol = 0;
// if (crow + 1 < Rows)
// crow++;
//}
if (sync)
UpdateScreen ();
}
public override void AddStr (ustring str)
{
foreach (var rune in str)
AddRune (rune);
}
public override void End ()
{
MockConsole.ResetColor ();
MockConsole.Clear ();
}
static Attribute MakeColor (ConsoleColor f, ConsoleColor b)
{
// Encode the colors into the int value.
return new Attribute () { value = ((((int)f) & 0xffff) << 16) | (((int)b) & 0xffff) };
}
public override void Init (Action terminalResized)
{
Colors.TopLevel = new ColorScheme ();
Colors.Base = new ColorScheme ();
Colors.Dialog = new ColorScheme ();
Colors.Menu = new ColorScheme ();
Colors.Error = new ColorScheme ();
Clip = new Rect (0, 0, Cols, Rows);
Colors.TopLevel.Normal = MakeColor (ConsoleColor.Green, ConsoleColor.Black);
Colors.TopLevel.Focus = MakeColor (ConsoleColor.White, ConsoleColor.DarkCyan);
Colors.TopLevel.HotNormal = MakeColor (ConsoleColor.DarkYellow, ConsoleColor.Black);
Colors.TopLevel.HotFocus = MakeColor (ConsoleColor.DarkBlue, ConsoleColor.DarkCyan);
Colors.Base.Normal = MakeColor (ConsoleColor.White, ConsoleColor.Blue);
Colors.Base.Focus = MakeColor (ConsoleColor.Black, ConsoleColor.Cyan);
Colors.Base.HotNormal = MakeColor (ConsoleColor.Yellow, ConsoleColor.Blue);
Colors.Base.HotFocus = MakeColor (ConsoleColor.Yellow, ConsoleColor.Cyan);
// Focused,
// Selected, Hot: Yellow on Black
// Selected, text: white on black
// Unselected, hot: yellow on cyan
// unselected, text: same as unfocused
Colors.Menu.HotFocus = MakeColor (ConsoleColor.Yellow, ConsoleColor.Black);
Colors.Menu.Focus = MakeColor (ConsoleColor.White, ConsoleColor.Black);
Colors.Menu.HotNormal = MakeColor (ConsoleColor.Yellow, ConsoleColor.Cyan);
Colors.Menu.Normal = MakeColor (ConsoleColor.White, ConsoleColor.Cyan);
Colors.Menu.Disabled = MakeColor (ConsoleColor.DarkGray, ConsoleColor.Cyan);
Colors.Dialog.Normal = MakeColor (ConsoleColor.Black, ConsoleColor.Gray);
Colors.Dialog.Focus = MakeColor (ConsoleColor.Black, ConsoleColor.Cyan);
Colors.Dialog.HotNormal = MakeColor (ConsoleColor.Blue, ConsoleColor.Gray);
Colors.Dialog.HotFocus = MakeColor (ConsoleColor.Blue, ConsoleColor.Cyan);
Colors.Error.Normal = MakeColor (ConsoleColor.White, ConsoleColor.Red);
Colors.Error.Focus = MakeColor (ConsoleColor.Black, ConsoleColor.Gray);
Colors.Error.HotNormal = MakeColor (ConsoleColor.Yellow, ConsoleColor.Red);
Colors.Error.HotFocus = Colors.Error.HotNormal;
HLine = '\u2500';
VLine = '\u2502';
Stipple = '\u2592';
Diamond = '\u25c6';
ULCorner = '\u250C';
LLCorner = '\u2514';
URCorner = '\u2510';
LRCorner = '\u2518';
LeftTee = '\u251c';
RightTee = '\u2524';
TopTee = '\u22a4';
BottomTee = '\u22a5';
Checked = '\u221a';
UnChecked = ' ';
Selected = '\u25cf';
UnSelected = '\u25cc';
RightArrow = '\u25ba';
LeftArrow = '\u25c4';
UpArrow = '\u25b2';
DownArrow = '\u25bc';
LeftDefaultIndicator = '\u25e6';
RightDefaultIndicator = '\u25e6';
LeftBracket = '[';
RightBracket = ']';
OnMeterSegment = '\u258c';
OffMeterSegement = ' ';
//MockConsole.Clear ();
}
public override Attribute MakeAttribute (Color fore, Color back)
{
return MakeColor ((ConsoleColor)fore, (ConsoleColor)back);
}
int redrawColor = -1;
void SetColor (int color)
{
redrawColor = color;
IEnumerable<int> values = Enum.GetValues (typeof (ConsoleColor))
.OfType<ConsoleColor> ()
.Select (s => (int)s);
if (values.Contains (color & 0xffff)) {
MockConsole.BackgroundColor = (ConsoleColor)(color & 0xffff);
}
if (values.Contains ((color >> 16) & 0xffff)) {
MockConsole.ForegroundColor = (ConsoleColor)((color >> 16) & 0xffff);
}
}
public override void UpdateScreen ()
{
int rows = Rows;
int cols = Cols;
MockConsole.CursorTop = 0;
MockConsole.CursorLeft = 0;
for (int row = 0; row < rows; row++) {
dirtyLine [row] = false;
for (int col = 0; col < cols; col++) {
contents [row, col, 2] = 0;
var color = contents [row, col, 1];
if (color != redrawColor)
SetColor (color);
MockConsole.Write ((char)contents [row, col, 0]);
}
}
}
public override void Refresh ()
{
int rows = Rows;
int cols = Cols;
var savedRow = MockConsole.CursorTop;
var savedCol = MockConsole.CursorLeft;
for (int row = 0; row < rows; row++) {
if (!dirtyLine [row])
continue;
dirtyLine [row] = false;
for (int col = 0; col < cols; col++) {
if (contents [row, col, 2] != 1)
continue;
MockConsole.CursorTop = row;
MockConsole.CursorLeft = col;
for (; col < cols && contents [row, col, 2] == 1; col++) {
var color = contents [row, col, 1];
if (color != redrawColor)
SetColor (color);
MockConsole.Write ((char)contents [row, col, 0]);
contents [row, col, 2] = 0;
}
}
}
MockConsole.CursorTop = savedRow;
MockConsole.CursorLeft = savedCol;
}
public override void UpdateCursor ()
{
//
}
public override void StartReportingMouseMoves ()
{
}
public override void StopReportingMouseMoves ()
{
}
public override void Suspend ()
{
}
int currentAttribute;
public override void SetAttribute (Attribute c)
{
currentAttribute = c.value;
}
Key MapKey (ConsoleKeyInfo keyInfo)
{
switch (keyInfo.Key) {
case ConsoleKey.Escape:
return Key.Esc;
case ConsoleKey.Tab:
return keyInfo.Modifiers == ConsoleModifiers.Shift ? Key.BackTab : Key.Tab;
case ConsoleKey.Home:
return Key.Home;
case ConsoleKey.End:
return Key.End;
case ConsoleKey.LeftArrow:
return Key.CursorLeft;
case ConsoleKey.RightArrow:
return Key.CursorRight;
case ConsoleKey.UpArrow:
return Key.CursorUp;
case ConsoleKey.DownArrow:
return Key.CursorDown;
case ConsoleKey.PageUp:
return Key.PageUp;
case ConsoleKey.PageDown:
return Key.PageDown;
case ConsoleKey.Enter:
return Key.Enter;
case ConsoleKey.Spacebar:
return Key.Space;
case ConsoleKey.Backspace:
return Key.Backspace;
case ConsoleKey.Delete:
return Key.Delete;
case ConsoleKey.Oem1:
case ConsoleKey.Oem2:
case ConsoleKey.Oem3:
case ConsoleKey.Oem4:
case ConsoleKey.Oem5:
case ConsoleKey.Oem6:
case ConsoleKey.Oem7:
case ConsoleKey.Oem8:
case ConsoleKey.Oem102:
case ConsoleKey.OemPeriod:
case ConsoleKey.OemComma:
case ConsoleKey.OemPlus:
case ConsoleKey.OemMinus:
return (Key)((uint)keyInfo.KeyChar);
}
var key = keyInfo.Key;
if (key >= ConsoleKey.A && key <= ConsoleKey.Z) {
var delta = key - ConsoleKey.A;
if (keyInfo.Modifiers == ConsoleModifiers.Control)
return (Key)((uint)Key.ControlA + delta);
if (keyInfo.Modifiers == ConsoleModifiers.Alt)
return (Key)(((uint)Key.AltMask) | ((uint)'A' + delta));
if (keyInfo.Modifiers == ConsoleModifiers.Shift)
return (Key)((uint)'A' + delta);
else
return (Key)((uint)'a' + delta);
}
if (key >= ConsoleKey.D0 && key <= ConsoleKey.D9) {
var delta = key - ConsoleKey.D0;
if (keyInfo.Modifiers == ConsoleModifiers.Alt)
return (Key)(((uint)Key.AltMask) | ((uint)'0' + delta));
if (keyInfo.Modifiers == ConsoleModifiers.Shift)
return (Key)((uint)keyInfo.KeyChar);
return (Key)((uint)'0' + delta);
}
if (key >= ConsoleKey.F1 && key <= ConsoleKey.F10) {
var delta = key - ConsoleKey.F1;
return (Key)((int)Key.F1 + delta);
}
return (Key)(0xffffffff);
}
KeyModifiers keyModifiers = new KeyModifiers ();
public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
{
// Note: Net doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called
(mainLoop.Driver as MockDriver).WindowsKeyPressed = delegate (ConsoleKeyInfo consoleKey) {
var map = MapKey (consoleKey);
if (map == (Key)0xffffffff)
return;
keyHandler (new KeyEvent (map, keyModifiers));
keyUpHandler (new KeyEvent (map, keyModifiers));
};
}
public override void SetColors (ConsoleColor foreground, ConsoleColor background)
{
throw new NotImplementedException ();
}
public override void SetColors (short foregroundColorId, short backgroundColorId)
{
throw new NotImplementedException ();
}
public override void CookMouse ()
{
}
public override void UncookMouse ()
{
}
AutoResetEvent keyReady = new AutoResetEvent (false);
AutoResetEvent waitForProbe = new AutoResetEvent (false);
ConsoleKeyInfo? windowsKeyResult = null;
public Action<ConsoleKeyInfo> WindowsKeyPressed;
MainLoop mainLoop;
void WindowsKeyReader ()
{
while (true) {
waitForProbe.WaitOne ();
windowsKeyResult = MockConsole.ReadKey (true);
keyReady.Set ();
}
}
void IMainLoopDriver.Setup (MainLoop mainLoop)
{
this.mainLoop = mainLoop;
Thread readThread = new Thread (WindowsKeyReader);
readThread.Start ();
}
void IMainLoopDriver.Wakeup ()
{
}
bool IMainLoopDriver.EventsPending (bool wait)
{
long now = DateTime.UtcNow.Ticks;
int waitTimeout;
if (mainLoop.timeouts.Count > 0) {
waitTimeout = (int)((mainLoop.timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
if (waitTimeout < 0)
return true;
} else
waitTimeout = -1;
if (!wait)
waitTimeout = 0;
windowsKeyResult = null;
waitForProbe.Set ();
keyReady.WaitOne (waitTimeout);
return windowsKeyResult.HasValue;
}
void IMainLoopDriver.MainIteration ()
{
if (windowsKeyResult.HasValue) {
if (WindowsKeyPressed != null)
WindowsKeyPressed (windowsKeyResult.Value);
windowsKeyResult = null;
}
}
}
}

View File

@@ -157,21 +157,28 @@ namespace Terminal.Gui {
/// Creates a <see cref="Toplevel"/> and assigns it to <see cref="Top"/> and <see cref="CurrentView"/>
/// </para>
/// </remarks>
public static void Init () => Init (() => Toplevel.Create ());
public static void Init (ConsoleDriver driver = null) => Init (() => Toplevel.Create (), driver);
internal static bool _initialized = false;
/// <summary>
/// Initializes the Terminal.Gui application
/// </summary>
static void Init (Func<Toplevel> topLevelFactory)
static void Init (Func<Toplevel> topLevelFactory, ConsoleDriver driver = null)
{
if (_initialized) return;
// This supports Unit Tests and the passing of a mock driver/loopdriver
if (driver != null) {
Driver = driver;
Driver.Init (TerminalResized);
MainLoop = new MainLoop ((IMainLoopDriver)driver);
SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
}
if (Driver == null) {
var p = Environment.OSVersion.Platform;
IMainLoopDriver mainLoopDriver;
if (UseSystemConsole) {
mainLoopDriver = new NetMainLoop ();
Driver = new NetDriver ();
@@ -199,7 +206,11 @@ namespace Terminal.Gui {
public class RunState : IDisposable {
internal bool closeDriver = true;
internal RunState (Toplevel view)
/// <summary>
/// Initializes a new <see cref="RunState"/> class.
/// </summary>
/// <param name="view"></param>
public RunState (Toplevel view)
{
Toplevel = view;
}
@@ -476,7 +487,7 @@ namespace Terminal.Gui {
}
/// <summary>
/// Shutdown an application initialized with <see cref="Init()"/>
/// Shutdown an application initialized with <see cref="Init(ConsoleDriver)"/>
/// </summary>
/// /// <param name="closeDriver"><c>true</c>Closes the application.<c>false</c>Closes toplevels only.</param>
public static void Shutdown (bool closeDriver = true)

View File

@@ -20,7 +20,7 @@ namespace Terminal.Gui {
/// been called (which sets the <see cref="Toplevel.Running"/> property to false).
/// </para>
/// <para>
/// A Toplevel is created when an application initialzies Terminal.Gui by callling <see cref="Application.Init()"/>.
/// A Toplevel is created when an application initialzies Terminal.Gui by callling <see cref="Application.Init(ConsoleDriver)"/>.
/// The application Toplevel can be accessed via <see cref="Application.Top"/>. Additional Toplevels can be created
/// and run (e.g. <see cref="Dialog"/>s. To run a Toplevel, create the <see cref="Toplevel"/> and
/// call <see cref="Application.Run(Toplevel, bool)"/>.

View File

@@ -6,10 +6,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example", "Example\Example.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui", "Terminal.Gui\Terminal.Gui.csproj", "{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Designer", "Designer\Designer.csproj", "{1228D992-C801-49BB-839A-7BD28A3FFF0A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Designer", "Designer\Designer.csproj", "{1228D992-C801-49BB-839A-7BD28A3FFF0A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UICatalog", "UICatalog\UICatalog.csproj", "{88979F89-9A42-448F-AE3E-3060145F6375}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{8B901EDE-8974-4820-B100-5226917E2990}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -50,6 +52,14 @@ Global
{88979F89-9A42-448F-AE3E-3060145F6375}.Release|Any CPU.Build.0 = Release|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Release|x86.ActiveCfg = Release|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Release|x86.Build.0 = Release|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Debug|x86.ActiveCfg = Debug|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Debug|x86.Build.0 = Debug|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Release|Any CPU.Build.0 = Release|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Release|x86.ActiveCfg = Release|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Terminal.Gui;
using Xunit;
// Alais Console to MockConsole so we don't accidentally use Console
using Console = Terminal.Gui.MockConsole;
// Since Application is a singleton we can't run tests in parallel
[assembly: CollectionBehavior (DisableTestParallelization = true)]
namespace Terminal.Gui {
public class ApplicationTests {
[Fact]
public void TestInitShutdown ()
{
Assert.Null (Application.Current);
Assert.Null (Application.CurrentView);
Assert.Null (Application.Top);
Assert.Null (Application.MainLoop);
Assert.Null (Application.Driver);
Application.Init (new MockDriver ());
Assert.NotNull (Application.Current);
Assert.NotNull (Application.CurrentView);
Assert.NotNull (Application.Top);
Assert.NotNull (Application.MainLoop);
Assert.NotNull (Application.Driver);
// MockDriver is always 80x25
Assert.Equal (80, Application.Driver.Cols);
Assert.Equal (25, Application.Driver.Rows);
Application.Shutdown (true);
Assert.Null (Application.Current);
Assert.Null (Application.CurrentView);
Assert.Null (Application.Top);
Assert.Null (Application.MainLoop);
Assert.Null (Application.Driver);
}
[Fact]
public void TestNewRunState ()
{
var rs = new Application.RunState (null);
Assert.NotNull (rs);
// Should not throw because Toplevel was null
rs.Dispose ();
var top = new Toplevel ();
rs = new Application.RunState (top);
Assert.NotNull (rs);
// Should throw because there's no stack
Assert.Throws<InvalidOperationException> (() => rs.Dispose ());
}
[Fact]
public void TestBeginEnd ()
{
// Setup Mock driver
Application.Init (new MockDriver ());
Assert.NotNull (Application.Driver);
// Test null Toplevel
Assert.Throws<ArgumentNullException> (() => Application.Begin (null));
var top = new Toplevel ();
var rs = Application.Begin (top);
Assert.NotNull (rs);
Assert.Equal (top, Application.Current);
Application.End (rs, true);
Assert.Null (Application.Current);
Assert.Null (Application.CurrentView);
Assert.Null (Application.Top);
Assert.Null (Application.MainLoop);
Assert.Null (Application.Driver);
Application.Shutdown (true);
}
[Fact]
public void TestRequestStop ()
{
// Setup Mock driver
Application.Init (new MockDriver ());
Assert.NotNull (Application.Driver);
var top = new Toplevel ();
var rs = Application.Begin (top);
Assert.NotNull (rs);
Assert.Equal (top, Application.Current);
Application.Iteration = () => {
Application.RequestStop ();
};
Application.Run (top, true);
Application.Shutdown (true);
Assert.Null (Application.Current);
Assert.Null (Application.CurrentView);
Assert.Null (Application.Top);
Assert.Null (Application.MainLoop);
Assert.Null (Application.Driver);
}
[Fact]
public void TestRunningFalse ()
{
// Setup Mock driver
Application.Init (new MockDriver ());
Assert.NotNull (Application.Driver);
var top = new Toplevel ();
var rs = Application.Begin (top);
Assert.NotNull (rs);
Assert.Equal (top, Application.Current);
Application.Iteration = () => {
top.Running = false;
};
Application.Run (top, true);
Application.Shutdown (true);
Assert.Null (Application.Current);
Assert.Null (Application.CurrentView);
Assert.Null (Application.Top);
Assert.Null (Application.MainLoop);
Assert.Null (Application.Driver);
}
[Fact]
public void TestKeyUp ()
{
// Setup Mock driver
Application.Init (new MockDriver ());
Assert.NotNull (Application.Driver);
// Setup some fake kepresses (This)
var input = "Tests";
// Put a control-q in at the end
Console.MockKeyPresses.Push (new ConsoleKeyInfo ('q', ConsoleKey.Q, shift: false, alt: false, control: true));
foreach (var c in input.Reverse()) {
if (char.IsLetter (c)) {
Console.MockKeyPresses.Push (new ConsoleKeyInfo (char.ToLower (c), (ConsoleKey)char.ToUpper (c), shift: char.IsUpper (c), alt: false, control: false));
}
else
{
Console.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)c, shift: false, alt: false, control: false));
}
}
int stackSize = Console.MockKeyPresses.Count;
int iterations = 0;
Application.Iteration = () => {
iterations++;
};
int keyUps = 0;
var output = string.Empty;
Application.Top.KeyUp += (View.KeyEventEventArgs args) => {
if (args.KeyEvent.Key != Key.ControlQ) {
output += (char)args.KeyEvent.KeyValue;
}
keyUps++;
};
Application.Run (Application.Top, true);
// Input string should match output
Assert.Equal (input, output);
// # of key up events should match stack size
Assert.Equal (stackSize, keyUps);
// # of key up events should match # of iterations
Assert.Equal (stackSize, iterations);
Application.Shutdown (true);
Assert.Null (Application.Current);
Assert.Null (Application.CurrentView);
Assert.Null (Application.Top);
Assert.Null (Application.MainLoop);
Assert.Null (Application.Driver);
}
}
}

View File

@@ -0,0 +1,67 @@
using System;
using Terminal.Gui;
using Xunit;
// Alais Console to MockConsole so we don't accidentally use Console
using Console = Terminal.Gui.MockConsole;
namespace Terminal.Gui {
public class ConsoleDriverTests {
[Fact]
public void TestInit ()
{
var driver = new MockDriver ();
driver.Init (() => { });
Assert.Equal (80, Console.BufferWidth);
Assert.Equal (25, Console.BufferHeight);
// MockDriver is always 80x25
Assert.Equal (Console.BufferWidth, driver.Cols);
Assert.Equal (Console.BufferHeight, driver.Rows);
driver.End ();
}
[Fact]
public void TestEnd ()
{
var driver = new MockDriver ();
driver.Init (() => { });
MockConsole.ForegroundColor = ConsoleColor.Red;
Assert.Equal (ConsoleColor.Red, Console.ForegroundColor);
MockConsole.BackgroundColor = ConsoleColor.Green;
Assert.Equal (ConsoleColor.Green, Console.BackgroundColor);
driver.Move (2, 3);
Assert.Equal (2, Console.CursorLeft);
Assert.Equal (3, Console.CursorTop);
driver.End ();
Assert.Equal (0, Console.CursorLeft);
Assert.Equal (0, Console.CursorTop);
Assert.Equal (ConsoleColor.Gray, Console.ForegroundColor);
Assert.Equal (ConsoleColor.Black, Console.BackgroundColor);
}
[Fact]
public void TestSetColors ()
{
var driver = new MockDriver ();
driver.Init (() => { });
Assert.Equal (ConsoleColor.Gray, Console.ForegroundColor);
Assert.Equal (ConsoleColor.Black, Console.BackgroundColor);
Console.ForegroundColor = ConsoleColor.Red;
Assert.Equal (ConsoleColor.Red, Console.ForegroundColor);
Console.BackgroundColor = ConsoleColor.Green;
Assert.Equal (ConsoleColor.Green, Console.BackgroundColor);
Console.ResetColor ();
Assert.Equal (ConsoleColor.Gray, Console.ForegroundColor);
Assert.Equal (ConsoleColor.Black, Console.BackgroundColor);
driver.End ();
}
}
}

View File

@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
<ProjectReference Include="..\UICatalog\UICatalog.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,5 @@
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"parallelizeTestCollections": false,
"parallelizeAssembly": false
}