From c311fb8cbef2787ac7fe02c64474b59710370e00 Mon Sep 17 00:00:00 2001 From: Colin Date: Thu, 22 Aug 2019 23:22:36 +0100 Subject: [PATCH 1/8] Second and subsequent Connections to the telescope driver now no longer trigger resetting the Guide rate and precision. It's assumed they are already set correctly. --- .../TelescopeUnitTests.cs | 33 +++++++++++++++---- Meade.net.Telescope/Telescope.cs | 22 ++++++++----- Meade.net.focuser/Focuser.cs | 6 ++-- Meade.net/ConnectionInfo.cs | 8 +++++ Meade.net/Meade.net.csproj | 1 + Meade.net/SharedResources.cs | 22 +++++++++++-- Meade.net/Wrapper/SharedResourcesWrapper.cs | 12 +++---- 7 files changed, 78 insertions(+), 26 deletions(-) create mode 100644 Meade.net/ConnectionInfo.cs diff --git a/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs b/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs index 6f0f5d0..5150e8d 100644 --- a/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs +++ b/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs @@ -23,6 +23,7 @@ namespace Meade.net.Telescope.UnitTests private Mock _astroMathsMock; private ProfileProperties _profileProperties; + private ConnectionInfo _connectionInfo; [SetUp] public void Setup() @@ -45,6 +46,10 @@ namespace Meade.net.Telescope.UnitTests _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny>())).Returns>( (func) => func()); _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny>())).Returns>((func) => func()); + _connectionInfo = new ConnectionInfo {Connections = 1, SameDevice = 1}; + + _sharedResourcesWrapperMock.Setup(x => x.Connect("Serial", It.IsAny())).Returns( () => _connectionInfo ); + _sharedResourcesWrapperMock.Setup(x => x.ReadProfile()).Returns(_profileProperties); @@ -350,7 +355,7 @@ namespace Meade.net.Telescope.UnitTests _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(firmware); _telescope.Connected = true; - _sharedResourcesWrapperMock.Verify( x => x.Connect("Serial"), Times.Once); + _sharedResourcesWrapperMock.Verify( x => x.Connect("Serial", It.IsAny()), Times.Once); _sharedResourcesWrapperMock.Verify(x => x.SendString(":GZ#"), Times.Once); _sharedResourcesWrapperMock.Verify(x => x.SendBlind($":Rg{_profileProperties.GuideRateArcSecondsPerSecond:00.0}#"),Times.Once); @@ -361,26 +366,26 @@ namespace Meade.net.Telescope.UnitTests public void Connected_Set_SettingTrueWhenTrue_ThenDoesNothing() { ConnectTelescope(); - _sharedResourcesWrapperMock.Verify( x => x.Connect(It.IsAny()),Times.Once); + _sharedResourcesWrapperMock.Verify( x => x.Connect(It.IsAny(), It.IsAny()),Times.Once); //act _telescope.Connected = true; //assert - _sharedResourcesWrapperMock.Verify(x => x.Connect(It.IsAny()), Times.Once); + _sharedResourcesWrapperMock.Verify(x => x.Connect(It.IsAny(), It.IsAny()), Times.Once); } [Test] public void Connected_Set_SettingFalseWhenTrue_ThenDisconnects() { ConnectTelescope(); - _sharedResourcesWrapperMock.Verify(x => x.Connect(It.IsAny()), Times.Once); + _sharedResourcesWrapperMock.Verify(x => x.Connect(It.IsAny(), It.IsAny()), Times.Once); //act _telescope.Connected = false; //assert - _sharedResourcesWrapperMock.Verify(x => x.Disconnect(It.IsAny()), Times.Once()); + _sharedResourcesWrapperMock.Verify(x => x.Disconnect(It.IsAny(), It.IsAny()), Times.Once()); } [Test] @@ -395,7 +400,7 @@ namespace Meade.net.Telescope.UnitTests _telescope.Connected = true; //assert - _sharedResourcesWrapperMock.Verify(x => x.Disconnect(It.IsAny()), Times.Once()); + _sharedResourcesWrapperMock.Verify(x => x.Disconnect(It.IsAny(), It.IsAny()), Times.Once()); } [TestCase("Autostar", "30Ab", false)] @@ -771,6 +776,22 @@ namespace Meade.net.Telescope.UnitTests _sharedResourcesWrapperMock.Verify(x => x.SendChar(":P#"), Times.AtLeastOnce); } + [TestCase("High", false, true)] + [TestCase("High", true, true)] + [TestCase("Low", false, false)] + [TestCase("Low", true, false)] + public void Precision_Set_WhenSecondConnectionMade_ThenTelescopePrecisionNotChanged(string desiredPresision, bool telescopePrecision, bool finalPrecision) + { + _profileProperties.Precision = desiredPresision; + + _connectionInfo.SameDevice = 2; + _connectionInfo.Connections = 2; + + _telescope.Connected = true; + + _sharedResourcesWrapperMock.Verify(x => x.SendChar(":P#"), Times.Never); + } + [Test] public void CanSetPark_Get_ReturnsFalse() { diff --git a/Meade.net.Telescope/Telescope.cs b/Meade.net.Telescope/Telescope.cs index 913033e..0ddd71b 100644 --- a/Meade.net.Telescope/Telescope.cs +++ b/Meade.net.Telescope/Telescope.cs @@ -277,7 +277,6 @@ namespace ASCOM.Meade.net $"Site {actionParameters} not allowed, must be between 1 and 4"); } - break; case "setname": switch (parames[1]) { @@ -374,12 +373,11 @@ namespace ASCOM.Meade.net ReadProfile(); LogMessage("Connected Set", "Connecting to port {0}", _comPort); - _sharedResourcesWrapper.Connect("Serial"); + var connectionInfo = _sharedResourcesWrapper.Connect("Serial", DriverId); try { LogMessage("Connected Set", $"Connected to port {_comPort}. Product: {_sharedResourcesWrapper.ProductName} Version:{_sharedResourcesWrapper.FirmwareVersion}"); - SetLongFormat(true); _userNewerPulseGuiding = IsNewPulseGuidingSupported(); _targetDeclination = InvalidParameter; _targetRightAscension = InvalidParameter; @@ -388,16 +386,22 @@ namespace ASCOM.Meade.net LogMessage("Connected Set", $"New Pulse Guiding Supported: {_userNewerPulseGuiding}"); IsConnected = true; - if (CanSetGuideRates) + if (connectionInfo.SameDevice == 1) { - SetNewGuideRate( _guideRate, "Connect" ); - } + //These settings are applied only when the first device connects to the telescope. + SetLongFormat(true); - SetTelescopePrecision("Connect"); + if (CanSetGuideRates) + { + SetNewGuideRate(_guideRate, "Connect"); + } + + SetTelescopePrecision("Connect"); + } } catch (Exception) { - _sharedResourcesWrapper.Disconnect("Serial"); + _sharedResourcesWrapper.Disconnect("Serial", DriverId); throw; } } @@ -409,7 +413,7 @@ namespace ASCOM.Meade.net else { LogMessage("Connected Set", "Disconnecting from port {0}", _comPort); - _sharedResourcesWrapper.Disconnect("Serial"); + _sharedResourcesWrapper.Disconnect("Serial", DriverId); IsConnected = false; } } diff --git a/Meade.net.focuser/Focuser.cs b/Meade.net.focuser/Focuser.cs index cbd9ad2..b675b31 100644 --- a/Meade.net.focuser/Focuser.cs +++ b/Meade.net.focuser/Focuser.cs @@ -179,7 +179,7 @@ namespace ASCOM.Meade.net try { ReadProfile(); - _sharedResourcesWrapper.Connect("Serial"); + _sharedResourcesWrapper.Connect("Serial", DriverId); try { SelectSite(1); @@ -189,7 +189,7 @@ namespace ASCOM.Meade.net } catch (Exception) { - _sharedResourcesWrapper.Disconnect("Serial"); + _sharedResourcesWrapper.Disconnect("Serial", DriverId); throw; } } @@ -201,7 +201,7 @@ namespace ASCOM.Meade.net else { LogMessage("Connected Set", "Disconnecting from port {0}", _comPort); - _sharedResourcesWrapper.Disconnect("Serial"); + _sharedResourcesWrapper.Disconnect("Serial", DriverId); IsConnected = false; } } diff --git a/Meade.net/ConnectionInfo.cs b/Meade.net/ConnectionInfo.cs new file mode 100644 index 0000000..4da4c7f --- /dev/null +++ b/Meade.net/ConnectionInfo.cs @@ -0,0 +1,8 @@ +namespace ASCOM.Meade.net +{ + public class ConnectionInfo + { + public int Connections { get; set; } + public int SameDevice { get; set; } + } +} \ No newline at end of file diff --git a/Meade.net/Meade.net.csproj b/Meade.net/Meade.net.csproj index eb6cc79..6c5a077 100644 --- a/Meade.net/Meade.net.csproj +++ b/Meade.net/Meade.net.csproj @@ -122,6 +122,7 @@ + Form diff --git a/Meade.net/SharedResources.cs b/Meade.net/SharedResources.cs index 8d27adb..cd5209f 100644 --- a/Meade.net/SharedResources.cs +++ b/Meade.net/SharedResources.cs @@ -260,12 +260,15 @@ namespace ASCOM.Meade.net /// private static readonly Dictionary _connectedDevices = new Dictionary(); + private static readonly Dictionary _connectedDeviceIds = new Dictionary(); + + /// /// This is called in the driver Connect(true) property, /// it add the device id to the list of devices if it's not there and increments the device count. /// /// - public static void Connect(string deviceId) + public static ConnectionInfo Connect(string deviceId, string driverId) { lock (LockObject) { @@ -273,6 +276,10 @@ namespace ASCOM.Meade.net _connectedDevices.Add(deviceId, new DeviceHardware()); _connectedDevices[deviceId].Count++; // increment the value + if (!_connectedDeviceIds.ContainsKey(driverId)) + _connectedDeviceIds.Add(driverId, new DeviceHardware()); + _connectedDeviceIds[driverId].Count++; // increment the value + if (deviceId == "Serial") { if (_connectedDevices[deviceId].Count == 1) @@ -292,10 +299,16 @@ namespace ASCOM.Meade.net FirmwareVersion = SendString(":GVN#"); } } + + return new ConnectionInfo + { + Connections = _connectedDevices[deviceId].Count, + SameDevice = _connectedDeviceIds[driverId].Count + }; } } - public static void Disconnect(string deviceId) + public static void Disconnect(string deviceId, string driverId) { lock (LockObject) { @@ -311,6 +324,11 @@ namespace ASCOM.Meade.net } } } + + if (_connectedDeviceIds.ContainsKey(driverId)) + { + _connectedDeviceIds[driverId].Count--; + } } } diff --git a/Meade.net/Wrapper/SharedResourcesWrapper.cs b/Meade.net/Wrapper/SharedResourcesWrapper.cs index 3417ce6..edb1232 100644 --- a/Meade.net/Wrapper/SharedResourcesWrapper.cs +++ b/Meade.net/Wrapper/SharedResourcesWrapper.cs @@ -4,8 +4,8 @@ namespace ASCOM.Meade.net.Wrapper { public interface ISharedResourcesWrapper { - void Connect(string deviceId); - void Disconnect(string deviceId); + ConnectionInfo Connect(string deviceId, string driverId); + void Disconnect(string deviceId, string driverId); string ProductName { get; } @@ -29,14 +29,14 @@ namespace ASCOM.Meade.net.Wrapper public class SharedResourcesWrapper : ISharedResourcesWrapper { - public void Connect(string deviceId) + public ConnectionInfo Connect(string deviceId, string driverId) { - SharedResources.Connect( deviceId); + return SharedResources.Connect(deviceId, driverId); } - public void Disconnect(string deviceId) + public void Disconnect(string deviceId, string driverId) { - SharedResources.Disconnect(deviceId); + SharedResources.Disconnect(deviceId, driverId); } public string ProductName => SharedResources.ProductName; From efa78ec8a05b40ef1fbbf56489f8d21129c0c97a Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 23 Aug 2019 18:05:10 +0100 Subject: [PATCH 2/8] Attempt to make sure that the setup dialog comes up on top of windows. --- Meade.net/SetupDialogForm.cs | 1 + Meade.net/SetupDialogForm.designer.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/Meade.net/SetupDialogForm.cs b/Meade.net/SetupDialogForm.cs index 874ecbc..2ad1077 100644 --- a/Meade.net/SetupDialogForm.cs +++ b/Meade.net/SetupDialogForm.cs @@ -74,6 +74,7 @@ namespace ASCOM.Meade.net private void SetupDialogForm_Shown(object sender, EventArgs e) { + BringToFront(); Activate(); } diff --git a/Meade.net/SetupDialogForm.designer.cs b/Meade.net/SetupDialogForm.designer.cs index 0f875dd..af1859b 100644 --- a/Meade.net/SetupDialogForm.designer.cs +++ b/Meade.net/SetupDialogForm.designer.cs @@ -152,6 +152,7 @@ namespace ASCOM.Meade.net this.MinimizeBox = false; this.Name = "SetupDialogForm"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.TopMost = true; this.Shown += new System.EventHandler(this.SetupDialogForm_Shown); ((System.ComponentModel.ISupportInitialize)(this.picASCOM)).EndInit(); this.ResumeLayout(false); From c6cab848f92952bd5143d4095e25cac4cc566e69 Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 23 Aug 2019 18:16:02 +0100 Subject: [PATCH 3/8] Another attempt to sort out the dialog appearing behind other windows. --- Meade.net/SetupDialogForm.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Meade.net/SetupDialogForm.cs b/Meade.net/SetupDialogForm.cs index 2ad1077..2c99826 100644 --- a/Meade.net/SetupDialogForm.cs +++ b/Meade.net/SetupDialogForm.cs @@ -72,9 +72,12 @@ namespace ASCOM.Meade.net return profileProperties; } + [DllImport("user32.dll")] + private static extern bool SetForegroundWindow(IntPtr hWnd); + private void SetupDialogForm_Shown(object sender, EventArgs e) { - BringToFront(); + SetForegroundWindow(Handle); Activate(); } From 5476331073284a98c626d5535b193d77968419bf Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 23 Aug 2019 18:57:48 +0100 Subject: [PATCH 4/8] Another attempt to sort out the dialog appearing behind other windows. --- Meade.net/SetupDialogForm.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Meade.net/SetupDialogForm.cs b/Meade.net/SetupDialogForm.cs index 2c99826..a09eb72 100644 --- a/Meade.net/SetupDialogForm.cs +++ b/Meade.net/SetupDialogForm.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel; +using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Forms; @@ -75,8 +76,14 @@ namespace ASCOM.Meade.net [DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); + [DllImport("user32.dll")] + + private static extern bool AllowSetForegroundWindow(int dwProcessId); + private void SetupDialogForm_Shown(object sender, EventArgs e) { + Process currentProcess = Process.GetCurrentProcess(); + AllowSetForegroundWindow(currentProcess.Id); SetForegroundWindow(Handle); Activate(); } From 036fd48bcf1f4f0588fb1dcec857125df0fb15a5 Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 23 Aug 2019 19:16:02 +0100 Subject: [PATCH 5/8] Another attempt to sort out the dialog appearing behind other windows. --- Meade.net/Meade.net.csproj | 1 + Meade.net/SetupDialogForm.cs | 12 +--- Meade.net/Win32Utilities.cs | 106 +++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 Meade.net/Win32Utilities.cs diff --git a/Meade.net/Meade.net.csproj b/Meade.net/Meade.net.csproj index 6c5a077..d8277ba 100644 --- a/Meade.net/Meade.net.csproj +++ b/Meade.net/Meade.net.csproj @@ -135,6 +135,7 @@ + Designer diff --git a/Meade.net/SetupDialogForm.cs b/Meade.net/SetupDialogForm.cs index a09eb72..cac2def 100644 --- a/Meade.net/SetupDialogForm.cs +++ b/Meade.net/SetupDialogForm.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; +using System.Text; using System.Windows.Forms; namespace ASCOM.Meade.net @@ -73,18 +74,9 @@ namespace ASCOM.Meade.net return profileProperties; } - [DllImport("user32.dll")] - private static extern bool SetForegroundWindow(IntPtr hWnd); - - [DllImport("user32.dll")] - - private static extern bool AllowSetForegroundWindow(int dwProcessId); - private void SetupDialogForm_Shown(object sender, EventArgs e) { - Process currentProcess = Process.GetCurrentProcess(); - AllowSetForegroundWindow(currentProcess.Id); - SetForegroundWindow(Handle); + Win32Utilities.BringWindowToFront(Handle); Activate(); } diff --git a/Meade.net/Win32Utilities.cs b/Meade.net/Win32Utilities.cs new file mode 100644 index 0000000..2be80b3 --- /dev/null +++ b/Meade.net/Win32Utilities.cs @@ -0,0 +1,106 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace ASCOM.Meade.net +{ + internal static class Win32Utilities + { + //Win32 API calls necesary to raise an unowned processs main window + + [DllImport("user32.dll")] + + private static extern bool SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); + + [DllImport("user32.dll")] + private static extern bool IsIconic(IntPtr hWnd); + + [DllImport("user32.dll", SetLastError = true)] + private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni); + + [DllImport("user32.dll", SetLastError = true)] + private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId); + + [DllImport("user32.dll")] + private static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); + + [DllImport("user32.dll")] + static extern bool BringWindowToTop(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, Int32 nMaxCount); + + [DllImport("user32.dll")] + private static extern int GetWindowThreadProcessId(IntPtr hWnd, ref Int32 lpdwProcessId); + + [DllImport("User32.dll")] + public static extern IntPtr GetParent(IntPtr hWnd); + + private const int SW_HIDE = 0; + private const int SW_SHOWNORMAL = 1; + private const int SW_NORMAL = 1; + private const int SW_SHOWMINIMIZED = 2; + private const int SW_SHOWMAXIMIZED = 3; + private const int SW_MAXIMIZE = 3; + private const int SW_SHOWNOACTIVATE = 4; + private const int SW_SHOW = 5; + private const int SW_MINIMIZE = 6; + private const int SW_SHOWMINNOACTIVE = 7; + private const int SW_SHOWNA = 8; + private const int SW_RESTORE = 9; + private const int SW_SHOWDEFAULT = 10; + private const int SW_MAX = 10; + + private const uint SPI_GETFOREGROUNDLOCKTIMEOUT = 0x2000; + private const uint SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001; + + private const int SPIF_SENDCHANGE = 0x2; + + + public static void BringWindowToFront(IntPtr hWnd) + { + if (IsIconic(hWnd)) + ShowWindowAsync(hWnd, SW_RESTORE); + + ShowWindowAsync(hWnd, SW_SHOW); + + SetForegroundWindow(hWnd); + + // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm + // Converted to Delphi by Ray Lischner + // Published in The Delphi Magazine 55, page 16 + // Converted to C# by Kevin Gale + IntPtr foregroundWindow = GetForegroundWindow(); + IntPtr Dummy = IntPtr.Zero; + + uint foregroundThreadId = GetWindowThreadProcessId(foregroundWindow, Dummy); + + uint thisThreadId = GetWindowThreadProcessId(hWnd, Dummy); + + if (AttachThreadInput(thisThreadId, foregroundThreadId, true)) + { + BringWindowToTop(hWnd); // IE 5.5 related hack + SetForegroundWindow(hWnd); + AttachThreadInput(thisThreadId, foregroundThreadId, false); + } + + if (GetForegroundWindow() != hWnd) + { + // Code by Daniel P. Stasinski + // Converted to C# by Kevin Gale + IntPtr Timeout = IntPtr.Zero; + SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, Timeout, 0); + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Dummy, SPIF_SENDCHANGE); + BringWindowToTop(hWnd); // IE 5.5 related hack + SetForegroundWindow(hWnd); + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Timeout, SPIF_SENDCHANGE); + } + } + } +} From 9a30e02a4bf0653fab810e044ea85deeb54d236c Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 23 Aug 2019 21:30:12 +0100 Subject: [PATCH 6/8] Started working on the focuser unit testing --- .../AstroMath.UnitTests.csproj | 5 +- AstroMath.UnitTests/app.config | 11 ++ AstroMath.UnitTests/packages.config | 2 +- .../BootstrapAscomProfileStore.ps1 | 36 +++++ .../FocuserUnitTests.cs | 145 ++++++++++++++++++ .../Meade.net.Focuser.UnitTests.csproj | 122 +++++++++++++++ .../Properties/AssemblyInfo.cs | 36 +++++ Meade.net.Focuser.UnitTests/app.config | 11 ++ Meade.net.Focuser.UnitTests/packages.config | 9 ++ .../Meade.net.Telescope.UnitTests.csproj | 4 +- .../TelescopeUnitTests.cs | 2 +- Meade.net.Telescope.UnitTests/app.config | 12 +- Meade.net.Telescope.UnitTests/packages.config | 2 +- Meade.net.focuser/Focuser.cs | 52 ++----- Meade.net.sln | 15 ++ Meade.net/SetupDialogForm.cs | 4 +- 16 files changed, 416 insertions(+), 52 deletions(-) create mode 100644 AstroMath.UnitTests/app.config create mode 100644 Meade.net.Focuser.UnitTests/BootstrapAscomProfileStore.ps1 create mode 100644 Meade.net.Focuser.UnitTests/FocuserUnitTests.cs create mode 100644 Meade.net.Focuser.UnitTests/Meade.net.Focuser.UnitTests.csproj create mode 100644 Meade.net.Focuser.UnitTests/Properties/AssemblyInfo.cs create mode 100644 Meade.net.Focuser.UnitTests/app.config create mode 100644 Meade.net.Focuser.UnitTests/packages.config diff --git a/AstroMath.UnitTests/AstroMath.UnitTests.csproj b/AstroMath.UnitTests/AstroMath.UnitTests.csproj index ad41f58..14292b4 100644 --- a/AstroMath.UnitTests/AstroMath.UnitTests.csproj +++ b/AstroMath.UnitTests/AstroMath.UnitTests.csproj @@ -68,8 +68,8 @@ ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - - ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + ..\packages\System.Threading.Tasks.Extensions.4.5.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll @@ -89,6 +89,7 @@ + diff --git a/AstroMath.UnitTests/app.config b/AstroMath.UnitTests/app.config new file mode 100644 index 0000000..8d5ec5f --- /dev/null +++ b/AstroMath.UnitTests/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/AstroMath.UnitTests/packages.config b/AstroMath.UnitTests/packages.config index 605fe2b..b50b126 100644 --- a/AstroMath.UnitTests/packages.config +++ b/AstroMath.UnitTests/packages.config @@ -4,5 +4,5 @@ - + \ No newline at end of file diff --git a/Meade.net.Focuser.UnitTests/BootstrapAscomProfileStore.ps1 b/Meade.net.Focuser.UnitTests/BootstrapAscomProfileStore.ps1 new file mode 100644 index 0000000..213c64d --- /dev/null +++ b/Meade.net.Focuser.UnitTests/BootstrapAscomProfileStore.ps1 @@ -0,0 +1,36 @@ +<# +This script initializes a bare minimum set of registry entries required for ASCOM.Utilities.Profile to work +without throwing any exceptions. When building on a build server, or on a computer without the ASCOM Platform installed, +it may be useful to execute this script as a build step prior to running any unit tests, or calling any code that relies on +ASCOM.Utilities.Profile. The alternative is to install the ASCOM Platform on the build agent. + +NOTE: This script equires elevated permissions because it creates registry keys in the LocalMachine hive. +#> + +$wow = Test-Path HKLM:\SOFTWARE\Wow6432Node +if ($wow) + { + $root = "HKLM:\SOFTWARE\Wow6432Node" + } +else + { + $root = "HKLM:\SOFTWARE" + } +$ascomRoot = $root + "\ASCOM" + +if (Test-Path $ascomRoot) + { + <# Don't upset an already-existing ASCOM registry #> + exit + } + +<# Create the ASCOM root key and set it's ACL to allow all users read/write access #> +New-Item -Path $root -Name ASCOM –Force +$ascomAcl = Get-Acl $ascomRoot +$aclRule = New-Object System.Security.AccessControl.RegistryAccessRule ("Users","FullControl","Allow") +$ascomAcl.SetAccessRule($aclRule) +$ascomAcl | Set-Acl -Path $ascomRoot + +<# Now create the bare minimum keys required so that ASCOM.Utilities.Profile doesn't crash and burn #> +New-ItemProperty -Path $ascomRoot -Name PlatformVersion -Value "6.1" -PropertyType String –Force +New-ItemProperty -Path $ascomRoot -Name SerTraceFile -Value "C:\SerialTraceAuto.txt" -PropertyType String –Force diff --git a/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs b/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs new file mode 100644 index 0000000..21aa8fa --- /dev/null +++ b/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs @@ -0,0 +1,145 @@ +using ASCOM; +using ASCOM.Meade.net; +using ASCOM.Meade.net.Wrapper; +using ASCOM.Utilities.Interfaces; +using Moq; +using NUnit.Framework; + +namespace Meade.net.Focuser.UnitTests +{ + [TestFixture] + public class FocuserUnitTests + { + private Mock _utilMock; + private Mock _sharedResourcesWrapperMock; + + private ProfileProperties _profileProperties; + + private ASCOM.Meade.net.Focuser _focuser; + + [SetUp] + public void Setup() + { + _profileProperties = new ProfileProperties(); + _profileProperties.TraceLogger = false; + _profileProperties.ComPort = "TestCom1"; + _profileProperties.GuideRateArcSecondsPerSecond = 1.23; + _profileProperties.Precision = "Unchanged"; + + _utilMock = new Mock(); + + _sharedResourcesWrapperMock = new Mock(); + _sharedResourcesWrapperMock.Setup(x => x.ReadProfile()).Returns(() => _profileProperties); + + _focuser = new ASCOM.Meade.net.Focuser(_utilMock.Object, _sharedResourcesWrapperMock.Object); + } + + private void ConnectFocuser() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => TelescopeList.Autostar497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => TelescopeList.Autostar497_31Ee); + _focuser.Connected = true; + } + + [Test] + public void CheckThatClassCreatedProperly() + { + Assert.That(_focuser, Is.Not.Null); + } + + [Test] + public void SetupDialog() + { + _sharedResourcesWrapperMock.Verify(x => x.ReadProfile(), Times.Once); + + _focuser.SetupDialog(); + + _sharedResourcesWrapperMock.Verify(x => x.SetupDialog(), Times.Once); + _sharedResourcesWrapperMock.Verify(x => x.ReadProfile(), Times.Exactly(2)); + } + + [Test] + public void SupportedActions() + { + var supportedActions = _focuser.SupportedActions; + + Assert.That(supportedActions, Is.Not.Null); + Assert.That(supportedActions.Count, Is.EqualTo(0)); + } + + [Test] + public void Action_WhenNotConnected_ThrowsNotConnectedException() + { + var actionName = "Action"; + + var exception = Assert.Throws(() => { var actualResult = _focuser.Action(actionName, string.Empty); }); + } + + [Test] + public void CommandBlind_WhenNotConnected_ThenThrowsNotConnectedException() + { + string expectedMessage = "test blind Message"; + var exception = Assert.Throws(() => { _focuser.CommandBlind(expectedMessage, true); }); + + Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: CommandBlind")); + } + + [Test] + public void CommandBlind_WhenConnected_ThenSendsExpectedMessage() + { + string expectedMessage = "test blind Message"; + + ConnectFocuser(); + + _focuser.CommandBlind(expectedMessage, true); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(expectedMessage), Times.Once); + } + + [Test] + public void CommandBool_WhenNotConnected_ThenThrowsNotConnectedException() + { + string expectedMessage = "test blind Message"; + var exception = Assert.Throws(() => { _focuser.CommandBool(expectedMessage, true); }); + + Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: CommandBool")); + } + + [Test] + public void CommandBool_WhenConnected_ThenSendsExpectedMessage() + { + string expectedMessage = "test blind Message"; + + ConnectFocuser(); + + var exception = Assert.Throws(() => { _focuser.CommandBool(expectedMessage, true); }); + + Assert.That(exception.Message, Is.EqualTo("Method CommandBool is not implemented in this driver.")); + } + + [Test] + public void CommandString_WhenNotConnected_ThenThrowsNotConnectedException() + { + string expectedMessage = "test blind Message"; + var exception = Assert.Throws(() => { _focuser.CommandString(expectedMessage, true); }); + + Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: CommandString")); + } + + [Test] + public void CommandString_WhenConnected_ThenSendsExpectedMessage() + { + string expectedMessage = "expected result message"; + string sendMessage = "test blind Message"; + + ConnectFocuser(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(sendMessage)).Returns(() => expectedMessage); + + var actualMessage = _focuser.CommandString(sendMessage, true); + + _sharedResourcesWrapperMock.Verify(x => x.SendString(sendMessage), Times.Once); + Assert.That(actualMessage, Is.EqualTo(expectedMessage)); + } + } +} diff --git a/Meade.net.Focuser.UnitTests/Meade.net.Focuser.UnitTests.csproj b/Meade.net.Focuser.UnitTests/Meade.net.Focuser.UnitTests.csproj new file mode 100644 index 0000000..8181584 --- /dev/null +++ b/Meade.net.Focuser.UnitTests/Meade.net.Focuser.UnitTests.csproj @@ -0,0 +1,122 @@ + + + + + + Debug + AnyCPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30} + Library + Properties + Meade.net.Focuser.UnitTests + Meade.net.Focuser.UnitTests + v4.7.2 + 512 + true + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Astrometry.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Attributes.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Cache.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Controls.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DeviceInterfaces.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DriverAccess.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Exceptions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Internal.Extensions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.SettingsProvider.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.Video.dll + + + ..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll + + + ..\packages\Moq.4.12.0\lib\net45\Moq.dll + + + ..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll + + + + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + + + + + + + + + + + + + + + + + + + {a97e3aec-f11d-49da-b259-de99da813a86} + Meade.net.focuser + + + {3689a2cb-94c5-4012-a5cf-7e7d1dd27143} + Meade.net + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/Meade.net.Focuser.UnitTests/Properties/AssemblyInfo.cs b/Meade.net.Focuser.UnitTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..61a9edd --- /dev/null +++ b/Meade.net.Focuser.UnitTests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Meade.net.Focuser.UnitTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Meade.net.Focuser.UnitTests")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a3991fa7-23c3-405a-96f9-5ab03ac58f30")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Meade.net.Focuser.UnitTests/app.config b/Meade.net.Focuser.UnitTests/app.config new file mode 100644 index 0000000..8d5ec5f --- /dev/null +++ b/Meade.net.Focuser.UnitTests/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Meade.net.Focuser.UnitTests/packages.config b/Meade.net.Focuser.UnitTests/packages.config new file mode 100644 index 0000000..1330573 --- /dev/null +++ b/Meade.net.Focuser.UnitTests/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Meade.net.Telescope.UnitTests/Meade.net.Telescope.UnitTests.csproj b/Meade.net.Telescope.UnitTests/Meade.net.Telescope.UnitTests.csproj index 23613aa..930def6 100644 --- a/Meade.net.Telescope.UnitTests/Meade.net.Telescope.UnitTests.csproj +++ b/Meade.net.Telescope.UnitTests/Meade.net.Telescope.UnitTests.csproj @@ -104,8 +104,8 @@ ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll - - ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + ..\packages\System.Threading.Tasks.Extensions.4.5.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll diff --git a/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs b/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs index 5150e8d..cb74535 100644 --- a/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs +++ b/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs @@ -41,7 +41,7 @@ namespace Meade.net.Telescope.UnitTests _sharedResourcesWrapperMock = new Mock(); _sharedResourcesWrapperMock.Setup(x => x.SendString(":GZ#")).Returns("DDD*MM’SS"); - _sharedResourcesWrapperMock.Setup(x => x.ReadProfile()).Returns(_profileProperties); + _sharedResourcesWrapperMock.Setup(x => x.ReadProfile()).Returns(() =>_profileProperties); _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny())).Callback(action => { action(); }); _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny>())).Returns>( (func) => func()); _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny>())).Returns>((func) => func()); diff --git a/Meade.net.Telescope.UnitTests/app.config b/Meade.net.Telescope.UnitTests/app.config index 312e994..ea6ff10 100644 --- a/Meade.net.Telescope.UnitTests/app.config +++ b/Meade.net.Telescope.UnitTests/app.config @@ -1,11 +1,15 @@ - + - - + + + + + + - + diff --git a/Meade.net.Telescope.UnitTests/packages.config b/Meade.net.Telescope.UnitTests/packages.config index b360f81..4c380c0 100644 --- a/Meade.net.Telescope.UnitTests/packages.config +++ b/Meade.net.Telescope.UnitTests/packages.config @@ -5,5 +5,5 @@ - + \ No newline at end of file diff --git a/Meade.net.focuser/Focuser.cs b/Meade.net.focuser/Focuser.cs index b675b31..0b7b896 100644 --- a/Meade.net.focuser/Focuser.cs +++ b/Meade.net.focuser/Focuser.cs @@ -66,12 +66,21 @@ namespace ASCOM.Meade.net public Focuser() { //todo move this out to IOC - _utilities = new Util(); //Initialise util object + var util = new Util(); //Initialise util object + _utilities = util; _sharedResourcesWrapper = new SharedResourcesWrapper(); Initialise(); } + public Focuser(IUtil util, ISharedResourcesWrapper sharedResourcesWrapper) + { + _utilities = util; + _sharedResourcesWrapper = sharedResourcesWrapper; + + Initialise(); + } + private void Initialise() { //todo move the TraceLogger out to a factory class. @@ -118,7 +127,7 @@ namespace ASCOM.Meade.net public string Action(string actionName, string actionParameters) { LogMessage("", "Action {0}, parameters {1} not implemented", actionName, actionParameters); - throw new ActionNotImplementedException("Action " + actionName + " is not implemented by this driver"); + throw new ActionNotImplementedException(); } public void CommandBlind(string command, bool raw) @@ -149,8 +158,7 @@ namespace ASCOM.Meade.net // then all communication calls this function // you need something to ensure that only one command is in progress at a time return _sharedResourcesWrapper.SendString(command); - - throw new MethodNotImplementedException("CommandString"); + //throw new ASCOM.MethodNotImplementedException("CommandString"); } public void Dispose() @@ -182,9 +190,6 @@ namespace ASCOM.Meade.net _sharedResourcesWrapper.Connect("Serial", DriverId); try { - SelectSite(1); - SetLongFormat(true); - IsConnected = true; } catch (Exception) @@ -207,37 +212,6 @@ namespace ASCOM.Meade.net } } - private void SetLongFormat(bool setLongFormat) - { - _sharedResourcesWrapper.Lock(() => - { - var result = _sharedResourcesWrapper.SendString(":GZ#"); - //:GZ# Get telescope azimuth - //Returns: DDD*MM#T or DDD*MM’SS# - //The current telescope Azimuth depending on the selected precision. - - bool isLongFormat = result.Length > 6; - - if (isLongFormat != setLongFormat) - { - _utilities.WaitForMilliseconds(500); - _sharedResourcesWrapper.SendBlind(":U#"); - //:U# Toggle between low/hi precision positions - //Low - RA displays and messages HH:MM.T sDD*MM - //High - Dec / Az / El displays and messages HH:MM: SS sDD*MM:SS - // Returns Nothing - } - }); - } - - private void SelectSite(int site) - { - _sharedResourcesWrapper.SendBlind($":W{site}#"); - //:W# - //Set current site to, an ASCII digit in the range 1..4 - //Returns: Nothing - } - public string Description { // TODO customise this device description @@ -568,7 +542,7 @@ namespace ASCOM.Meade.net { if (!IsConnected) { - throw new NotConnectedException(message); + throw new NotConnectedException($"Not connected to focuser when trying to execute: {message}"); } } diff --git a/Meade.net.sln b/Meade.net.sln index a77a62d..e916044 100644 --- a/Meade.net.sln +++ b/Meade.net.sln @@ -23,6 +23,8 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Meade.net.Setup", "Meade.ne EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meade.net.Telescope.UnitTests", "Meade.net.Telescope.UnitTests\Meade.net.Telescope.UnitTests.csproj", "{B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meade.net.Focuser.UnitTests", "Meade.net.Focuser.UnitTests\Meade.net.Focuser.UnitTests.csproj", "{A3991FA7-23C3-405A-96F9-5AB03AC58F30}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -120,6 +122,18 @@ Global {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Release|x64.Build.0 = Release|Any CPU {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Release|x86.ActiveCfg = Release|x86 {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Release|x86.Build.0 = Release|x86 + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Debug|x64.ActiveCfg = Debug|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Debug|x64.Build.0 = Debug|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Debug|x86.ActiveCfg = Debug|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Debug|x86.Build.0 = Debug|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Release|Any CPU.Build.0 = Release|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Release|x64.ActiveCfg = Release|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Release|x64.Build.0 = Release|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Release|x86.ActiveCfg = Release|Any CPU + {A3991FA7-23C3-405A-96F9-5AB03AC58F30}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -129,6 +143,7 @@ Global {AABC96B8-C462-4B3A-9B5F-2929E3CB7A49} = {BF650D97-AF98-4638-9C55-21311C6D88DA} {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95} = {0958D817-269C-44BE-BEFB-F3E6A409DE91} {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33} = {0958D817-269C-44BE-BEFB-F3E6A409DE91} + {A3991FA7-23C3-405A-96F9-5AB03AC58F30} = {0958D817-269C-44BE-BEFB-F3E6A409DE91} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3C0509DC-C7F5-48DC-920D-DCFD9C879BD2} diff --git a/Meade.net/SetupDialogForm.cs b/Meade.net/SetupDialogForm.cs index cac2def..645ca81 100644 --- a/Meade.net/SetupDialogForm.cs +++ b/Meade.net/SetupDialogForm.cs @@ -55,7 +55,7 @@ namespace ASCOM.Meade.net { cboPrecision.SelectedItem = profileProperties.Precision; } - catch (Exception e) + catch (Exception) { cboPrecision.SelectedItem = "Unchanged"; } @@ -95,7 +95,7 @@ namespace ASCOM.Meade.net lblPercentOfSiderealRate.Text = $"({percentOfSideReal:00.0}% of sidereal rate)"; _guideRateValid = true; } - catch (Exception exception) + catch (Exception) { //Surpressing this exception as if the value is not valid then it's not useful. _guideRateValid = false; From 7ed79d695464031c3ab0ac7ba3632045cfdddd27 Mon Sep 17 00:00:00 2001 From: Colin Date: Sat, 24 Aug 2019 16:40:15 +0100 Subject: [PATCH 7/8] Added more code towards focuser unit testing --- .../FocuserUnitTests.cs | 239 +++++++++++++++++- .../TelescopeUnitTests.cs | 2 +- Meade.net.focuser/Focuser.cs | 13 +- 3 files changed, 247 insertions(+), 7 deletions(-) diff --git a/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs b/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs index 21aa8fa..638cb56 100644 --- a/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs +++ b/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs @@ -1,4 +1,6 @@ -using ASCOM; +using System; +using ASCOM; +using ASCOM.DeviceInterface; using ASCOM.Meade.net; using ASCOM.Meade.net.Wrapper; using ASCOM.Utilities.Interfaces; @@ -47,6 +49,12 @@ namespace Meade.net.Focuser.UnitTests Assert.That(_focuser, Is.Not.Null); } + [Test] + public void NotConnectedByDefault() + { + Assert.That(_focuser.Connected, Is.False); + } + [Test] public void SetupDialog() { @@ -141,5 +149,234 @@ namespace Meade.net.Focuser.UnitTests _sharedResourcesWrapperMock.Verify(x => x.SendString(sendMessage), Times.Once); Assert.That(actualMessage, Is.EqualTo(expectedMessage)); } + + [TestCase(true)] + [TestCase(false)] + public void Connected_Get_ReturnsExpectedValue(bool expectedConnected) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => TelescopeList.Autostar497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => TelescopeList.Autostar497_31Ee); + _focuser.Connected = expectedConnected; + + Assert.That(_focuser.Connected, Is.EqualTo(expectedConnected)); + } + + [Test] + public void Connected_Set_WhenConnecting_Then_ConnectsToSerialDevice() + { + var productName = "LX2001"; + var firmware = string.Empty; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(productName); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(firmware); + _focuser.Connected = true; + + _sharedResourcesWrapperMock.Verify(x => x.Connect("Serial", It.IsAny()), Times.Once); + } + + + [Test] + public void Connected_Set_SettingTrueWhenTrue_ThenDoesNothing() + { + ConnectFocuser(); + _sharedResourcesWrapperMock.Verify(x => x.Connect(It.IsAny(), It.IsAny()), Times.Once); + + //act + _focuser.Connected = true; + + //assert + _sharedResourcesWrapperMock.Verify(x => x.Connect(It.IsAny(), It.IsAny()), Times.Once); + } + + [Test] + public void Connected_Set_SettingFalseWhenTrue_ThenDisconnects() + { + ConnectFocuser(); + _sharedResourcesWrapperMock.Verify(x => x.Connect(It.IsAny(), It.IsAny()), Times.Once); + + //act + _focuser.Connected = false; + + //assert + _sharedResourcesWrapperMock.Verify(x => x.Disconnect(It.IsAny(), It.IsAny()), Times.Once()); + } + + //Commented out for now as the catch after connect is currently unreachable code. + //[Test] + //public void Connected_Set_WhenFailsToConnect_ThenDisconnects() + //{ + // _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => TelescopeList.Autostar497); + // _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => TelescopeList.Autostar497_31Ee); + + // _sharedResourcesWrapperMock.Setup(x => x.SendString(It.IsAny())).Throws(new Exception("TestFailed")); + + // //act + // _focuser.Connected = true; + + // //assert + // _sharedResourcesWrapperMock.Verify(x => x.Disconnect(It.IsAny(), It.IsAny()), Times.Once()); + //} + + [Test] + public void Description_Get() + { + var expectedDescription = "Meade Generic"; + + var description = _focuser.Description; + + Assert.That(description, Is.EqualTo(expectedDescription)); + } + + [Test] + public void DriverVersion_Get() + { + Version version = System.Reflection.Assembly.GetAssembly(typeof(ASCOM.Meade.net.Focuser)).GetName().Version; + + string exptectedDriverInfo = $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"; + + var driverVersion = _focuser.DriverVersion; + + Assert.That(driverVersion, Is.EqualTo(exptectedDriverInfo)); + } + + [Test] + public void DriverInfo_Get() + { + Version version = System.Reflection.Assembly.GetAssembly(typeof(ASCOM.Meade.net.Focuser)).GetName().Version; + + string exptectedDriverInfo = $"{_focuser.Description} .net driver. Version: {_focuser.DriverVersion}"; + + var driverInfo = _focuser.DriverInfo; + + Assert.That(driverInfo, Is.EqualTo(exptectedDriverInfo)); + } + + [Test] + public void InterfaceVersion_Get() + { + var interfaceVersion = _focuser.InterfaceVersion; + Assert.That(interfaceVersion, Is.EqualTo(3)); + + Assert.That(_focuser, Is.AssignableTo()); + } + + [Test] + public void Name_Get() + { + string expectedName = "Meade Generic"; + + var name = _focuser.Name; + + Assert.That(name, Is.EqualTo(expectedName)); + } + + [Test] + public void Absolute_Get_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _focuser.Absolute; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: Absolute Get")); + } + + [Test] + public void Absolute_Get_WhenConnected_ThenReturnsFalse() + { + ConnectFocuser(); + var result = _focuser.Absolute; + + Assert.That(result, Is.False); + } + + [Test] + public void Halt_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _focuser.Halt(); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: Halt")); + } + + [Test] + public void Halt_WhenConnected_ThenSendsHaltCommand() + { + ConnectFocuser(); + + _focuser.Halt(); + + _sharedResourcesWrapperMock.Verify( x => x.SendBlind(":FQ#"), Times.AtLeastOnce); + _utilMock.Verify( x => x.WaitForMilliseconds(250), Times.AtLeastOnce); + } + + [Test] + public void IsMoving_WhenCalled_ThenReturnsFalse() + { + ConnectFocuser(); + + var result = _focuser.IsMoving; + + Assert.That(result, Is.False); + } + + [TestCase(false)] + [TestCase(true)] + public void Link_Get_ReturnsSameValueAsConnected( bool connected) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => TelescopeList.Autostar497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => TelescopeList.Autostar497_31Ee); + _focuser.Connected = connected; + + Assert.That( _focuser.Link, Is.EqualTo(connected)); + } + + [TestCase(false)] + [TestCase(true)] + public void Link_Set_WhenSet_ThenSetsConnectedState(bool connected) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => TelescopeList.Autostar497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => TelescopeList.Autostar497_31Ee); + _focuser.Link = connected; + + Assert.That(_focuser.Link, Is.EqualTo(connected)); + } + + [Test] + public void MaxIncrement_WhenCalled_ThenReturnsExpectedValue() + { + var result = _focuser.MaxIncrement; + + Assert.That(result, Is.EqualTo(7000)); + } + + [Test] + public void MaxStep_WhenCalled_ThenReturnsExpectedValue() + { + var result = _focuser.MaxStep; + + Assert.That(result, Is.EqualTo(7000)); + } + + [Test] + public void Move_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _focuser.Move(0); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: Move")); + } + + [TestCase(-7001)] + [TestCase(7001)] + public void Move_WhenLargerThanMaxIncrement_ThenThrowsException(int increment) + { + ConnectFocuser(); + + var exception = Assert.Throws(() => { _focuser.Move(increment); }); + Assert.That(exception.Message, Is.EqualTo($"position out of range -{_focuser.MaxIncrement} < {increment} < {_focuser.MaxIncrement}")); + } + + [Test] + public void Move_WhenIncrementIs0_ThenDoesNothing() + { + ConnectFocuser(); + + _focuser.Move(0); + + _utilMock.Verify( x => x.WaitForMilliseconds(It.IsAny()), Times.Never); + } } } diff --git a/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs b/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs index cb74535..3fb595c 100644 --- a/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs +++ b/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs @@ -346,7 +346,7 @@ namespace Meade.net.Telescope.UnitTests } [Test] - public void Connected_Set_WhenConnecting_Then() + public void Connected_Set_WhenConnecting_Then_ConnectsToSerialDevice() { var productName = "LX2001"; var firmware = string.Empty; diff --git a/Meade.net.focuser/Focuser.cs b/Meade.net.focuser/Focuser.cs index 0b7b896..a49bfbe 100644 --- a/Meade.net.focuser/Focuser.cs +++ b/Meade.net.focuser/Focuser.cs @@ -226,10 +226,9 @@ namespace ASCOM.Meade.net { get { - Version version = Assembly.GetExecutingAssembly().GetName().Version; // TODO customise this driver description - string driverInfo = "Information about the driver itself. Version: " + String.Format(CultureInfo.InvariantCulture, "{0}.{1}", version.Major, version.Minor); - Tl.LogMessage("DriverInfo Get", driverInfo); + string driverInfo = $"{Description} .net driver. Version: {DriverVersion}"; + LogMessage("DriverInfo Get", driverInfo); return driverInfo; } } @@ -239,8 +238,8 @@ namespace ASCOM.Meade.net get { Version version = Assembly.GetExecutingAssembly().GetName().Version; - string driverVersion = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", version.Major, version.Minor); - Tl.LogMessage("DriverVersion Get", driverVersion); + string driverVersion = $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"; + LogMessage("DriverVersion Get", driverVersion); return driverVersion; } } @@ -274,6 +273,8 @@ namespace ASCOM.Meade.net { get { + CheckConnected("Absolute Get"); + Tl.LogMessage("Absolute Get", false.ToString()); return false; // This is a relative focuser } @@ -286,6 +287,7 @@ namespace ASCOM.Meade.net CheckConnected("Halt"); //A single halt command is sometimes missed by the #909 apm, so let's do it a few times to be safe. + //todo make this mockable Stopwatch stopwatch = Stopwatch.StartNew(); while (stopwatch.ElapsedMilliseconds < 1000) { @@ -386,6 +388,7 @@ namespace ASCOM.Meade.net _utilities.WaitForMilliseconds(100); //A Single focus command sometimes gets lost on the #909, so sending lots of them solves the issue. + //todo make this mockable Stopwatch stopwatch = Stopwatch.StartNew(); while (stopwatch.ElapsedMilliseconds < steps) { From 77ca457646b0e2b5660ad069195cbbad46f2528d Mon Sep 17 00:00:00 2001 From: Colin Date: Sat, 24 Aug 2019 16:59:24 +0100 Subject: [PATCH 8/8] Finished the basic unit testing for the focuser --- .../FocuserUnitTests.cs | 79 ++++++++++++++++++- Meade.net.focuser/Focuser.cs | 1 - 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs b/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs index 638cb56..9dfd50b 100644 --- a/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs +++ b/Meade.net.Focuser.UnitTests/FocuserUnitTests.cs @@ -6,6 +6,7 @@ using ASCOM.Meade.net.Wrapper; using ASCOM.Utilities.Interfaces; using Moq; using NUnit.Framework; +using NotImplementedException = System.NotImplementedException; namespace Meade.net.Focuser.UnitTests { @@ -31,6 +32,9 @@ namespace Meade.net.Focuser.UnitTests _utilMock = new Mock(); _sharedResourcesWrapperMock = new Mock(); + + _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny())).Callback(action => { action(); }); + _sharedResourcesWrapperMock.Setup(x => x.ReadProfile()).Returns(() => _profileProperties); _focuser = new ASCOM.Meade.net.Focuser(_utilMock.Object, _sharedResourcesWrapperMock.Object); @@ -361,12 +365,12 @@ namespace Meade.net.Focuser.UnitTests [TestCase(-7001)] [TestCase(7001)] - public void Move_WhenLargerThanMaxIncrement_ThenThrowsException(int increment) + public void Move_WhenLargerThanMaxIncrement_ThenThrowsException(int position) { ConnectFocuser(); - var exception = Assert.Throws(() => { _focuser.Move(increment); }); - Assert.That(exception.Message, Is.EqualTo($"position out of range -{_focuser.MaxIncrement} < {increment} < {_focuser.MaxIncrement}")); + var exception = Assert.Throws(() => { _focuser.Move(position); }); + Assert.That(exception.Message, Is.EqualTo($"position out of range -{_focuser.MaxIncrement} < {position} < {_focuser.MaxIncrement}")); } [Test] @@ -378,5 +382,74 @@ namespace Meade.net.Focuser.UnitTests _utilMock.Verify( x => x.WaitForMilliseconds(It.IsAny()), Times.Never); } + + [TestCase(200)] + [TestCase(-200)] + public void Move_WhenIncrementIsNot0_ThenMovesFocuserAndStopsFocuser( int position) + { + ConnectFocuser(); + + _focuser.Move(position); + + if (position < 0) + { + _sharedResourcesWrapperMock.Verify( x => x.SendBlind(":F-#"), Times.AtLeastOnce); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F+#"), Times.Never); + } + else + { + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F-#"), Times.Never); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F+#"), Times.AtLeastOnce); + } + + _sharedResourcesWrapperMock.Verify( x => x.Lock(It.IsAny()), Times.Once); + + _utilMock.Verify(x => x.WaitForMilliseconds(250), Times.AtLeastOnce); + + _utilMock.Verify(x => x.WaitForMilliseconds(100), Times.Once()); + _utilMock.Verify(x => x.WaitForMilliseconds(1000), Times.Once()); + } + + [Test] + public void Position_WhenCalled_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _focuser.Position; }); + Assert.That(exception.Message, Is.EqualTo("Property read Position is not implemented in this driver.")); + } + + [Test] + public void StepSize_WhenCalled_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _focuser.StepSize; }); + Assert.That(exception.Message, Is.EqualTo("Property read StepSize is not implemented in this driver.")); + } + + [Test] + public void TempComp_WhenRead_ThenReturnsFalse() + { + var result = _focuser.TempComp; + Assert.That(result, Is.False); + } + + [Test] + public void TempComp_WhenWrite_ThenThrowsException() + { + var exception = Assert.Throws(() => { _focuser.TempComp = false; }); + Assert.That(exception.Message, Is.EqualTo("Property read TempComp is not implemented in this driver.")); + } + + [Test] + public void TempCompAvailable_WhenRead_ThenReturnsFalse() + { + var result = _focuser.TempCompAvailable; + Assert.That(result, Is.False); + } + + [Test] + public void Temperature_WhenCalled_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _focuser.Temperature; }); + Assert.That(exception.Message, Is.EqualTo("Property read Temperature is not implemented in this driver.")); + } } } diff --git a/Meade.net.focuser/Focuser.cs b/Meade.net.focuser/Focuser.cs index a49bfbe..81362d9 100644 --- a/Meade.net.focuser/Focuser.cs +++ b/Meade.net.focuser/Focuser.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.Runtime.InteropServices; using ASCOM.Utilities; using ASCOM.DeviceInterface; -using System.Globalization; using System.Collections; using System.Reflection; using ASCOM.Meade.net.Wrapper;