Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tests, Update Docs, Update code #43

Merged
merged 1 commit into from
Jun 5, 2024
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 Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<Nullable>enable</Nullable>
<PackageIcon>icon.png</PackageIcon>
<Configurations>Debug;Release;PreRelease</Configurations>
<PackageReleaseNotes>Compatability with Net 6 / 7 / 8 and netstandard2.0</PackageReleaseNotes>
<PackageReleaseNotes>Compatability with Net 6 / 8 and netstandard2.0</PackageReleaseNotes>
<PackageTags>Hashtable;rx;reactive;extensions;observable;LINQ;net;netstandard</PackageTags>
<EnableNETAnalyzers>True</EnableNETAnalyzers>
<AnalysisLevel>latest</AnalysisLevel>
Expand Down
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,41 @@
# HashTableRx
A Reactive Hash Table
A Reactive Hash Table, used to store and observe values in a hash table reflecting the structure of an object.

## Usage

```csharp
// Replace YOUR_OBJECT with the object you want to store in the hash table
var obj = new YOUR_OBJECT();

// Create a new Hash Table - the bool is used to determine if the hash table should use Upper Case or Case Sensitive keys
var hashTable = new HashTableRx(false);

// Set / update the structure of the Hash Table
hashTable.SetStructure(obj);

hashTable.Observe<bool>("YourProperty").Subscribe(value =>
{
// Do something with the value
});

// Set the value in the hash table
hashTable.Value<float>("YourProperty", 10.5f);

// Get the value from the hash table
var value = hashTable.Value<float>("YourProperty");

// Get the current structure of the hash table
var updatedObj = hashTable.GetStructure();
```

## About

The HashTableRx can be used to store and observe values in a hash table reflecting the structure of an object. The HashTableRx is a reactive hash table, which means that you can observe the values in the hash table and react to changes in the values. The HashTableRx is a generic class, which means that you can store any type of object in the hash table. The HashTableRx is a lightweight and easy-to-use library that can be used in any C# project.

Variables in the HashTableRx are seperated by a dot, for example: "YourProperty.SubProperty".
This is used to reflect the layers of a structured object in the hash table.

Currently, the HashTableRx supports the following types:
Structures made of Public Fields both Primative and further layers of classes, itteration will be done to find the Primative values in a Structure.

ToDo: Add support for Properties.
2 changes: 1 addition & 1 deletion Version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json",
"version": "1.1",
"version": "1.2",
"publicReleaseRefSpec": [
"^refs/heads/master$",
"^refs/heads/main$"
Expand Down
39 changes: 39 additions & 0 deletions src/HashTableRx.Tests/HashTableRx.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\HashTableRx\HashTableRx.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

<ItemGroup>
<None Update="MockLibraryWithFields.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
70 changes: 70 additions & 0 deletions src/HashTableRx.Tests/HashTableRxFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) Chris Pulman. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Reflection;

namespace CP.Collections.Tests
{
/// <summary>
/// HashTableRxFixture.
/// </summary>
/// <seealso cref="System.IDisposable" />
public class HashTableRxFixture : IDisposable
{
private bool _disposedValue;

/// <summary>
/// Initializes a new instance of the <see cref="HashTableRxFixture"/> class.
/// </summary>
public HashTableRxFixture()
{
// get the current directory
var currentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

// load the assembly MockLibraryWithFields.dll
var assembly = Assembly.LoadFrom(currentDirectory + "\\MockLibraryWithFields.dll");
Assert.NotNull(assembly);

// Create an instance of the MockLibraryWithFields.MockClassWithFields class
var obj = assembly.CreateInstance("TwinCATRx.RigSTRUCT");
Assert.NotNull(obj);

HtRx = new(false);
HtRx.SetStucture(obj);
}

/// <summary>
/// Gets the HashTable Rx.
/// </summary>
/// <value>
/// The ht rx.
/// </value>
public HashTableRx HtRx { get; }

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
HtRx.Dispose();
}

_disposedValue = true;
}
}
}
}
100 changes: 100 additions & 0 deletions src/HashTableRx.Tests/HashTableRxTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) Chris Pulman. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Reactive.Disposables;
using System.Reactive.Linq;

namespace CP.Collections.Tests
{
/// <summary>
/// UnitTest1.
/// </summary>
/// <remarks>
/// Initializes a new instance of the <see cref="HashTableRxTest"/> class.
/// </remarks>
/// <param name="fixture">The hash table rx fixture.</param>
public class HashTableRxTest(HashTableRxFixture fixture) : IClassFixture<HashTableRxFixture>
{
/// <summary>
/// Test1s this instance.
/// </summary>
[Fact]
public void HashTableRxCanReadValuesDirectly()
{
fixture.HtRx["CalibrationDataValid"] = false;
var t = (bool?)fixture.HtRx["CalibrationDataValid"];
Assert.False(t);

fixture.HtRx["Casing.Temperature.PV.Value"] = 0.0f;
var t2 = (float?)fixture.HtRx["Casing.Temperature.PV.Value"];
Assert.Equal(0.0f, t2);
}

/// <summary>
/// Hashes the table rx can write values.
/// </summary>
[Fact]
public void HashTableRxCanWriteValuesDirectly()
{
fixture.HtRx["CalibrationDataValid"] = true;
var t = (bool?)fixture.HtRx["CalibrationDataValid"];
Assert.True(t);

fixture.HtRx["Casing.Temperature.PV.Value"] = 1.0f;
var t2 = (float?)fixture.HtRx["Casing.Temperature.PV.Value"];
Assert.Equal(1.0f, t2);
}

/// <summary>
/// Hashes the table rx can read values from observable.
/// </summary>
[Fact]
public void HashTableRxCanReadValuesFromObservable()
{
var disposables = new CompositeDisposable();
fixture.HtRx["CalibrationDataValid"] = false;
var t = (bool?)fixture.HtRx["CalibrationDataValid"];
Assert.False(t);
disposables.Add(fixture.HtRx.Observe<bool>("CalibrationDataValid").Skip(1).Subscribe(x => Assert.True(x)));
fixture.HtRx["CalibrationDataValid"] = true;

fixture.HtRx["Casing.Temperature.PV.Value"] = 0.0f;
var t2 = (float?)fixture.HtRx["Casing.Temperature.PV.Value"];
Assert.Equal(0.0f, t2);
disposables.Add(fixture.HtRx.Observe<float>("Casing.Temperature.PV.Value").Skip(1).Subscribe(x => Assert.Equal(1.0f, x)));
fixture.HtRx["Casing.Temperature.PV.Value"] = 1.0f;

disposables.Dispose();
}

/// <summary>
/// Hashes the table rx can read values.
/// </summary>
[Fact]
public void HashTableRxCanReadValues()
{
fixture.HtRx["CalibrationDataValid"] = false;
var t = fixture.HtRx.Value<bool>("CalibrationDataValid");
Assert.False(t);

fixture.HtRx["Casing.Temperature.PV.Value"] = 0.0f;
var t2 = fixture.HtRx.Value<float>("Casing.Temperature.PV.Value");
Assert.Equal(0.0f, t2);
}

/// <summary>
/// Hashes the table rx can write values.
/// </summary>
[Fact]
public void HashTableRxCanWriteValues()
{
fixture.HtRx.Value("CalibrationDataValid", true);
var t = fixture.HtRx.Value<bool>("CalibrationDataValid");
Assert.True(t);

fixture.HtRx.Value("Casing.Temperature.PV.Value", 1.0f);
var t2 = fixture.HtRx.Value<float>("Casing.Temperature.PV.Value");
Assert.Equal(1.0f, t2);
}
}
}
Binary file not shown.
9 changes: 8 additions & 1 deletion src/HashTableRx.sln
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32922.545
Expand All @@ -18,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionConfig", "SolutionC
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "..\build\_build.csproj", "{5A3634B0-A15E-4B5D-8367-7D9FD0EACEE2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HashTableRx.Tests", "HashTableRx.Tests\HashTableRx.Tests.csproj", "{1DF2E1C4-3A84-4A32-A11C-0FD053D22696}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -31,6 +32,12 @@ Global
{0B3BCECD-D330-4704-82B1-83EEB8C9A808}.PreRelease|Any CPU.Build.0 = PreRelease|Any CPU
{0B3BCECD-D330-4704-82B1-83EEB8C9A808}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B3BCECD-D330-4704-82B1-83EEB8C9A808}.Release|Any CPU.Build.0 = Release|Any CPU
{1DF2E1C4-3A84-4A32-A11C-0FD053D22696}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1DF2E1C4-3A84-4A32-A11C-0FD053D22696}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1DF2E1C4-3A84-4A32-A11C-0FD053D22696}.PreRelease|Any CPU.ActiveCfg = PreRelease|Any CPU
{1DF2E1C4-3A84-4A32-A11C-0FD053D22696}.PreRelease|Any CPU.Build.0 = PreRelease|Any CPU
{1DF2E1C4-3A84-4A32-A11C-0FD053D22696}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1DF2E1C4-3A84-4A32-A11C-0FD053D22696}.Release|Any CPU.Build.0 = Release|Any CPU
{5A3634B0-A15E-4B5D-8367-7D9FD0EACEE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A3634B0-A15E-4B5D-8367-7D9FD0EACEE2}.PreRelease|Any CPU.ActiveCfg = Release|Any CPU
{5A3634B0-A15E-4B5D-8367-7D9FD0EACEE2}.PreRelease|Any CPU.Build.0 = Release|Any CPU
Expand Down
Loading
Loading