repo creation with initial code after cloning public repo
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests
|
||||
{
|
||||
public static class CopyToExtensionsTests
|
||||
{
|
||||
public static TheoryData<IReadOnlyList<int>, IList<int>, int, IList<int>> CopyTo_Valid_Correct_TestData()
|
||||
{
|
||||
var data = new TheoryData<IReadOnlyList<int>, IList<int>, int, IList<int>>
|
||||
{
|
||||
{ new[] { 0, 1, 2, 3, 4, 5 }, new[] { 0, 0, 0, 0, 0, 0 }, 0, new[] { 0, 1, 2, 3, 4, 5 } },
|
||||
{ new[] { 0, 1, 2 }, new[] { 5, 4, 3, 2, 1, 0 }, 2, new[] { 5, 4, 0, 1, 2, 0 } }
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(CopyTo_Valid_Correct_TestData))]
|
||||
public static void CopyTo_Valid_Correct(IReadOnlyList<int> source, IList<int> destination, int index, IList<int> expected)
|
||||
{
|
||||
source.CopyTo(destination, index);
|
||||
Assert.Equal(expected, destination);
|
||||
}
|
||||
|
||||
public static TheoryData<IReadOnlyList<int>, IList<int>, int> CopyTo_Invalid_ThrowsArgumentOutOfRangeException_TestData()
|
||||
{
|
||||
var data = new TheoryData<IReadOnlyList<int>, IList<int>, int>
|
||||
{
|
||||
{ new[] { 0, 1, 2, 3, 4, 5 }, new[] { 0, 0, 0, 0, 0, 0 }, -1 },
|
||||
{ new[] { 0, 1, 2 }, new[] { 5, 4, 3, 2, 1, 0 }, 6 },
|
||||
{ new[] { 0, 1, 2 }, Array.Empty<int>(), 0 },
|
||||
{ new[] { 0, 1, 2, 3, 4, 5 }, new[] { 0 }, 0 },
|
||||
{ new[] { 0, 1, 2, 3, 4, 5 }, new[] { 0, 0, 0, 0, 0, 0 }, 1 }
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(CopyTo_Invalid_ThrowsArgumentOutOfRangeException_TestData))]
|
||||
public static void CopyTo_Invalid_ThrowsArgumentOutOfRangeException(IReadOnlyList<int> source, IList<int> destination, int index)
|
||||
{
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => source.CopyTo(destination, index));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests;
|
||||
|
||||
public static class FileHelperTests
|
||||
{
|
||||
[Fact]
|
||||
public static void CreateEmpty_Valid_Correct()
|
||||
{
|
||||
var path = Path.Join(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
var fileInfo = new FileInfo(path);
|
||||
|
||||
Assert.False(fileInfo.Exists);
|
||||
|
||||
FileHelper.CreateEmpty(path);
|
||||
|
||||
fileInfo.Refresh();
|
||||
Assert.True(fileInfo.Exists);
|
||||
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests;
|
||||
|
||||
public static class FormattingStreamWriterTests
|
||||
{
|
||||
[Fact]
|
||||
public static void Shuffle_Valid_Correct()
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE", false);
|
||||
using (var ms = new MemoryStream())
|
||||
using (var txt = new FormattingStreamWriter(ms, CultureInfo.InvariantCulture))
|
||||
{
|
||||
txt.Write("{0}", 3.14159);
|
||||
txt.Close();
|
||||
Assert.Equal("3.14159", Encoding.UTF8.GetString(ms.ToArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<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="FsCheck.Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../MediaBrowser.Model/MediaBrowser.Model.csproj" />
|
||||
<ProjectReference Include="../../src/Jellyfin.Extensions/Jellyfin.Extensions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Text.Json;
|
||||
using FsCheck;
|
||||
using FsCheck.Fluent;
|
||||
using FsCheck.Xunit;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters
|
||||
{
|
||||
public class JsonBoolNumberTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions()
|
||||
{
|
||||
Converters =
|
||||
{
|
||||
new JsonBoolNumberConverter()
|
||||
}
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[InlineData("1", true)]
|
||||
[InlineData("0", false)]
|
||||
[InlineData("2", true)]
|
||||
[InlineData("true", true)]
|
||||
[InlineData("false", false)]
|
||||
public void Deserialize_Number_Valid_Success(string input, bool? output)
|
||||
{
|
||||
var value = JsonSerializer.Deserialize<bool>(input, _jsonOptions);
|
||||
Assert.Equal(value, output);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, "true")]
|
||||
[InlineData(false, "false")]
|
||||
public void Serialize_Bool_Success(bool input, string output)
|
||||
{
|
||||
var value = JsonSerializer.Serialize(input, _jsonOptions);
|
||||
Assert.Equal(value, output);
|
||||
}
|
||||
|
||||
[Property]
|
||||
public Property Deserialize_NonZeroInt_True(NonZeroInt input)
|
||||
=> JsonSerializer.Deserialize<bool>(input.ToString(), _jsonOptions).ToProperty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Text.Json;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters
|
||||
{
|
||||
public class JsonBoolStringTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions()
|
||||
{
|
||||
Converters =
|
||||
{
|
||||
new JsonBoolStringConverter()
|
||||
}
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"{ ""Value"": ""true"" }", true)]
|
||||
[InlineData(@"{ ""Value"": ""false"" }", false)]
|
||||
public void Deserialize_String_Valid_Success(string input, bool output)
|
||||
{
|
||||
var s = JsonSerializer.Deserialize<TestStruct>(input, _jsonOptions);
|
||||
Assert.Equal(s.Value, output);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, "true")]
|
||||
[InlineData(false, "false")]
|
||||
public void Serialize_Bool_Success(bool input, string output)
|
||||
{
|
||||
var value = JsonSerializer.Serialize(input, _jsonOptions);
|
||||
Assert.Equal(value, output);
|
||||
}
|
||||
|
||||
private readonly record struct TestStruct(bool Value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Extensions.Tests.Json.Models;
|
||||
using MediaBrowser.Model.Session;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters
|
||||
{
|
||||
public class JsonCommaDelimitedCollectionTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions()
|
||||
{
|
||||
Converters =
|
||||
{
|
||||
new JsonStringEnumConverter()
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_String_Null_Success()
|
||||
{
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<string>>(@"{ ""Value"": null }", _jsonOptions);
|
||||
Assert.Null(value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_Empty_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyArrayModel<string>
|
||||
{
|
||||
Value = Array.Empty<string>()
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<string>>(@"{ ""Value"": """" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_EmptyList_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyListModel<string>
|
||||
{
|
||||
Value = []
|
||||
};
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => JsonSerializer.Deserialize<GenericBodyListModel<string>>(@"{ ""Value"": """" }", _jsonOptions));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_EmptyIReadOnlyList_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyIReadOnlyListModel<string>
|
||||
{
|
||||
Value = []
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyIReadOnlyListModel<string>>(@"{ ""Value"": """" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_String_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyArrayModel<string>
|
||||
{
|
||||
Value = ["a", "b", "c"]
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<string>>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_StringList_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyListModel<string>
|
||||
{
|
||||
Value = ["a", "b", "c"]
|
||||
};
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => JsonSerializer.Deserialize<GenericBodyListModel<string>>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_String_Space_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyArrayModel<string>
|
||||
{
|
||||
Value = ["a", "b", "c"]
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<string>>(@"{ ""Value"": ""a, b, c"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_GenericCommandType_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyArrayModel<GeneralCommandType>
|
||||
{
|
||||
Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown]
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<GeneralCommandType>>(@"{ ""Value"": ""MoveUp,MoveDown"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_GenericCommandType_EmptyEntry_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyArrayModel<GeneralCommandType>
|
||||
{
|
||||
Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown]
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<GeneralCommandType>>(@"{ ""Value"": ""MoveUp,,MoveDown"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_GenericCommandType_Invalid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyArrayModel<GeneralCommandType>
|
||||
{
|
||||
Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown]
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<GeneralCommandType>>(@"{ ""Value"": ""MoveUp,TotallyNotAValidCommand,MoveDown"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_GenericCommandType_Space_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyArrayModel<GeneralCommandType>
|
||||
{
|
||||
Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown]
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<GeneralCommandType>>(@"{ ""Value"": ""MoveUp, MoveDown"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_String_Array_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyArrayModel<string>
|
||||
{
|
||||
Value = ["a", "b", "c"]
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<string>>(@"{ ""Value"": [""a"",""b"",""c""] }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_GenericCommandType_Array_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyArrayModel<GeneralCommandType>
|
||||
{
|
||||
Value = [GeneralCommandType.MoveUp, GeneralCommandType.MoveDown]
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyArrayModel<GeneralCommandType>>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_GenericCommandType_ReadOnlyArray_Valid_Success()
|
||||
{
|
||||
var valueToSerialize = new GenericBodyIReadOnlyCollectionModel<GeneralCommandType>
|
||||
{
|
||||
Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }.AsReadOnly()
|
||||
};
|
||||
|
||||
string value = JsonSerializer.Serialize<GenericBodyIReadOnlyCollectionModel<GeneralCommandType>>(valueToSerialize, _jsonOptions);
|
||||
Assert.Equal(@"{""Value"":[""MoveUp"",""MoveDown""]}", value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_GenericCommandType_ImmutableArrayArray_Valid_Success()
|
||||
{
|
||||
var valueToSerialize = new GenericBodyIReadOnlyCollectionModel<GeneralCommandType>
|
||||
{
|
||||
Value = ImmutableArray.Create(new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown })
|
||||
};
|
||||
|
||||
string value = JsonSerializer.Serialize<GenericBodyIReadOnlyCollectionModel<GeneralCommandType>>(valueToSerialize, _jsonOptions);
|
||||
Assert.Equal(@"{""Value"":[""MoveUp"",""MoveDown""]}", value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_GenericCommandType_List_Valid_Success()
|
||||
{
|
||||
var valueToSerialize = new GenericBodyIReadOnlyListModel<GeneralCommandType>
|
||||
{
|
||||
Value = new List<GeneralCommandType> { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }
|
||||
};
|
||||
|
||||
string value = JsonSerializer.Serialize<GenericBodyIReadOnlyListModel<GeneralCommandType>>(valueToSerialize, _jsonOptions);
|
||||
Assert.Equal(@"{""Value"":[""MoveUp"",""MoveDown""]}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Extensions.Tests.Json.Models;
|
||||
using MediaBrowser.Model.Session;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters
|
||||
{
|
||||
public class JsonCommaDelimitedIReadOnlyListTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions()
|
||||
{
|
||||
Converters =
|
||||
{
|
||||
new JsonStringEnumConverter()
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_String_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyIReadOnlyListModel<string>
|
||||
{
|
||||
Value = new[] { "a", "b", "c" }
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyIReadOnlyListModel<string>>(@"{ ""Value"": ""a,b,c"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_String_Space_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyIReadOnlyListModel<string>
|
||||
{
|
||||
Value = new[] { "a", "b", "c" }
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyIReadOnlyListModel<string>>(@"{ ""Value"": ""a, b, c"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_GenericCommandType_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyIReadOnlyListModel<GeneralCommandType>
|
||||
{
|
||||
Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyIReadOnlyListModel<GeneralCommandType>>(@"{ ""Value"": ""MoveUp,MoveDown"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_GenericCommandType_Space_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyIReadOnlyListModel<GeneralCommandType>
|
||||
{
|
||||
Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyIReadOnlyListModel<GeneralCommandType>>(@"{ ""Value"": ""MoveUp, MoveDown"" }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_String_Array_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyIReadOnlyListModel<string>
|
||||
{
|
||||
Value = new[] { "a", "b", "c" }
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyIReadOnlyListModel<string>>(@"{ ""Value"": [""a"",""b"",""c""] }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_GenericCommandType_Array_Valid_Success()
|
||||
{
|
||||
var desiredValue = new GenericBodyIReadOnlyListModel<GeneralCommandType>
|
||||
{
|
||||
Value = new[] { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }
|
||||
};
|
||||
|
||||
var value = JsonSerializer.Deserialize<GenericBodyIReadOnlyListModel<GeneralCommandType>>(@"{ ""Value"": [""MoveUp"", ""MoveDown""] }", _jsonOptions);
|
||||
Assert.Equal(desiredValue.Value, value?.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_GenericCommandType_IReadOnlyList_Valid_Success()
|
||||
{
|
||||
var valueToSerialize = new GenericBodyIReadOnlyListModel<GeneralCommandType>
|
||||
{
|
||||
Value = new List<GeneralCommandType> { GeneralCommandType.MoveUp, GeneralCommandType.MoveDown }
|
||||
};
|
||||
|
||||
string value = JsonSerializer.Serialize<GenericBodyIReadOnlyListModel<GeneralCommandType>>(valueToSerialize, _jsonOptions);
|
||||
Assert.Equal(@"{""Value"":[""MoveUp"",""MoveDown""]}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
using System.Text.Json;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters;
|
||||
|
||||
public class JsonDefaultStringEnumConverterTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _jsonOptions = new() { Converters = { new JsonDefaultStringEnumConverterFactory() } };
|
||||
|
||||
/// <summary>
|
||||
/// Test to ensure that `null` and empty string are deserialized to the default value.
|
||||
/// </summary>
|
||||
/// <param name="input">The input string.</param>
|
||||
/// <param name="output">The expected enum value.</param>
|
||||
[Theory]
|
||||
[InlineData("\"\"", MediaStreamProtocol.http)]
|
||||
[InlineData("\"Http\"", MediaStreamProtocol.http)]
|
||||
[InlineData("\"Hls\"", MediaStreamProtocol.hls)]
|
||||
public void Deserialize_Enum_Direct(string input, MediaStreamProtocol output)
|
||||
{
|
||||
var value = JsonSerializer.Deserialize<MediaStreamProtocol>(input, _jsonOptions);
|
||||
Assert.Equal(output, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to ensure that `null` and empty string are deserialized to the default value.
|
||||
/// </summary>
|
||||
/// <param name="input">The input string.</param>
|
||||
/// <param name="output">The expected enum value.</param>
|
||||
[Theory]
|
||||
[InlineData(null, MediaStreamProtocol.http)]
|
||||
[InlineData("\"\"", MediaStreamProtocol.http)]
|
||||
[InlineData("\"Http\"", MediaStreamProtocol.http)]
|
||||
[InlineData("\"Hls\"", MediaStreamProtocol.hls)]
|
||||
public void Deserialize_Enum(string? input, MediaStreamProtocol output)
|
||||
{
|
||||
input ??= "null";
|
||||
var json = $"{{ \"EnumValue\": {input} }}";
|
||||
var value = JsonSerializer.Deserialize<TestClass>(json, _jsonOptions);
|
||||
Assert.NotNull(value);
|
||||
Assert.Equal(output, value.EnumValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test to ensure that empty string is deserialized to the default value,
|
||||
/// and `null` is deserialized to `null`.
|
||||
/// </summary>
|
||||
/// <param name="input">The input string.</param>
|
||||
/// <param name="output">The expected enum value.</param>
|
||||
[Theory]
|
||||
[InlineData(null, null)]
|
||||
[InlineData("\"\"", MediaStreamProtocol.http)]
|
||||
[InlineData("\"Http\"", MediaStreamProtocol.http)]
|
||||
[InlineData("\"Hls\"", MediaStreamProtocol.hls)]
|
||||
public void Deserialize_Enum_Nullable(string? input, MediaStreamProtocol? output)
|
||||
{
|
||||
input ??= "null";
|
||||
var json = $"{{ \"EnumValue\": {input} }}";
|
||||
var value = JsonSerializer.Deserialize<NullTestClass>(json, _jsonOptions);
|
||||
Assert.NotNull(value);
|
||||
Assert.Equal(output, value.EnumValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the roundtrip serialization & deserialization is successful.
|
||||
/// </summary>
|
||||
/// <param name="input">Input enum.</param>
|
||||
/// <param name="output">Output enum.</param>
|
||||
[Theory]
|
||||
[InlineData(MediaStreamProtocol.http, MediaStreamProtocol.http)]
|
||||
[InlineData(MediaStreamProtocol.hls, MediaStreamProtocol.hls)]
|
||||
public void Enum_RoundTrip(MediaStreamProtocol input, MediaStreamProtocol output)
|
||||
{
|
||||
var inputObj = new TestClass { EnumValue = input };
|
||||
|
||||
var outputObj = JsonSerializer.Deserialize<TestClass>(JsonSerializer.Serialize(inputObj, _jsonOptions), _jsonOptions);
|
||||
|
||||
Assert.NotNull(outputObj);
|
||||
Assert.Equal(output, outputObj.EnumValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the roundtrip serialization & deserialization is successful, including null.
|
||||
/// </summary>
|
||||
/// <param name="input">Input enum.</param>
|
||||
/// <param name="output">Output enum.</param>
|
||||
[Theory]
|
||||
[InlineData(MediaStreamProtocol.http, MediaStreamProtocol.http)]
|
||||
[InlineData(MediaStreamProtocol.hls, MediaStreamProtocol.hls)]
|
||||
[InlineData(null, null)]
|
||||
public void Enum_RoundTrip_Nullable(MediaStreamProtocol? input, MediaStreamProtocol? output)
|
||||
{
|
||||
var inputObj = new NullTestClass { EnumValue = input };
|
||||
|
||||
var outputObj = JsonSerializer.Deserialize<NullTestClass>(JsonSerializer.Serialize(inputObj, _jsonOptions), _jsonOptions);
|
||||
|
||||
Assert.NotNull(outputObj);
|
||||
Assert.Equal(output, outputObj.EnumValue);
|
||||
}
|
||||
|
||||
private sealed class TestClass
|
||||
{
|
||||
public MediaStreamProtocol EnumValue { get; set; }
|
||||
}
|
||||
|
||||
private sealed class NullTestClass
|
||||
{
|
||||
public MediaStreamProtocol? EnumValue { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Text.Json;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
using MediaBrowser.Model.Session;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters;
|
||||
|
||||
public class JsonFlagEnumTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _jsonOptions = new()
|
||||
{
|
||||
Converters =
|
||||
{
|
||||
new JsonFlagEnumConverter<TranscodeReason>()
|
||||
}
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[InlineData(TranscodeReason.AudioIsExternal | TranscodeReason.ContainerNotSupported, "[\"ContainerNotSupported\",\"AudioIsExternal\"]")]
|
||||
[InlineData(TranscodeReason.AudioIsExternal | TranscodeReason.ContainerNotSupported | TranscodeReason.VideoBitDepthNotSupported, "[\"ContainerNotSupported\",\"AudioIsExternal\",\"VideoBitDepthNotSupported\"]")]
|
||||
[InlineData((TranscodeReason)0, "[]")]
|
||||
public void Serialize_Transcode_Reason(TranscodeReason transcodeReason, string output)
|
||||
{
|
||||
var result = JsonSerializer.Serialize(transcodeReason, _jsonOptions);
|
||||
|
||||
Assert.Equal(output, result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters
|
||||
{
|
||||
public class JsonGuidConverterTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _options;
|
||||
|
||||
public JsonGuidConverterTests()
|
||||
{
|
||||
_options = new JsonSerializerOptions();
|
||||
_options.Converters.Add(new JsonGuidConverter());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_Valid_Success()
|
||||
{
|
||||
Guid value = JsonSerializer.Deserialize<Guid>(@"""a852a27afe324084ae66db579ee3ee18""", _options);
|
||||
Assert.Equal(new Guid("a852a27afe324084ae66db579ee3ee18"), value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_ValidDashed_Success()
|
||||
{
|
||||
Guid value = JsonSerializer.Deserialize<Guid>(@"""e9b2dcaa-529c-426e-9433-5e9981f27f2e""", _options);
|
||||
Assert.Equal(new Guid("e9b2dcaa-529c-426e-9433-5e9981f27f2e"), value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Roundtrip_Valid_Success()
|
||||
{
|
||||
Guid guid = new Guid("a852a27afe324084ae66db579ee3ee18");
|
||||
string value = JsonSerializer.Serialize(guid, _options);
|
||||
Assert.Equal(guid, JsonSerializer.Deserialize<Guid>(value, _options));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_Null_EmptyGuid()
|
||||
{
|
||||
Assert.Equal(Guid.Empty, JsonSerializer.Deserialize<Guid>("null", _options));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_EmptyGuid_EmptyGuid()
|
||||
{
|
||||
Assert.Equal($"\"{Guid.Empty:N}\"", JsonSerializer.Serialize(Guid.Empty, _options));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_Valid_NoDash_Success()
|
||||
{
|
||||
var guid = new Guid("531797E9-9457-40E0-88BC-B1D6D38752FA");
|
||||
var str = JsonSerializer.Serialize(guid, _options);
|
||||
Assert.Equal($"\"{guid:N}\"", str);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_Nullable_Success()
|
||||
{
|
||||
Guid? guid = new Guid("531797E9-9457-40E0-88BC-B1D6D38752FA");
|
||||
var str = JsonSerializer.Serialize(guid, _options);
|
||||
Assert.Equal($"\"{guid:N}\"", str);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters
|
||||
{
|
||||
public class JsonNullableGuidConverterTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _options;
|
||||
|
||||
public JsonNullableGuidConverterTests()
|
||||
{
|
||||
_options = new JsonSerializerOptions();
|
||||
_options.Converters.Add(new JsonNullableGuidConverter());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_Valid_Success()
|
||||
{
|
||||
Guid? value = JsonSerializer.Deserialize<Guid?>(@"""a852a27afe324084ae66db579ee3ee18""", _options);
|
||||
Assert.Equal(new Guid("a852a27afe324084ae66db579ee3ee18"), value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_ValidDashed_Success()
|
||||
{
|
||||
Guid? value = JsonSerializer.Deserialize<Guid?>(@"""e9b2dcaa-529c-426e-9433-5e9981f27f2e""", _options);
|
||||
Assert.Equal(new Guid("e9b2dcaa-529c-426e-9433-5e9981f27f2e"), value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Roundtrip_Valid_Success()
|
||||
{
|
||||
Guid guid = new Guid("a852a27afe324084ae66db579ee3ee18");
|
||||
string value = JsonSerializer.Serialize(guid, _options);
|
||||
Assert.Equal(guid, JsonSerializer.Deserialize<Guid?>(value, _options));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_Null_Null()
|
||||
{
|
||||
Assert.Null(JsonSerializer.Deserialize<Guid?>("null", _options));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_EmptyGuid_EmptyGuid()
|
||||
{
|
||||
Assert.Equal(Guid.Empty, JsonSerializer.Deserialize<Guid?>(@"""00000000-0000-0000-0000-000000000000""", _options));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_EmptyGuid_Null()
|
||||
{
|
||||
Assert.Equal("null", JsonSerializer.Serialize((Guid?)Guid.Empty, _options));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_Null_Null()
|
||||
{
|
||||
Assert.Equal("null", JsonSerializer.Serialize((Guid?)null, _options));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_Valid_NoDash_Success()
|
||||
{
|
||||
var guid = (Guid?)new Guid("531797E9-9457-40E0-88BC-B1D6D38752FA");
|
||||
var str = JsonSerializer.Serialize(guid, _options);
|
||||
Assert.Equal($"\"{guid:N}\"", str);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_Nullable_Success()
|
||||
{
|
||||
Guid? guid = new Guid("531797E9-9457-40E0-88BC-B1D6D38752FA");
|
||||
var str = JsonSerializer.Serialize(guid, _options);
|
||||
Assert.Equal($"\"{guid:N}\"", str);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Text.Json;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters
|
||||
{
|
||||
public class JsonStringConverterTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _jsonSerializerOptions = new()
|
||||
{
|
||||
Converters =
|
||||
{
|
||||
new JsonStringConverter()
|
||||
}
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[InlineData("\"test\"", "test")]
|
||||
[InlineData("123", "123")]
|
||||
[InlineData("123.45", "123.45")]
|
||||
[InlineData("true", "true")]
|
||||
[InlineData("false", "false")]
|
||||
public void Deserialize_String_Valid_Success(string input, string output)
|
||||
{
|
||||
var deserialized = JsonSerializer.Deserialize<string>(input, _jsonSerializerOptions);
|
||||
Assert.Equal(deserialized, output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_Int32asInt32_Valid_Success()
|
||||
{
|
||||
const string? input = "123";
|
||||
const int output = 123;
|
||||
var deserialized = JsonSerializer.Deserialize<int>(input, _jsonSerializerOptions);
|
||||
Assert.Equal(output, deserialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Converters
|
||||
{
|
||||
public class JsonVersionConverterTests
|
||||
{
|
||||
private readonly JsonSerializerOptions _options;
|
||||
|
||||
public JsonVersionConverterTests()
|
||||
{
|
||||
_options = new JsonSerializerOptions();
|
||||
_options.Converters.Add(new JsonVersionConverter());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deserialize_Version_Success()
|
||||
{
|
||||
var input = "\"1.025.222\"";
|
||||
var output = new Version(1, 25, 222);
|
||||
var deserializedInput = JsonSerializer.Deserialize<Version>(input, _options);
|
||||
Assert.Equal(output, deserializedInput);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serialize_Version_Success()
|
||||
{
|
||||
var input = new Version(1, 09, 59);
|
||||
var output = "\"1.9.59\"";
|
||||
var serializedInput = JsonSerializer.Serialize(input, _options);
|
||||
Assert.Equal(output, serializedInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The generic body model.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The value type.</typeparam>
|
||||
public sealed class GenericBodyArrayModel<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the value.
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Performance", "CA1819:Properties should not return arrays", MessageId = "Value", Justification = "Imported from ServiceStack")]
|
||||
[JsonConverter(typeof(JsonCommaDelimitedCollectionConverterFactory))]
|
||||
public T[] Value { get; set; } = default!;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The generic body <c>IReadOnlyCollection</c> model.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The value type.</typeparam>
|
||||
public sealed class GenericBodyIReadOnlyCollectionModel<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the value.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonCommaDelimitedCollectionConverterFactory))]
|
||||
public IReadOnlyCollection<T> Value { get; set; } = default!;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The generic body <c>IReadOnlyList</c> model.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The value type.</typeparam>
|
||||
public sealed class GenericBodyIReadOnlyListModel<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the value.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonCommaDelimitedCollectionConverterFactory))]
|
||||
public IReadOnlyList<T> Value { get; set; } = default!;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma warning disable CA1002 // Do not expose generic lists
|
||||
#pragma warning disable CA2227 // Collection properties should be read only
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Extensions.Json.Converters;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests.Json.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The generic body <c>List</c> model.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The value type.</typeparam>
|
||||
public sealed class GenericBodyListModel<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the value.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonCommaDelimitedCollectionConverterFactory))]
|
||||
public List<T> Value { get; set; } = default!;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests
|
||||
{
|
||||
public static class ShuffleExtensionsTests
|
||||
{
|
||||
[Fact]
|
||||
public static void Shuffle_Valid_Correct()
|
||||
{
|
||||
byte[] original = new byte[1 << 6];
|
||||
Random.Shared.NextBytes(original);
|
||||
byte[] shuffled = (byte[])original.Clone();
|
||||
shuffled.Shuffle();
|
||||
|
||||
Assert.NotEqual(original, shuffled);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Extensions.Tests
|
||||
{
|
||||
public class StringExtensionsTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("", "")] // Identity edge-case (no diacritics)
|
||||
[InlineData("Indiana Jones", "Indiana Jones")] // Identity (no diacritics)
|
||||
[InlineData("a\ud800b", "ab")] // Invalid UTF-16 char stripping
|
||||
[InlineData("åäö", "aao")] // Issue #7484
|
||||
[InlineData("Jön", "Jon")] // Issue #7484
|
||||
[InlineData("Jönssonligan", "Jonssonligan")] // Issue #7484
|
||||
[InlineData("Kieślowski", "Kieslowski")] // Issue #7450
|
||||
[InlineData("Cidadão Kane", "Cidadao Kane")] // Issue #7560
|
||||
[InlineData("운명처럼 널 사랑해", "운명처럼 널 사랑해")] // Issue #6393 (Korean language support)
|
||||
[InlineData("애타는 로맨스", "애타는 로맨스")] // Issue #6393
|
||||
[InlineData("Le cœur a ses raisons", "Le coeur a ses raisons")] // Issue #8893
|
||||
[InlineData("Béla Tarr", "Bela Tarr")] // Issue #8893
|
||||
public void RemoveDiacritics_ValidInput_Corrects(string input, string expectedResult)
|
||||
{
|
||||
string result = input.RemoveDiacritics();
|
||||
Assert.Equal(expectedResult, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", false)] // Identity edge-case (no diacritics)
|
||||
[InlineData("Indiana Jones", false)] // Identity (no diacritics)
|
||||
[InlineData("a\ud800b", true)] // Invalid UTF-16 char stripping
|
||||
[InlineData("åäö", true)] // Issue #7484
|
||||
[InlineData("Jön", true)] // Issue #7484
|
||||
[InlineData("Jönssonligan", true)] // Issue #7484
|
||||
[InlineData("Kieślowski", true)] // Issue #7450
|
||||
[InlineData("Cidadão Kane", true)] // Issue #7560
|
||||
[InlineData("운명처럼 널 사랑해", false)] // Issue #6393 (Korean language support)
|
||||
[InlineData("애타는 로맨스", false)] // Issue #6393
|
||||
[InlineData("Le cœur a ses raisons", true)] // Issue #8893
|
||||
[InlineData("Béla Tarr", true)] // Issue #8893
|
||||
public void HasDiacritics_ValidInput_Corrects(string input, bool expectedResult)
|
||||
{
|
||||
bool result = input.HasDiacritics();
|
||||
Assert.Equal(expectedResult, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", '_', 0)]
|
||||
[InlineData("___", '_', 3)]
|
||||
[InlineData("test\x00", '\x00', 1)]
|
||||
[InlineData("Imdb=tt0119567|Tmdb=330|TmdbCollection=328", '|', 2)]
|
||||
public void ReadOnlySpan_Count_Success(string str, char needle, int count)
|
||||
{
|
||||
Assert.Equal(count, str.AsSpan().Count(needle));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", 'q', "")]
|
||||
[InlineData("Banana split", ' ', "Banana")]
|
||||
[InlineData("Banana split", 'q', "Banana split")]
|
||||
[InlineData("Banana split 2", ' ', "Banana")]
|
||||
public void LeftPart_ValidArgsCharNeedle_Correct(string str, char needle, string expectedResult)
|
||||
{
|
||||
var result = str.AsSpan().LeftPart(needle).ToString();
|
||||
Assert.Equal(expectedResult, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", 'q', "")]
|
||||
[InlineData("Banana split", ' ', "split")]
|
||||
[InlineData("Banana split", 'q', "Banana split")]
|
||||
[InlineData("Banana split.", '.', "")]
|
||||
[InlineData("Banana split 2", ' ', "2")]
|
||||
public void RightPart_ValidArgsCharNeedle_Correct(string str, char needle, string expectedResult)
|
||||
{
|
||||
var result = str.AsSpan().RightPart(needle).ToString();
|
||||
Assert.Equal(expectedResult, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+4
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("Jellyfin.Extensions.Tests")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("Jellyfin.Extensions.Tests")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("Jellyfin.Extensions.Tests")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
a9cd9f1b54cb0c14d8cfa5b8178fecf508c852c97b2e4a7c895ddcc7cc974ad2
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net10.0
|
||||
build_property.TargetFramework = net10.0
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkVersion = v10.0
|
||||
build_property.TargetFrameworkVersion = v10.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = Jellyfin.Extensions.Tests
|
||||
build_property.ProjectDir = /srv/common_drive/Projects/pgsql-jellyfin/tests/Jellyfin.Extensions.Tests/
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.EffectiveAnalysisLevelStyle = 10.0
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+2744
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/wjones/.nuget/packages/</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/wjones/.nuget/packages/</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="/home/wjones/.nuget/packages/" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)xunit.runner.visualstudio/2.8.2/build/net6.0/xunit.runner.visualstudio.props" Condition="Exists('$(NuGetPackageRoot)xunit.runner.visualstudio/2.8.2/build/net6.0/xunit.runner.visualstudio.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)xunit.core/2.9.3/build/xunit.core.props" Condition="Exists('$(NuGetPackageRoot)xunit.core/2.9.3/build/xunit.core.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.testplatform.testhost/18.0.1/build/net8.0/Microsoft.TestPlatform.TestHost.props" Condition="Exists('$(NuGetPackageRoot)microsoft.testplatform.testhost/18.0.1/build/net8.0/Microsoft.TestPlatform.TestHost.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.codecoverage/18.0.1/build/netstandard2.0/Microsoft.CodeCoverage.props" Condition="Exists('$(NuGetPackageRoot)microsoft.codecoverage/18.0.1/build/netstandard2.0/Microsoft.CodeCoverage.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.net.test.sdk/18.0.1/build/net8.0/Microsoft.NET.Test.Sdk.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.test.sdk/18.0.1/build/net8.0/Microsoft.NET.Test.Sdk.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore/10.0.3/buildTransitive/net10.0/Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore/10.0.3/buildTransitive/net10.0/Microsoft.EntityFrameworkCore.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.props" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Pkgxunit_analyzers Condition=" '$(Pkgxunit_analyzers)' == '' ">/home/wjones/.nuget/packages/xunit.analyzers/1.18.0</Pkgxunit_analyzers>
|
||||
<PkgStyleCop_Analyzers_Unstable Condition=" '$(PkgStyleCop_Analyzers_Unstable)' == '' ">/home/wjones/.nuget/packages/stylecop.analyzers.unstable/1.2.0.556</PkgStyleCop_Analyzers_Unstable>
|
||||
<PkgSmartAnalyzers_MultithreadingAnalyzer Condition=" '$(PkgSmartAnalyzers_MultithreadingAnalyzer)' == '' ">/home/wjones/.nuget/packages/smartanalyzers.multithreadinganalyzer/1.1.31</PkgSmartAnalyzers_MultithreadingAnalyzer>
|
||||
<PkgSerilogAnalyzer Condition=" '$(PkgSerilogAnalyzer)' == '' ">/home/wjones/.nuget/packages/seriloganalyzer/0.15.0</PkgSerilogAnalyzer>
|
||||
<PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers)' == '' ">/home/wjones/.nuget/packages/microsoft.codeanalysis.bannedapianalyzers/4.14.0</PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)xunit.core/2.9.3/build/xunit.core.targets" Condition="Exists('$(NuGetPackageRoot)xunit.core/2.9.3/build/xunit.core.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.testplatform.testhost/18.0.1/build/net8.0/Microsoft.TestPlatform.TestHost.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.testplatform.testhost/18.0.1/build/net8.0/Microsoft.TestPlatform.TestHost.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.codecoverage/18.0.1/build/netstandard2.0/Microsoft.CodeCoverage.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codecoverage/18.0.1/build/netstandard2.0/Microsoft.CodeCoverage.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.net.test.sdk/18.0.1/build/net8.0/Microsoft.NET.Test.Sdk.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.test.sdk/18.0.1/build/net8.0/Microsoft.NET.Test.Sdk.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Options.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)coverlet.collector/8.0.0/build/net8.0/coverlet.collector.targets" Condition="Exists('$(NuGetPackageRoot)coverlet.collector/8.0.0/build/net8.0/coverlet.collector.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "0dsNVQWWNB8=",
|
||||
"success": true,
|
||||
"projectFilePath": "/srv/common_drive/Projects/pgsql-jellyfin/tests/Jellyfin.Extensions.Tests/Jellyfin.Extensions.Tests.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"/home/wjones/.nuget/packages/coverlet.collector/8.0.0/coverlet.collector.8.0.0.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/diacritics/4.1.4/diacritics.4.1.4.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/fscheck/3.3.2/fscheck.3.3.2.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/fscheck.xunit/3.3.2/fscheck.xunit.3.3.2.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/fsharp.core/5.0.2/fsharp.core.5.0.2.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/icu4n/60.1.0-alpha.356/icu4n.60.1.0-alpha.356.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/icu4n.transliterator/60.1.0-alpha.356/icu4n.transliterator.60.1.0-alpha.356.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/j2n/2.0.0/j2n.2.0.0.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.codeanalysis.bannedapianalyzers/4.14.0/microsoft.codeanalysis.bannedapianalyzers.4.14.0.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.codecoverage/18.0.1/microsoft.codecoverage.18.0.1.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore/10.0.3/microsoft.entityframeworkcore.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore.abstractions/10.0.3/microsoft.entityframeworkcore.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore.analyzers/10.0.3/microsoft.entityframeworkcore.analyzers.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore.relational/10.0.3/microsoft.entityframeworkcore.relational.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.caching.abstractions/10.0.3/microsoft.extensions.caching.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.caching.memory/10.0.3/microsoft.extensions.caching.memory.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.configuration.abstractions/10.0.3/microsoft.extensions.configuration.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.dependencyinjection/10.0.3/microsoft.extensions.dependencyinjection.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.dependencyinjection.abstractions/10.0.3/microsoft.extensions.dependencyinjection.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.logging/10.0.3/microsoft.extensions.logging.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.logging.abstractions/10.0.3/microsoft.extensions.logging.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.options/10.0.3/microsoft.extensions.options.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.primitives/10.0.3/microsoft.extensions.primitives.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.net.test.sdk/18.0.1/microsoft.net.test.sdk.18.0.1.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.testplatform.objectmodel/18.0.1/microsoft.testplatform.objectmodel.18.0.1.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.testplatform.testhost/18.0.1/microsoft.testplatform.testhost.18.0.1.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/polly/8.6.5/polly.8.6.5.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/polly.core/8.6.5/polly.core.8.6.5.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/seriloganalyzer/0.15.0/seriloganalyzer.0.15.0.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/smartanalyzers.multithreadinganalyzer/1.1.31/smartanalyzers.multithreadinganalyzer.1.1.31.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/stylecop.analyzers/1.2.0-beta.556/stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/stylecop.analyzers.unstable/1.2.0.556/stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/xunit/2.9.3/xunit.2.9.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/xunit.abstractions/2.0.3/xunit.abstractions.2.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/xunit.analyzers/1.18.0/xunit.analyzers.1.18.0.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/xunit.assert/2.9.3/xunit.assert.2.9.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/xunit.core/2.9.3/xunit.core.2.9.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/xunit.extensibility.core/2.9.3/xunit.extensibility.core.2.9.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/xunit.extensibility.execution/2.9.3/xunit.extensibility.execution.2.9.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/xunit.runner.visualstudio/2.8.2/xunit.runner.visualstudio.2.8.2.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
17714532033100000
|
||||
@@ -0,0 +1 @@
|
||||
17715044195400000
|
||||
Reference in New Issue
Block a user