Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
15 changes: 9 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 `<sln>\bin\`, and both the app and the
Expand Down Expand Up @@ -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:

Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,16 @@ 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.

## 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
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion RandomNumberGenerator.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.props')" />
<Import Project="..\..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.props" Condition="Exists('..\..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand Down Expand Up @@ -43,29 +43,29 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="Castle.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll</HintPath>
<HintPath>..\..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll</HintPath>
</Reference>
<Reference Include="MathNet.Numerics, Version=5.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MathNet.Numerics.5.0.0\lib\net48\MathNet.Numerics.dll</HintPath>
<HintPath>..\..\packages\MathNet.Numerics.5.0.0\lib\net48\MathNet.Numerics.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
<HintPath>..\..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
<HintPath>..\..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
</Reference>
<Reference Include="Moq, Version=4.20.70.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.20.70\lib\net462\Moq.dll</HintPath>
<HintPath>..\..\packages\Moq.4.20.70\lib\net462\Moq.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<HintPath>..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
<HintPath>..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Forms.DataVisualization" />
Expand Down Expand Up @@ -94,7 +94,7 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RandomNumberGenerator.csproj">
<ProjectReference Include="..\..\RandomNumberGenerator.csproj">
<Project>{58f5fb77-99e5-4212-a46f-af3a18d46b17}</Project>
<Name>RandomNumberGenerator</Name>
</ProjectReference>
Expand All @@ -105,10 +105,10 @@
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.props'))" />
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.targets'))" />
<Error Condition="!Exists('..\..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.props'))" />
<Error Condition="!Exists('..\..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.targets'))" />
</Target>
<Import Project="..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.targets')" />
<Import Project="..\..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.targets" Condition="Exists('..\..\packages\MSTest.TestAdapter.2.2.10\build\net46\MSTest.TestAdapter.targets')" />
<PropertyGroup>
<PostBuildEvent>xcopy /Y "$(SolutionDir)bin\TruRNGpro.dll" "$(TargetDir)"
if errorlevel 1 goto end
Expand Down
1 change: 1 addition & 0 deletions tests/RandomNumberGenerator.Test/RandomNumberGenerator.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

2 changes: 1 addition & 1 deletion tests/manual/README.md
Original file line number Diff line number Diff line change
@@ -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.

Expand Down