diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 434f467..6772790 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -147,7 +147,7 @@ jobs: exit 1 } - & $vstest "RandomNumberGenerator.Test\bin\Release\Random Number Generator.Test.dll" /Logger:"console;verbosity=minimal" + & $vstest "tests\RandomNumberGenerator.Test\bin\Release\Random Number Generator.Test.dll" /Logger:"console;verbosity=minimal" if ($LASTEXITCODE -ne 0) { Write-Host "::error::The tests did not pass, so nothing is released." diff --git a/CLAUDE.md b/CLAUDE.md index 27a9f6e..265c721 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,7 +11,10 @@ the results. The device access layer is a native C++ DLL (`TruRNGpro`) called th Three projects in `RandomNumberGenerator.sln`: - `RandomNumberGenerator.csproj` — WinForms app, AnyCPU (64-bit; `Prefer32Bit=false`) - `TruRNGpro/TruRNGpro.vcxproj` — native C++ DLL, **x64 only** (solution maps `Any CPU` → `x64`) -- `RandomNumberGenerator.Test/` — MSTest + Moq unit tests +- `tests/RandomNumberGenerator.Test/` — MSTest + Moq unit tests + +Both kinds of test live under `tests/`: the unit tests above, and `tests/manual/`, which drives the built +application and is described in its own README. ## Build and test @@ -28,12 +31,12 @@ nuget restore RandomNumberGenerator.sln & $msbuild RandomNumberGenerator.sln /p:Configuration=Debug /p:Platform="Any CPU" # Run all tests -& $vstest "RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" +& $vstest "tests\RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" # Run a single test / class / category -& $vstest "RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" /Tests:WriteDataPoint_ValidWriter_Success -& $vstest "RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" /TestCaseFilter:"FullyQualifiedName~RNGXMLWriterTests" -& $vstest "RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" /TestCaseFilter:"TestCategory=Component" +& $vstest "tests\RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" /Tests:WriteDataPoint_ValidWriter_Success +& $vstest "tests\RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" /TestCaseFilter:"FullyQualifiedName~RNGXMLWriterTests" +& $vstest "tests\RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" /TestCaseFilter:"TestCategory=Component" ``` Build ordering matters. The native project copies `TruRNGpro.dll` to `\bin\`, and both the app and the @@ -241,7 +244,7 @@ here (`DeviceInterfaces` supplies the `USBDeviceNotification` constants used in ## Coding conventions -`CODING_GUIDELINES.md` (app), `RandomNumberGenerator.Test/CODING_GUIDELINES_TESTS.md` (tests), and +`CODING_GUIDELINES.md` (app), `tests/RandomNumberGenerator.Test/CODING_GUIDELINES_TESTS.md` (tests), and `TruRNGpro/CODING_GUIDELINES_CPP.md` (native) are authoritative and are actually followed throughout. The non-obvious rules new code is expected to match: diff --git a/README.md b/README.md index 3e89578..c86af0b 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,8 @@ stopping the recording. |---|---| | `RandomNumberGenerator.csproj` | The application. Windows Forms, .NET Framework 4.8, AnyCPU | | `TruRNGpro/TruRNGpro.vcxproj` | Native DLL holding the device interface and the simulator. x64 | -| `RandomNumberGenerator.Test/` | Unit tests. MSTest and Moq | +| `tests/RandomNumberGenerator.Test/` | Unit tests. MSTest and Moq | +| `tests/manual/` | Suites that drive the built application, some needing the device attached | The application talks to the native DLL through two exported functions, `Initialize` and `GetRandomBitAverage`, which sit behind an interface implemented by both the real device and the simulator. @@ -143,7 +144,7 @@ The application talks to the native DLL through two exported functions, `Initial ## Tests ``` -vstest.console.exe "RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" +vstest.console.exe "tests\RandomNumberGenerator.Test\bin\Debug\Random Number Generator.Test.dll" ``` `vstest.console.exe` is under the Visual Studio installation, in @@ -162,7 +163,7 @@ in place. The coding standards are written down and are followed throughout: - `CODING_GUIDELINES.md` for the application -- `RandomNumberGenerator.Test/CODING_GUIDELINES_TESTS.md` for the tests +- `tests/RandomNumberGenerator.Test/CODING_GUIDELINES_TESTS.md` for the tests - `TruRNGpro/CODING_GUIDELINES_CPP.md` for the native code `CLAUDE.md` describes the architecture and the build for anyone, or anything, new to the codebase. diff --git a/RandomNumberGenerator.sln b/RandomNumberGenerator.sln index d5cf5e6..17b103d 100644 --- a/RandomNumberGenerator.sln +++ b/RandomNumberGenerator.sln @@ -10,7 +10,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RandomNumberGenerator", "Ra EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TruRNGpro", "TruRNGpro\TruRNGpro.vcxproj", "{983F2AF3-825E-4283-B55C-D0401CDA780B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RandomNumberGenerator.Test", "RandomNumberGenerator.Test\RandomNumberGenerator.Test.csproj", "{0507DC94-C63E-4C0A-8659-B18BC37DDE25}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RandomNumberGenerator.Test", "tests\RandomNumberGenerator.Test\RandomNumberGenerator.Test.csproj", "{0507DC94-C63E-4C0A-8659-B18BC37DDE25}" ProjectSection(ProjectDependencies) = postProject {983F2AF3-825E-4283-B55C-D0401CDA780B} = {983F2AF3-825E-4283-B55C-D0401CDA780B} EndProjectSection diff --git a/RandomNumberGenerator.Test/CODING_GUIDELINES_TESTS.md b/tests/RandomNumberGenerator.Test/CODING_GUIDELINES_TESTS.md similarity index 100% rename from RandomNumberGenerator.Test/CODING_GUIDELINES_TESTS.md rename to tests/RandomNumberGenerator.Test/CODING_GUIDELINES_TESTS.md diff --git a/RandomNumberGenerator.Test/DeviceUpdateThread.Test.cs b/tests/RandomNumberGenerator.Test/DeviceUpdateThread.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/DeviceUpdateThread.Test.cs rename to tests/RandomNumberGenerator.Test/DeviceUpdateThread.Test.cs diff --git a/RandomNumberGenerator.Test/GeneratorForm.Test.cs b/tests/RandomNumberGenerator.Test/GeneratorForm.Test.cs similarity index 99% rename from RandomNumberGenerator.Test/GeneratorForm.Test.cs rename to tests/RandomNumberGenerator.Test/GeneratorForm.Test.cs index 7273045..ba1f34f 100644 --- a/RandomNumberGenerator.Test/GeneratorForm.Test.cs +++ b/tests/RandomNumberGenerator.Test/GeneratorForm.Test.cs @@ -100,6 +100,16 @@ public TestContext TestContext [TestCleanup] public void Cleanup() { + // Let go of the form this test built, the way DeviceUpdateThreadTests does and for the same + // reason. Building a form points the device search at it and queues a search on the thread pool, + // and that search reports back by assigning the device list to whichever form is the parent when + // it finishes - which is a later test's form, or one that is being written to at that moment. + // The search guards that assignment with InvokeRequired, but a form that was never shown has no + // window handle, and InvokeRequired on a handleless control is false rather than true, so the + // report is made from the pool thread instead of being marshalled. Leaving the parent set is + // what let a search outlive the test that started it. + DeviceUpdateThread.Parent = null; + // Delete test files if they exist to ensure clean state for next test string[] testFiles = { m_sBASELINE_TEST_FILE, diff --git a/RandomNumberGenerator.Test/HistogramChart.Test.cs b/tests/RandomNumberGenerator.Test/HistogramChart.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/HistogramChart.Test.cs rename to tests/RandomNumberGenerator.Test/HistogramChart.Test.cs diff --git a/RandomNumberGenerator.Test/Properties/AssemblyInfo.cs b/tests/RandomNumberGenerator.Test/Properties/AssemblyInfo.cs similarity index 100% rename from RandomNumberGenerator.Test/Properties/AssemblyInfo.cs rename to tests/RandomNumberGenerator.Test/Properties/AssemblyInfo.cs diff --git a/RandomNumberGenerator.Test/RNGChart.Test.cs b/tests/RandomNumberGenerator.Test/RNGChart.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/RNGChart.Test.cs rename to tests/RandomNumberGenerator.Test/RNGChart.Test.cs diff --git a/RandomNumberGenerator.Test/RNGDevice.Test.cs b/tests/RandomNumberGenerator.Test/RNGDevice.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/RNGDevice.Test.cs rename to tests/RandomNumberGenerator.Test/RNGDevice.Test.cs diff --git a/RandomNumberGenerator.Test/RNGDeviceTimer.Test.cs b/tests/RandomNumberGenerator.Test/RNGDeviceTimer.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/RNGDeviceTimer.Test.cs rename to tests/RandomNumberGenerator.Test/RNGDeviceTimer.Test.cs diff --git a/RandomNumberGenerator.Test/RNGSessionData.Test.cs b/tests/RandomNumberGenerator.Test/RNGSessionData.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/RNGSessionData.Test.cs rename to tests/RandomNumberGenerator.Test/RNGSessionData.Test.cs diff --git a/RandomNumberGenerator.Test/RNGSessionDataFile.Test.cs b/tests/RandomNumberGenerator.Test/RNGSessionDataFile.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/RNGSessionDataFile.Test.cs rename to tests/RandomNumberGenerator.Test/RNGSessionDataFile.Test.cs diff --git a/RandomNumberGenerator.Test/RNGSessionTimer.Test.cs b/tests/RandomNumberGenerator.Test/RNGSessionTimer.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/RNGSessionTimer.Test.cs rename to tests/RandomNumberGenerator.Test/RNGSessionTimer.Test.cs diff --git a/RandomNumberGenerator.Test/RNGXMLReader.Test.cs b/tests/RandomNumberGenerator.Test/RNGXMLReader.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/RNGXMLReader.Test.cs rename to tests/RandomNumberGenerator.Test/RNGXMLReader.Test.cs diff --git a/RandomNumberGenerator.Test/RNGXMLWriter.Test.cs b/tests/RandomNumberGenerator.Test/RNGXMLWriter.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/RNGXMLWriter.Test.cs rename to tests/RandomNumberGenerator.Test/RNGXMLWriter.Test.cs diff --git a/RandomNumberGenerator.Test/RandomNumberGenerator.Test.csproj b/tests/RandomNumberGenerator.Test/RandomNumberGenerator.Test.csproj similarity index 76% rename from RandomNumberGenerator.Test/RandomNumberGenerator.Test.csproj rename to tests/RandomNumberGenerator.Test/RandomNumberGenerator.Test.csproj index 8faf58b..89000f4 100644 --- a/RandomNumberGenerator.Test/RandomNumberGenerator.Test.csproj +++ b/tests/RandomNumberGenerator.Test/RandomNumberGenerator.Test.csproj @@ -1,6 +1,6 @@ - + Debug @@ -43,29 +43,29 @@ - ..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll + ..\..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll - ..\packages\MathNet.Numerics.5.0.0\lib\net48\MathNet.Numerics.dll + ..\..\packages\MathNet.Numerics.5.0.0\lib\net48\MathNet.Numerics.dll - ..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + ..\..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - ..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + ..\..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll - ..\packages\Moq.4.20.70\lib\net462\Moq.dll + ..\..\packages\Moq.4.20.70\lib\net462\Moq.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll - ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + ..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll @@ -94,7 +94,7 @@ - + {58f5fb77-99e5-4212-a46f-af3a18d46b17} RandomNumberGenerator @@ -105,10 +105,10 @@ 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}. - - + + - + xcopy /Y "$(SolutionDir)bin\TruRNGpro.dll" "$(TargetDir)" if errorlevel 1 goto end diff --git a/tests/RandomNumberGenerator.Test/RandomNumberGenerator.sln b/tests/RandomNumberGenerator.Test/RandomNumberGenerator.sln new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/tests/RandomNumberGenerator.Test/RandomNumberGenerator.sln @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/RandomNumberGenerator.Test/SignificanceTest.Test.cs b/tests/RandomNumberGenerator.Test/SignificanceTest.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/SignificanceTest.Test.cs rename to tests/RandomNumberGenerator.Test/SignificanceTest.Test.cs diff --git a/RandomNumberGenerator.Test/StatisticalAnalysis.Test.cs b/tests/RandomNumberGenerator.Test/StatisticalAnalysis.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/StatisticalAnalysis.Test.cs rename to tests/RandomNumberGenerator.Test/StatisticalAnalysis.Test.cs diff --git a/RandomNumberGenerator.Test/TargetValues.Test.cs b/tests/RandomNumberGenerator.Test/TargetValues.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/TargetValues.Test.cs rename to tests/RandomNumberGenerator.Test/TargetValues.Test.cs diff --git a/RandomNumberGenerator.Test/XMLDataPoint.Test.cs b/tests/RandomNumberGenerator.Test/XMLDataPoint.Test.cs similarity index 100% rename from RandomNumberGenerator.Test/XMLDataPoint.Test.cs rename to tests/RandomNumberGenerator.Test/XMLDataPoint.Test.cs diff --git a/RandomNumberGenerator.Test/packages.config b/tests/RandomNumberGenerator.Test/packages.config similarity index 100% rename from RandomNumberGenerator.Test/packages.config rename to tests/RandomNumberGenerator.Test/packages.config diff --git a/tests/manual/README.md b/tests/manual/README.md index ed02f62..7fe0fe4 100644 --- a/tests/manual/README.md +++ b/tests/manual/README.md @@ -1,6 +1,6 @@ # Manual test suites -These drive the built application rather than its classes. The unit tests in `RandomNumberGenerator.Test` +These drive the built application rather than its classes. The unit tests in `tests/RandomNumberGenerator.Test` cover the layers underneath the window; nothing in them builds the form's event wiring, and nothing in them can reach the device at all. Everything here exists because a fault got past a clean unit run.