Skip to content

List functionality bug fixes #40

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

Merged
merged 1 commit into from
Feb 10, 2025
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
968 changes: 484 additions & 484 deletions .gitignore

Large diffs are not rendered by default.

8,167 changes: 8,166 additions & 1 deletion reference.md

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions src/Merge.Client.Test/Core/EnumSerializerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Runtime.Serialization;
using System.Text.Json;
using System.Text.Json.Serialization;
using Merge.Client.Core;
using NUnit.Framework;

namespace Merge.Client.Test.Core;

[TestFixture]
public class StringEnumSerializerTests
{
private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };

private const DummyEnum KnownEnumValue2 = DummyEnum.KnownValue2;
private const string KnownEnumValue2String = "known_value2";

private const string JsonWithKnownEnum2 = $$"""
{
"enum_property": "{{KnownEnumValue2String}}"
}
""";

[Test]
public void ShouldParseKnownEnumValue2()
{
var obj = JsonSerializer.Deserialize<DummyObject>(JsonWithKnownEnum2, JsonOptions);
Assert.That(obj, Is.Not.Null);
Assert.That(obj.EnumProperty, Is.EqualTo(KnownEnumValue2));
}

[Test]
public void ShouldSerializeKnownEnumValue2()
{
var json = JsonSerializer.SerializeToElement(
new DummyObject { EnumProperty = KnownEnumValue2 },
JsonOptions
);
TestContext.Out.WriteLine("Serialized JSON: \n" + json);
var enumString = json.GetProperty("enum_property").GetString();
Assert.That(enumString, Is.Not.Null);
Assert.That(enumString, Is.EqualTo(KnownEnumValue2String));
}
}

public class DummyObject
{
[JsonPropertyName("enum_property")]
public DummyEnum EnumProperty { get; set; }
}

[JsonConverter(typeof(EnumSerializer<DummyEnum>))]
public enum DummyEnum
{
[EnumMember(Value = "known_value1")]
KnownValue1,

[EnumMember(Value = "known_value2")]
KnownValue2,
}
310 changes: 310 additions & 0 deletions src/Merge.Client.Test/Core/OneOfSerializerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Merge.Client.Core;
using NUnit.Framework;
using OneOf;

namespace Merge.Client.Test.Core;

[TestFixture]
public class OneOfSerializerTests
{
private class Foo
{
[JsonPropertyName("string_prop")]
public required string StringProp { get; set; }
}

private class Bar
{
[JsonPropertyName("int_prop")]
public required int IntProp { get; set; }
}

private static readonly OneOf<string, int, object, Foo, Bar> OneOf1 = OneOf<
string,
int,
object,
Foo,
Bar
>.FromT2(new { });
private const string OneOf1String = "{}";

private static readonly OneOf<string, int, object, Foo, Bar> OneOf2 = OneOf<
string,
int,
object,
Foo,
Bar
>.FromT0("test");
private const string OneOf2String = "\"test\"";

private static readonly OneOf<string, int, object, Foo, Bar> OneOf3 = OneOf<
string,
int,
object,
Foo,
Bar
>.FromT1(123);
private const string OneOf3String = "123";

private static readonly OneOf<string, int, object, Foo, Bar> OneOf4 = OneOf<
string,
int,
object,
Foo,
Bar
>.FromT3(new Foo { StringProp = "test" });
private const string OneOf4String = "{\n \"string_prop\": \"test\"\n}";

private static readonly OneOf<string, int, object, Foo, Bar> OneOf5 = OneOf<
string,
int,
object,
Foo,
Bar
>.FromT4(new Bar { IntProp = 5 });
private const string OneOf5String = "{\n \"int_prop\": 5\n}";

[Test]
public void Serialize_OneOfs_Should_Return_Expected_String()
{
(OneOf<string, int, object, Foo, Bar>, string)[] testData =
[
(OneOf1, OneOf1String),
(OneOf2, OneOf2String),
(OneOf3, OneOf3String),
(OneOf4, OneOf4String),
(OneOf5, OneOf5String),
];
Assert.Multiple(() =>
{
foreach (var (oneOf, expected) in testData)
{
var result = JsonUtils.Serialize(oneOf);
Assert.That(result, Is.EqualTo(expected));
}
});
}

[Test]
public void OneOfs_Should_Deserialize_From_String()
{
(OneOf<string, int, object, Foo, Bar>, string)[] testData =
[
(OneOf1, OneOf1String),
(OneOf2, OneOf2String),
(OneOf3, OneOf3String),
(OneOf4, OneOf4String),
(OneOf5, OneOf5String),
];
Assert.Multiple(() =>
{
foreach (var (oneOf, json) in testData)
{
var result = JsonUtils.Deserialize<OneOf<string, int, object, Foo, Bar>>(json);
Assert.That(result.Index, Is.EqualTo(oneOf.Index));
Assert.That(json, Is.EqualTo(JsonUtils.Serialize(result.Value)));
}
});
}

private static readonly OneOf<string, int, object, Foo, Bar>? NullableOneOf1 = null;
private const string NullableOneOf1String = "null";

private static readonly OneOf<string, int, object, Foo, Bar>? NullableOneOf2 = OneOf<
string,
int,
object,
Foo,
Bar
>.FromT4(new Bar { IntProp = 5 });
private const string NullableOneOf2String = "{\n \"int_prop\": 5\n}";

[Test]
public void Serialize_NullableOneOfs_Should_Return_Expected_String()
{
(OneOf<string, int, object, Foo, Bar>?, string)[] testData =
[
(NullableOneOf1, NullableOneOf1String),
(NullableOneOf2, NullableOneOf2String),
];
Assert.Multiple(() =>
{
foreach (var (oneOf, expected) in testData)
{
var result = JsonUtils.Serialize(oneOf);
Assert.That(result, Is.EqualTo(expected));
}
});
}

[Test]
public void NullableOneOfs_Should_Deserialize_From_String()
{
(OneOf<string, int, object, Foo, Bar>?, string)[] testData =
[
(NullableOneOf1, NullableOneOf1String),
(NullableOneOf2, NullableOneOf2String),
];
Assert.Multiple(() =>
{
foreach (var (oneOf, json) in testData)
{
var result = JsonUtils.Deserialize<OneOf<string, int, object, Foo, Bar>?>(json);
Assert.That(result?.Index, Is.EqualTo(oneOf?.Index));
Assert.That(json, Is.EqualTo(JsonUtils.Serialize(result?.Value)));
}
});
}

private static readonly OneOf<string, int, Foo?> OneOfWithNullable1 = OneOf<
string,
int,
Foo?
>.FromT2(null);
private const string OneOfWithNullable1String = "null";

private static readonly OneOf<string, int, Foo?> OneOfWithNullable2 = OneOf<
string,
int,
Foo?
>.FromT2(new Foo { StringProp = "test" });
private const string OneOfWithNullable2String = "{\n \"string_prop\": \"test\"\n}";

private static readonly OneOf<string, int, Foo?> OneOfWithNullable3 = OneOf<
string,
int,
Foo?
>.FromT0("test");
private const string OneOfWithNullable3String = "\"test\"";

[Test]
public void Serialize_OneOfWithNullables_Should_Return_Expected_String()
{
(OneOf<string, int, Foo?>, string)[] testData =
[
(OneOfWithNullable1, OneOfWithNullable1String),
(OneOfWithNullable2, OneOfWithNullable2String),
(OneOfWithNullable3, OneOfWithNullable3String),
];
Assert.Multiple(() =>
{
foreach (var (oneOf, expected) in testData)
{
var result = JsonUtils.Serialize(oneOf);
Assert.That(result, Is.EqualTo(expected));
}
});
}

[Test]
public void OneOfWithNullables_Should_Deserialize_From_String()
{
(OneOf<string, int, Foo?>, string)[] testData =
[
// (OneOfWithNullable1, OneOfWithNullable1String), // not possible with .NET's JSON serializer
(OneOfWithNullable2, OneOfWithNullable2String),
(OneOfWithNullable3, OneOfWithNullable3String),
];
Assert.Multiple(() =>
{
foreach (var (oneOf, json) in testData)
{
var result = JsonUtils.Deserialize<OneOf<string, int, Foo?>>(json);
Assert.That(result.Index, Is.EqualTo(oneOf.Index));
Assert.That(json, Is.EqualTo(JsonUtils.Serialize(result.Value)));
}
});
}

[Test]
public void Serialize_OneOfWithObjectLast_Should_Return_Expected_String()
{
var oneOfWithObjectLast = OneOf<string, int, Foo, Bar, object>.FromT4(
new { random = "data" }
);
const string oneOfWithObjectLastString = "{\n \"random\": \"data\"\n}";

var result = JsonUtils.Serialize(oneOfWithObjectLast);
Assert.That(result, Is.EqualTo(oneOfWithObjectLastString));
}

[Test]
public void OneOfWithObjectLast_Should_Deserialize_From_String()
{
const string oneOfWithObjectLastString = "{\n \"random\": \"data\"\n}";
var result = JsonUtils.Deserialize<OneOf<string, int, Foo, Bar, object>>(
oneOfWithObjectLastString
);
Assert.Multiple(() =>
{
Assert.That(result.Index, Is.EqualTo(4));
Assert.That(result.Value, Is.InstanceOf<object>());
Assert.That(JsonUtils.Serialize(result.Value), Is.EqualTo(oneOfWithObjectLastString));
});
}

[Test]
public void Serialize_OneOfWithObjectNotLast_Should_Return_Expected_String()
{
var oneOfWithObjectNotLast = OneOf<string, object, int, Foo, Bar>.FromT1(
new { random = "data" }
);
const string oneOfWithObjectNotLastString = "{\n \"random\": \"data\"\n}";

var result = JsonUtils.Serialize(oneOfWithObjectNotLast);
Assert.That(result, Is.EqualTo(oneOfWithObjectNotLastString));
}

[Test]
public void OneOfWithObjectNotLast_Should_Deserialize_From_String()
{
const string oneOfWithObjectNotLastString = "{\n \"random\": \"data\"\n}";
var result = JsonUtils.Deserialize<OneOf<string, object, int, Foo, Bar>>(
oneOfWithObjectNotLastString
);
Assert.Multiple(() =>
{
Assert.That(result.Index, Is.EqualTo(1));
Assert.That(result.Value, Is.InstanceOf<object>());
Assert.That(
JsonUtils.Serialize(result.Value),
Is.EqualTo(oneOfWithObjectNotLastString)
);
});
}

[Test]
public void Serialize_OneOfSingleType_Should_Return_Expected_String()
{
var oneOfSingle = OneOf<string>.FromT0("single");
const string oneOfSingleString = "\"single\"";

var result = JsonUtils.Serialize(oneOfSingle);
Assert.That(result, Is.EqualTo(oneOfSingleString));
}

[Test]
public void OneOfSingleType_Should_Deserialize_From_String()
{
const string oneOfSingleString = "\"single\"";
var result = JsonUtils.Deserialize<OneOf<string>>(oneOfSingleString);
Assert.Multiple(() =>
{
Assert.That(result.Index, Is.EqualTo(0));
Assert.That(result.Value, Is.EqualTo("single"));
});
}

[Test]
public void Deserialize_InvalidData_Should_Throw_Exception()
{
const string invalidJson = "{\"invalid\": \"data\"}";

Assert.Throws<JsonException>(() =>
{
JsonUtils.Deserialize<OneOf<string, int>>(invalidJson);
});
}
}
Loading
Loading