-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: [ main ] | ||
pull_request: | ||
branches: [ main ] | ||
|
||
jobs: | ||
build: | ||
name: Build | ||
runs-on: ${{ matrix.os }} | ||
|
||
strategy: | ||
matrix: | ||
os: [ubuntu-latest, windows-latest] | ||
configuration: [ 'Debug', 'Release' ] | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
|
||
- name: Setup .NET | ||
uses: actions/setup-dotnet@v2 | ||
with: | ||
dotnet-version: '9.0.x' | ||
|
||
- name: Restore dependencies | ||
run: dotnet restore | ||
|
||
- name: Build | ||
run: dotnet build --configuration ${{ matrix.configuration }} --no-restore | ||
|
||
test: | ||
name: Test | ||
runs-on: ${{ matrix.os }} | ||
|
||
needs: build | ||
|
||
strategy: | ||
matrix: | ||
os: [ubuntu-latest, windows-latest] | ||
configuration: [ 'Release' ] | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
|
||
- name: Setup .NET | ||
uses: actions/setup-dotnet@v2 | ||
with: | ||
dotnet-version: '9.0.x' | ||
|
||
- name: Test | ||
run: dotnet test --configuration Release --verbosity normal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
using System.Runtime.CompilerServices; | ||
|
||
[assembly: InternalsVisibleTo("Riverside.JsonBinder.Tests")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
namespace Riverside.JsonBinder.Tests; | ||
|
||
[TestClass] | ||
public class JsonSerializerTests | ||
{ | ||
[TestMethod] | ||
[DataRow("{\"name\":\"John\"}", SerializableLanguage.CSharp, "public class Root\n{\n public string name { get; set; }\n}")] | ||
[DataRow("{\"name\":\"John\"}", SerializableLanguage.Python, "class Root:\n def __init__(self):\n self.name: str = None")] | ||
[DataRow("{\"name\":\"John\"}", SerializableLanguage.Java, "public class Root {\n private String name;\n public String getname() { return name; }\n public void setname(String name) { this.name = name; }\n}")] | ||
public void ConvertTo_ValidJson_ReturnsExpectedResult(string json, SerializableLanguage language, string expected) | ||
{ | ||
// Act | ||
var result = JsonSerializer.ConvertTo(json, language); | ||
|
||
// Assert | ||
Assert.AreEqual(Normalize(expected), Normalize(result)); | ||
} | ||
|
||
[TestMethod] | ||
public void ConvertTo_InvalidJson_ThrowsException() | ||
{ | ||
// Arrange | ||
string invalidJson = "invalid json"; | ||
|
||
// Act | ||
try | ||
{ | ||
// Stupidly, JsonReaderException is internal, so it can't be caught. | ||
// Instead, we need to compare the exception message with the expected message. | ||
JsonSerializer.ConvertTo(invalidJson, SerializableLanguage.CSharp); | ||
} | ||
catch (Exception ex) | ||
{ | ||
// Assert | ||
Assert.AreEqual("'i' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.", ex.Message); | ||
} | ||
} | ||
|
||
[TestMethod] | ||
[ExpectedException(typeof(ArgumentNullException))] | ||
public void ConvertTo_NullJson_ThrowsException() | ||
{ | ||
// Arrange | ||
string? invalidJson = null; | ||
|
||
JsonSerializer.ConvertTo(invalidJson, SerializableLanguage.CSharp); | ||
Check warning on line 46 in tests/Riverside.JsonBinder.Tests/JsonSerializerTests.cs
|
||
} | ||
|
||
[TestMethod] | ||
[ExpectedException(typeof(NotSupportedException))] | ||
public void ConvertTo_UnsupportedLanguage_ThrowsNotSupportedException() | ||
{ | ||
// Arrange | ||
string json = "{\"name\":\"John\"}"; | ||
|
||
// Act | ||
JsonSerializer.ConvertTo(json, (SerializableLanguage)0xFFFFFF); | ||
} | ||
|
||
[TestMethod] | ||
public void ConvertTo_JsonArray_WrapsInRootObject() | ||
{ | ||
// Arrange | ||
string jsonArray = "[{\"name\":\"John\"}]"; | ||
string expected = """ | ||
public class Root | ||
{ | ||
public List<Items> Items { get; set; } | ||
} | ||
public class ItemsItem | ||
{ | ||
public string name { get; set; } | ||
} | ||
public class Items | ||
{ | ||
public List<ItemsItem> Items { get; set; } = new List<ItemsItem>(); | ||
} | ||
"""; | ||
// Act | ||
var result = JsonSerializer.ConvertTo(jsonArray, SerializableLanguage.CSharp); | ||
|
||
// Assert | ||
Assert.AreEqual(Normalize(expected), Normalize(result)); | ||
} | ||
|
||
private static string Normalize(string input) | ||
=> input.Replace("\r\n", "\n").Trim(); | ||
} |
97 changes: 97 additions & 0 deletions
97
tests/Riverside.JsonBinder.Tests/LanguageSerializerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
using System.Text.Json.Nodes; | ||
using Riverside.JsonBinder.Serialization; | ||
|
||
namespace Riverside.JsonBinder.Tests; | ||
|
||
[TestClass] | ||
public class LanguageSerializerTests | ||
{ | ||
private static readonly Dictionary<SerializableLanguage, Type> SerializerTypes = new() | ||
{ | ||
{ SerializableLanguage.CSharp, typeof(CSharpSerializer) }, | ||
{ SerializableLanguage.Python, typeof(PythonSerializer) }, | ||
{ SerializableLanguage.Java, typeof(JavaSerializer) }, | ||
{ SerializableLanguage.JavaScript, typeof(JavaScriptSerializer) }, | ||
{ SerializableLanguage.TypeScript, typeof(TypeScriptSerializer) }, | ||
{ SerializableLanguage.PHP, typeof(PHPSerializer) }, | ||
{ SerializableLanguage.Ruby, typeof(RubySerializer) }, | ||
{ SerializableLanguage.Swift, typeof(SwiftSerializer) } | ||
}; | ||
|
||
[TestMethod] | ||
[DynamicData(nameof(GetTestData), DynamicDataSourceType.Method)] | ||
public void GenerateClasses_ValidJson_ReturnsExpectedResult(SerializableLanguage language, string json, string expected) | ||
{ | ||
// Arrange | ||
if (!SerializerTypes.TryGetValue(language, out var serializerType) || serializerType == null) | ||
{ | ||
Assert.Fail($"Serializer for language {language} not found."); | ||
return; | ||
} | ||
|
||
var serializer = (LanguageSerializer?)Activator.CreateInstance(serializerType); | ||
Assert.IsNotNull(serializer, $"Failed to create instance of {serializerType}"); | ||
|
||
// Act | ||
var jsonNode = JsonNode.Parse(json); | ||
Assert.IsNotNull(jsonNode, "Failed to parse JSON"); | ||
|
||
var result = serializer.GenerateClasses(jsonNode, "Root"); | ||
|
||
// Assert | ||
Assert.AreEqual(expected.Normalize(), result.Normalize()); | ||
} | ||
|
||
[TestMethod] | ||
[DynamicData(nameof(GetInvalidJsonTestData), DynamicDataSourceType.Method)] | ||
public void GenerateClasses_InvalidJson_ThrowsException(SerializableLanguage language, string invalidJson) | ||
{ | ||
// Arrange | ||
if (!SerializerTypes.TryGetValue(language, out var serializerType) || serializerType == null) | ||
{ | ||
Assert.Fail($"Serializer for language {language} not found."); | ||
return; | ||
} | ||
|
||
var serializer = (LanguageSerializer?)Activator.CreateInstance(serializerType); | ||
Assert.IsNotNull(serializer, $"Failed to create instance of {serializerType}"); | ||
|
||
// Act | ||
try | ||
{ | ||
var jsonNode = JsonNode.Parse(invalidJson); | ||
Assert.IsNotNull(jsonNode, "Failed to parse JSON"); | ||
|
||
serializer.GenerateClasses(jsonNode, "Root"); | ||
} | ||
catch (Exception ex) | ||
{ | ||
// Assert | ||
Assert.AreEqual("'i' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.", ex.Message); | ||
} | ||
} | ||
|
||
public static IEnumerable<object[]> GetTestData() | ||
{ | ||
yield return new object[] { SerializableLanguage.CSharp, "{\"name\":\"John\"}", "public class Root\n{\n public string name { get; set; }\n}" }; | ||
yield return new object[] { SerializableLanguage.Python, "{\"name\":\"John\"}", "class Root:\n def __init__(self):\n self.name: str = None" }; | ||
yield return new object[] { SerializableLanguage.Java, "{\"name\":\"John\"}", "public class Root {\n private String name;\n public String getname() { return name; }\n public void setname(String name) { this.name = name; }\n}" }; | ||
yield return new object[] { SerializableLanguage.JavaScript, "{\"name\":\"John\"}", "class Root {\n constructor() {\n this.name = null;\n }\n}" }; | ||
yield return new object[] { SerializableLanguage.TypeScript, "{\"name\":\"John\"}", "class Root {\n constructor() {\n this.name = null;\n }\n}" }; | ||
yield return new object[] { SerializableLanguage.PHP, "{\"name\":\"John\"}", "class Root {\n public $name;\n}" }; | ||
yield return new object[] { SerializableLanguage.Ruby, "{\"name\":\"John\"}", "class Root\n attr_accessor :name\nend" }; | ||
yield return new object[] { SerializableLanguage.Swift, "{\"name\":\"John\"}", "struct Root {\n var name: String?\n}" }; | ||
} | ||
|
||
public static IEnumerable<object[]> GetInvalidJsonTestData() | ||
{ | ||
yield return new object[] { SerializableLanguage.CSharp, "invalid json" }; | ||
yield return new object[] { SerializableLanguage.Python, "invalid json" }; | ||
yield return new object[] { SerializableLanguage.Java, "invalid json" }; | ||
yield return new object[] { SerializableLanguage.JavaScript, "invalid json" }; | ||
yield return new object[] { SerializableLanguage.TypeScript, "invalid json" }; | ||
yield return new object[] { SerializableLanguage.PHP, "invalid json" }; | ||
yield return new object[] { SerializableLanguage.Ruby, "invalid json" }; | ||
yield return new object[] { SerializableLanguage.Swift, "invalid json" }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] |
24 changes: 24 additions & 0 deletions
24
tests/Riverside.JsonBinder.Tests/Riverside.JsonBinder.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<Project Sdk="MSTest.Sdk/3.6.4"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net9.0</TargetFramework> | ||
<LangVersion>latest</LangVersion> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<!-- | ||
Displays error on console in addition to the log file. Note that this feature comes with a performance impact. | ||
For more information, visit https://learn.microsoft.com/dotnet/core/testing/unit-testing-platform-integration-dotnet-test#show-failure-per-test | ||
--> | ||
<TestingPlatformShowTestsFailure>true</TestingPlatformShowTestsFailure> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup> | ||
<NoWarn>1701;1702;CA1707;CS1591</NoWarn> | ||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\Riverside.JsonBinder\Riverside.JsonBinder.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |