feat: Add unit tests and fakes for Crestron environment and data store

- Introduced `FakeCrestronEnvironment` and `FakeEthernetHelper` for testing purposes.
- Implemented `InMemoryCrestronDataStore` to facilitate unit tests for data storage.
- Created `DebugServiceTests` to validate the behavior of debug-related services.
- Added project files for unit tests targeting .NET 9.0 with necessary dependencies.
- Developed production adapters (`CrestronConsoleAdapter`, `CrestronDataStoreAdapter`, `CrestronEnvironmentAdapter`, `CrestronEthernetAdapter`) to interface with the Crestron SDK.
- Updated `Debug` class to utilize injected service abstractions instead of direct SDK calls.
- Enhanced `ControlSystem` initialization to register service adapters before usage.
This commit is contained in:
Neil Dorin 2026-04-08 12:41:15 -06:00
parent bfb9838743
commit 24df4e7a03
21 changed files with 1020 additions and 93 deletions

View file

@ -0,0 +1,73 @@
using FluentAssertions;
using PepperDash.Core.Abstractions;
using PepperDash.Core.Tests.Fakes;
using Xunit;
namespace PepperDash.Essentials.Core.Tests.Config;
/// <summary>
/// Tests for the configuration loading abstractions.
/// These verify behaviour of the test fakes and interfaces independently of
/// any Crestron SDK types (ConfigReader itself will be tested here once it
/// is migrated from Crestron.SimplSharp.CrestronIO to System.IO — see plan Phase 4).
/// </summary>
public class ConfigServiceFakesTests
{
[Fact]
public void DataStore_MultipleKeys_AreStoredIndependently()
{
var store = new InMemoryCrestronDataStore();
store.InitStore();
store.SetLocalInt("KeyA", 1);
store.SetLocalInt("KeyB", 2);
store.TryGetLocalInt("KeyA", out var a);
store.TryGetLocalInt("KeyB", out var b);
a.Should().Be(1);
b.Should().Be(2);
}
[Fact]
public void DataStore_OverwriteKey_ReturnsNewValue()
{
var store = new InMemoryCrestronDataStore();
store.SetLocalInt("Level", 1);
store.SetLocalInt("Level", 5);
store.TryGetLocalInt("Level", out var level);
level.Should().Be(5);
}
[Fact]
public void FakeEnvironment_CanBeConfiguredForServer()
{
var env = new FakeCrestronEnvironment
{
DevicePlatform = DevicePlatform.Server,
ApplicationNumber = 1,
RoomId = 42,
};
env.DevicePlatform.Should().Be(DevicePlatform.Server);
env.RoomId.Should().Be(42u);
}
[Fact]
public void FakeEthernetHelper_SeedAndRetrieve()
{
var eth = new FakeEthernetHelper()
.Seed(EthernetParameterType.GetCurrentIpAddress, "192.168.1.100")
.Seed(EthernetParameterType.GetHostname, "MC4-TEST");
eth.GetEthernetParameter(EthernetParameterType.GetCurrentIpAddress, 0)
.Should().Be("192.168.1.100");
eth.GetEthernetParameter(EthernetParameterType.GetHostname, 0)
.Should().Be("MC4-TEST");
eth.GetEthernetParameter(EthernetParameterType.GetDomainName, 0)
.Should().BeEmpty("unseeded parameter should return empty string");
}
}

View file

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="FluentAssertions" Version="7.0.0" />
</ItemGroup>
<!-- Reference the Abstractions project only — no Crestron SDK dependency -->
<ItemGroup>
<ProjectReference Include="..\PepperDash.Core.Abstractions\PepperDash.Core.Abstractions.csproj" />
<!-- Reference Core.Tests to share the Fakes folder -->
<ProjectReference Include="..\PepperDash.Core.Tests\PepperDash.Core.Tests.csproj" />
</ItemGroup>
</Project>