Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Dragemil committed Sep 11, 2023
1 parent 259ac56 commit f31f713
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 23 deletions.
7 changes: 7 additions & 0 deletions publisher/LeanPipe.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LeanPipe.Tests.Additional",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LeanPipe.TestClient", "src\LeanPipe.TestClient\LeanPipe.TestClient.csproj", "{F1830D31-AA1D-409B-B78E-FC2BB88B7DF8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LeanPipe.TestClient.Tests", "test\LeanPipe.TestClient.Tests\LeanPipe.TestClient.Tests.csproj", "{38F1AA50-B16E-47A7-925A-AB574E9120FF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -40,11 +42,16 @@ Global
{F1830D31-AA1D-409B-B78E-FC2BB88B7DF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F1830D31-AA1D-409B-B78E-FC2BB88B7DF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F1830D31-AA1D-409B-B78E-FC2BB88B7DF8}.Release|Any CPU.Build.0 = Release|Any CPU
{38F1AA50-B16E-47A7-925A-AB574E9120FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38F1AA50-B16E-47A7-925A-AB574E9120FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38F1AA50-B16E-47A7-925A-AB574E9120FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38F1AA50-B16E-47A7-925A-AB574E9120FF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{75B2B837-B392-4DC1-8CF7-C1B2C4E03312} = {401E8BD4-C7D7-48F2-8899-EA9859247BD7}
{898B0F90-3D05-4372-88F8-BB0B863D2970} = {CBE053F8-6853-4FFC-A931-84A210C5FF2C}
{D365AF42-33A5-4FB3-96DB-692F2417C458} = {CBE053F8-6853-4FFC-A931-84A210C5FF2C}
{F1830D31-AA1D-409B-B78E-FC2BB88B7DF8} = {401E8BD4-C7D7-48F2-8899-EA9859247BD7}
{38F1AA50-B16E-47A7-925A-AB574E9120FF} = {CBE053F8-6853-4FFC-A931-84A210C5FF2C}
EndGlobalSection
EndGlobal
3 changes: 3 additions & 0 deletions publisher/src/LeanPipe.TestClient/LeanPipeTestClient.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Text.Json;
using LeanCode.Components;
using LeanCode.Contracts;
using Microsoft.AspNetCore.Http.Connections.Client;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;

[assembly: InternalsVisibleTo("LeanPipe.TestClient.Tests")]

namespace LeanPipe.TestClient;

public class LeanPipeTestClient : IAsyncDisposable
Expand Down
60 changes: 41 additions & 19 deletions publisher/src/LeanPipe.TestClient/TopicDeepEqualityComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,26 @@ public override bool Equals(object? x, object? y)
return false;
}

var xType = x.GetType();

// Compare the types
if (x.GetType() != y!.GetType())
if (xType != y!.GetType())
{
return false;
}

if (IsPrimitive(xType))
{
if (x is string xString)
{
return string.Equals(xString, y as string, StringComparison.InvariantCulture);
}
else
{
return x.Equals(y);
}
}

// Get all property infos of the right object
var propertyInfos = x.GetType().GetProperties();

Expand Down Expand Up @@ -107,35 +121,43 @@ public override int GetHashCode(object obj)
{
var hashCode = new HashCode();

hashCode.Add(obj.GetType());
var type = obj.GetType();

foreach (var propertyInfo in obj.GetType().GetProperties())
{
var value = propertyInfo.GetValue(obj);
hashCode.Add(type);

if (value is IList valueList && propertyInfo.PropertyType.IsGenericType)
{
foreach (var listValue in valueList)
{
hashCode.AddBytes(BitConverter.GetBytes(GetHashCode(listValue)));
}
}
else
if (IsPrimitive(type))
{
hashCode.Add(obj);
}
else
{
foreach (var propertyInfo in obj.GetType().GetProperties())
{
var type = value!.GetType();
var value = propertyInfo.GetValue(obj);

// Values are primitive
if (type.IsValueType || value is string)
if (value is IList valueList && propertyInfo.PropertyType.IsGenericType)
{
hashCode.Add(value);
foreach (var listValue in valueList)
{
hashCode.AddBytes(BitConverter.GetBytes(GetHashCode(listValue)));
}
}
else // Values are complex
else
{
hashCode.AddBytes(BitConverter.GetBytes(GetHashCode(value)));
if (IsPrimitive(value!.GetType()))
{
hashCode.Add(value);
}
else // Values are complex
{
hashCode.AddBytes(BitConverter.GetBytes(GetHashCode(value)));
}
}
}
}

return hashCode.ToHashCode();
}

private static bool IsPrimitive(Type type) => type.IsValueType || type == typeof(string);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />

<PackageReference Include="xunit" />
<PackageReference Include="xunit.analyzers" />
<PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../../src/LeanPipe.TestClient/LeanPipe.TestClient.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Text.Json;
using FluentAssertions;
using LeanCode.Contracts;
using Xunit;

namespace LeanPipe.TestClient.Tests;

public class NotificationEnvelopeDeserializerTests
{
private static readonly NotificationEnvelopeDeserializer Deserializer =
new(new(typeof(Topic)), null);

[Fact]
public void NotificationEnvelopeDeserializer_deserializes_topic_and_notification()
{
var topic = new Topic
{
EntityIds = new() { "Entity1", "Entity2" },
};

var notification = new Notification { EntityId = "Entity1" };

var notificationEnvelope = NotificationEnvelope.Create(topic, notification);

var serializedEnvelope = JsonSerializer.Serialize(notificationEnvelope);

var deserializedEnvelope = JsonSerializer.Deserialize<NotificationEnvelope>(
serializedEnvelope
);

Deserializer
.Deserialize(deserializedEnvelope!)
.Should()
.BeEquivalentTo(
new NotificationEnvelopeDeserializer.TopicsNotification(topic, notification)
);
}

public class Topic : ITopic, IProduceNotification<Notification>
{
public List<string> EntityIds { get; set; } = default!;
}

public class Notification
{
public string EntityId { get; set; } = default!;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using FluentAssertions;
using LeanCode.Contracts;
using Xunit;

namespace LeanPipe.TestClient.Tests;

public class TopicDeepEqualityComparerTests
{
private static readonly TopicDeepEqualityComparer ComparerInstance =
TopicDeepEqualityComparer.Instance;

private static ComplexTopic GetComplexTopic =>
new()
{
PrimitiveGuid = Guid.Parse("c00d2320-3ff8-4fcb-854f-8c53d8d2637f"),
ListOfPrimitives = new() { 1, 2 },
Complex = new() { PrimitiveString = "String1", },
};

[Fact]
public void Topics_are_correctly_compared_when_they_are_the_same()
{
var topic1 = GetComplexTopic;
var topic2 = GetComplexTopic;

ComparerInstance.Equals(topic1, topic2).Should().BeTrue();

ComparerInstance.GetHashCode(topic1).Should().Be(ComparerInstance.GetHashCode(topic2));
}

[Fact]
public void Topics_are_correctly_compared_when_some_primitives_differ()
{
var topic1 = GetComplexTopic;
var topic2 = GetComplexTopic;
topic2.PrimitiveGuid = Guid.NewGuid();

ComparerInstance.Equals(topic1, topic2).Should().BeFalse();

ComparerInstance.GetHashCode(topic1).Should().NotBe(ComparerInstance.GetHashCode(topic2));
}

[Fact]
public void Topics_are_correctly_compared_when_some_lists_differ()
{
var topic1 = GetComplexTopic;
var topic2 = GetComplexTopic;
topic2.ListOfPrimitives[^1] = 3;

ComparerInstance.Equals(topic1, topic2).Should().BeFalse();

ComparerInstance.GetHashCode(topic1).Should().NotBe(ComparerInstance.GetHashCode(topic2));

var topic3 = GetComplexTopic;
topic3.ListOfPrimitives.Add(3);

ComparerInstance.Equals(topic1, topic3).Should().BeFalse();

ComparerInstance.GetHashCode(topic1).Should().NotBe(ComparerInstance.GetHashCode(topic3));
}

[Fact]
public void Topics_are_correctly_compared_when_some_complex_objects_differ()
{
var topic1 = GetComplexTopic;
var topic2 = GetComplexTopic;
topic2.Complex.PrimitiveString = "String2";

ComparerInstance.Equals(topic1, topic2).Should().BeFalse();

ComparerInstance.GetHashCode(topic1).Should().NotBe(ComparerInstance.GetHashCode(topic2));
}

private class ComplexTopic : ITopic
{
public Guid PrimitiveGuid { get; set; }
public List<int> ListOfPrimitives { get; set; } = default!;
public ComplexDTO Complex { get; set; } = default!;
}

private class ComplexDTO
{
public string PrimitiveString { get; set; } = default!;
}
}
5 changes: 1 addition & 4 deletions publisher/test/LeanPipe.Tests/LeanPipe.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
Expand All @@ -12,10 +13,6 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" />
</ItemGroup>

Expand Down

0 comments on commit f31f713

Please sign in to comment.