Skip to content

Commit df39df3

Browse files
authored
fix serialization context (#156)
1 parent 3817bed commit df39df3

29 files changed

+300
-283
lines changed

src/cs/Bootsharp.Common.Test/Bootsharp.Common.Test.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@
1111
</ItemGroup>
1212

1313
<ItemGroup>
14-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
15-
<PackageReference Include="xunit" Version="2.6.6"/>
16-
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
15+
<PackageReference Include="xunit" Version="2.8.1"/>
16+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
1717
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1818
<PrivateAssets>all</PrivateAssets>
1919
</PackageReference>
20-
<PackageReference Include="coverlet.collector" Version="6.0.0">
20+
<PackageReference Include="coverlet.collector" Version="6.0.2">
2121
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2222
<PrivateAssets>all</PrivateAssets>
2323
</PackageReference>
24-
<PackageReference Include="coverlet.msbuild" Version="6.0.0">
24+
<PackageReference Include="coverlet.msbuild" Version="6.0.2">
2525
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2626
<PrivateAssets>all</PrivateAssets>
2727
</PackageReference>

src/cs/Bootsharp.Common.Test/SerializerTest.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public void WhenInfoResolverNotAssignedThrowsError ()
2121
TypeInfoResolver = null
2222
};
2323
Assert.Contains("Serializer info resolver is not assigned",
24-
Assert.Throws<Error>(() => Serialize("")).Message);
24+
Assert.Throws<Error>(() => Serialize("", null)).Message);
2525
}
2626

2727
[Fact]
@@ -31,20 +31,20 @@ public void WhenTypeInfoNotAvailableThrowsError ()
3131
TypeInfoResolver = new MockResolver()
3232
};
3333
Assert.Contains("Failed to resolve serializer info",
34-
Assert.Throws<Error>(() => Serialize("")).Message);
34+
Assert.Throws<Error>(() => Serialize("", null)).Message);
3535
}
3636

3737
[Fact]
3838
public void CanSerialize ()
3939
{
4040
Assert.Equal("""{"items":[{"id":"foo"},{"id":"bar"}]}""",
41-
Serialize(new MockRecord(new MockItem[] { new("foo"), new("bar") })));
41+
Serialize(new MockRecord(new MockItem[] { new("foo"), new("bar") }), typeof(MockRecord)));
4242
}
4343

4444
[Fact]
4545
public void SerializesNullAsNull ()
4646
{
47-
Assert.Equal("null", Serialize(null));
47+
Assert.Equal("null", Serialize(null, null));
4848
}
4949

5050
[Fact]
@@ -77,17 +77,17 @@ public void WhenDeserializationFailsErrorIsThrown ()
7777
[Fact]
7878
public void RespectsOptions ()
7979
{
80-
Assert.Equal("{\"enum\":0}", Serialize(new MockItemWithEnum(MockEnum.Foo)));
81-
Assert.Equal("{\"enum\":null}", Serialize(new MockItemWithEnum(null)));
80+
Assert.Equal("{\"enum\":0}", Serialize(new MockItemWithEnum(MockEnum.Foo), typeof(MockItemWithEnum)));
81+
Assert.Equal("{\"enum\":null}", Serialize(new MockItemWithEnum(null), typeof(MockItemWithEnum)));
8282
Assert.Equal(MockEnum.Foo, Deserialize<MockItemWithEnum>("{\"enum\":0}").Enum);
8383
Assert.Null((Deserialize<MockItemWithEnum>("{\"enum\":null}")).Enum);
8484
Options = new JsonSerializerOptions(JsonSerializerDefaults.Web) {
8585
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
8686
Converters = { new JsonStringEnumConverter() },
8787
TypeInfoResolver = new DefaultJsonTypeInfoResolver()
8888
};
89-
Assert.Equal("{\"enum\":\"Foo\"}", Serialize(new MockItemWithEnum(MockEnum.Foo)));
90-
Assert.Equal("{}", Serialize(new MockItemWithEnum(null)));
89+
Assert.Equal("{\"enum\":\"Foo\"}", Serialize(new MockItemWithEnum(MockEnum.Foo), typeof(MockItemWithEnum)));
90+
Assert.Equal("{}", Serialize(new MockItemWithEnum(null), typeof(MockItemWithEnum)));
9191
Assert.Equal(MockEnum.Foo, (Deserialize<MockItemWithEnum>("{\"enum\":\"Foo\"}")).Enum);
9292
Assert.Null((Deserialize<MockItemWithEnum>("{}")).Enum);
9393
}

src/cs/Bootsharp.Common.Test/TypesTest.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@ public class TypesTest
1111
private readonly CustomAttributeData export = GetMockExportAttribute();
1212
private readonly CustomAttributeData import = GetMockImportAttribute();
1313

14-
[Fact]
15-
public void Records ()
16-
{
17-
// TODO: Remove when coverlet bug is resolved: https://github.com/coverlet-coverage/coverlet/issues/1561
18-
_ = new MockItem("") with { Id = "foo" };
19-
_ = new MockItemWithEnum(default) with { Enum = MockEnum.Bar };
20-
_ = new MockRecord(default) with { Items = new[] { new MockItem("") } };
21-
}
22-
2314
[Fact]
2415
public void TypesAreAssigned ()
2516
{

src/cs/Bootsharp.Common/Interop/Serializer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ public static class Serializer
1717
};
1818

1919
/// <summary>
20-
/// Serializes specified object to JSON string.
20+
/// Serializes specified object to JSON string using specified serialization context type.
2121
/// </summary>
22-
public static string Serialize (object? @object)
22+
public static string Serialize (object? @object, Type type)
2323
{
2424
if (@object is null) return "null";
25-
return JsonSerializer.Serialize(@object, GetInfo(@object.GetType()));
25+
return JsonSerializer.Serialize(@object, GetInfo(type));
2626
}
2727

2828
/// <summary>

src/cs/Bootsharp.Generate.Test/Bootsharp.Generate.Test.csproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@
1616
</ItemGroup>
1717

1818
<ItemGroup>
19-
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.8.0"/>
19+
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.9.2"/>
2020
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing" Version="1.1.2-beta1.23431.1"/>
21-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
22-
<PackageReference Include="xunit" Version="2.6.6"/>
23-
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
21+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
22+
<PackageReference Include="xunit" Version="2.8.1"/>
23+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
2424
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2525
<PrivateAssets>all</PrivateAssets>
2626
</PackageReference>
27-
<PackageReference Include="coverlet.collector" Version="6.0.0">
27+
<PackageReference Include="coverlet.collector" Version="6.0.2">
2828
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2929
<PrivateAssets>all</PrivateAssets>
3030
</PackageReference>
31-
<PackageReference Include="coverlet.msbuild" Version="6.0.0">
31+
<PackageReference Include="coverlet.msbuild" Version="6.0.2">
3232
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3333
<PrivateAssets>all</PrivateAssets>
3434
</PackageReference>

src/cs/Bootsharp.Inject.Test/Bootsharp.Inject.Test.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313

1414
<ItemGroup>
1515
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0"/>
16-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
17-
<PackageReference Include="xunit" Version="2.6.6"/>
18-
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
16+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
17+
<PackageReference Include="xunit" Version="2.8.1"/>
18+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
1919
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2020
<PrivateAssets>all</PrivateAssets>
2121
</PackageReference>
22-
<PackageReference Include="coverlet.collector" Version="6.0.0">
22+
<PackageReference Include="coverlet.collector" Version="6.0.2">
2323
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2424
<PrivateAssets>all</PrivateAssets>
2525
</PackageReference>
26-
<PackageReference Include="coverlet.msbuild" Version="6.0.0">
26+
<PackageReference Include="coverlet.msbuild" Version="6.0.2">
2727
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2828
<PrivateAssets>all</PrivateAssets>
2929
</PackageReference>

src/cs/Bootsharp.Inject/Bootsharp.Inject.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
<ItemGroup>
1515
<PackageReference Include="Bootsharp.Common" Version="$(Version)"/>
16-
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0"/>
16+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1"/>
1717
</ItemGroup>
1818

1919
</Project>

src/cs/Bootsharp.Publish.Test/Bootsharp.Publish.Test.csproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@
1111
</ItemGroup>
1212

1313
<ItemGroup>
14-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0"/>
15-
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.8.3"/>
16-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
17-
<PackageReference Include="MSBuild.ProjectCreation" Version="11.0.1"/>
18-
<PackageReference Include="xunit" Version="2.6.6"/>
19-
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
14+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2"/>
15+
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.10.4"/>
16+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
17+
<PackageReference Include="MSBuild.ProjectCreation" Version="12.0.1"/>
18+
<PackageReference Include="xunit" Version="2.8.1"/>
19+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
2020
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2121
<PrivateAssets>all</PrivateAssets>
2222
</PackageReference>
23-
<PackageReference Include="coverlet.collector" Version="6.0.0">
23+
<PackageReference Include="coverlet.collector" Version="6.0.2">
2424
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2525
<PrivateAssets>all</PrivateAssets>
2626
</PackageReference>
27-
<PackageReference Include="coverlet.msbuild" Version="6.0.0">
27+
<PackageReference Include="coverlet.msbuild" Version="6.0.2">
2828
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2929
<PrivateAssets>all</PrivateAssets>
3030
</PackageReference>

src/cs/Bootsharp.Publish.Test/Emit/DependenciesTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public class Class
7272
Added(All, "Bootsharp.Generated.Imports.JSImportedInstancedA");
7373
Added(All, "Bootsharp.Generated.Imports.JSImportedInstancedB");
7474
// Export interop instances are not generated in C#; they're authored by user.
75-
Assert.DoesNotContain("Bootsharp.Generated.Exports.JSExportedInstanced", TestedContent);
75+
DoesNotContain("Bootsharp.Generated.Exports.JSExportedInstanced");
7676
}
7777

7878
[Fact]

src/cs/Bootsharp.Publish.Test/Emit/InterfacesTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public class JSImported(global::System.Int32 _id) : global::IImported
146146
}
147147
}
148148
""");
149-
Assert.DoesNotContain("JSExported", TestedContent); // Exported instances are authored by user and registered on initial interop.
149+
DoesNotContain("JSExported"); // Exported instances are authored by user and registered on initial interop.
150150
}
151151

152152
[Fact]
@@ -297,6 +297,6 @@ public class Class
297297
}
298298
"""));
299299
Execute();
300-
Assert.DoesNotContain("Foo", TestedContent, StringComparison.OrdinalIgnoreCase);
300+
DoesNotContain("Foo");
301301
}
302302
}

src/cs/Bootsharp.Publish.Test/Emit/InteropTest.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ internal static void RegisterProxies ()
2626
public void GeneratesDisposeInstanceBindings ()
2727
{
2828
Execute();
29-
Contains("JSExport] internal static void DisposeExportedInstance (global::System.Int32 id) => global::Bootsharp.Instances.Dispose(id);");
30-
Contains("""JSImport("disposeInstance", "Bootsharp")] internal static partial void DisposeImportedInstance (global::System.Int32 id);""");
29+
Contains("JSExport] internal static void DisposeExportedInstance (int id) => global::Bootsharp.Instances.Dispose(id);");
30+
Contains("""JSImport("disposeInstance", "Bootsharp")] internal static partial void DisposeImportedInstance (int id);""");
3131
}
3232

3333
[Fact]
@@ -158,7 +158,7 @@ public class Class
158158
}
159159
"""));
160160
Execute();
161-
Assert.DoesNotContain("Foo", TestedContent, StringComparison.OrdinalIgnoreCase);
161+
DoesNotContain("Foo");
162162
}
163163

164164
[Fact]
@@ -206,17 +206,17 @@ public class Class
206206
}
207207
"""));
208208
Execute();
209-
Contains("""Proxies.Set("Space.Class.FunA", (global::Space.Record a) => Deserialize<global::Space.Record>(Space_Class_FunA(Serialize(a))));""");
210-
Contains("""Proxies.Set("Space.Class.FunB", async (global::Space.Record?[]? a) => Deserialize<global::Space.Record?[]?>(await Space_Class_FunB(Serialize(a))));""");
211-
Contains("JSExport] internal static global::System.String Space_Class_InvA (global::System.String a) => Serialize(global::Space.Class.InvA(Deserialize<global::Space.Record>(a)));");
212-
Contains("JSExport] internal static async global::System.Threading.Tasks.Task<global::System.String?> Space_Class_InvB (global::System.String? a) => Serialize(await global::Space.Class.InvB(Deserialize<global::Space.Record?[]?>(a)));");
209+
Contains("""Proxies.Set("Space.Class.FunA", (global::Space.Record a) => Deserialize<global::Space.Record>(Space_Class_FunA(Serialize(a, typeof(global::Space.Record)))));""");
210+
Contains("""Proxies.Set("Space.Class.FunB", async (global::Space.Record?[]? a) => Deserialize<global::Space.Record?[]?>(await Space_Class_FunB(Serialize(a, typeof(global::Space.Record[])))));""");
211+
Contains("JSExport] internal static global::System.String Space_Class_InvA (global::System.String a) => Serialize(global::Space.Class.InvA(Deserialize<global::Space.Record>(a)), typeof(global::Space.Record));");
212+
Contains("JSExport] internal static async global::System.Threading.Tasks.Task<global::System.String?> Space_Class_InvB (global::System.String? a) => Serialize(await global::Space.Class.InvB(Deserialize<global::Space.Record?[]?>(a)), typeof(global::Space.Record[]));");
213213
Contains("""JSImport("Space.Class.funASerialized", "Bootsharp")] internal static partial global::System.String Space_Class_FunA (global::System.String a);""");
214214
Contains("""JSImport("Space.Class.funBSerialized", "Bootsharp")] internal static partial global::System.Threading.Tasks.Task<global::System.String?> Space_Class_FunB (global::System.String? a);""");
215215

216216
// TODO: Remove when resolved: https://github.com/elringus/bootsharp/issues/138
217-
Contains("""Proxies.Set("Space.Class.FunAsyncBytes", async () => Deserialize<global::System.Byte[]>(await Space_Class_FunAsyncBytes()));""");
218-
Contains("JSExport] internal static async global::System.Threading.Tasks.Task<global::System.String> Space_Class_InvAsyncBytes () => Serialize(await global::Space.Class.InvAsyncBytes());");
219-
Contains("""JSImport("Space.Class.funAsyncBytesSerialized", "Bootsharp")] internal static partial global::System.Threading.Tasks.Task<global::System.String> Space_Class_FunAsyncBytes ();""");
217+
Contains("""Proxies.Set("Space.Class.FunAsyncBytes", async () => await Space_Class_FunAsyncBytes());""");
218+
Contains("JSExport] [return: JSMarshalAs<JSType.Promise<JSType.Any>>] internal static async global::System.Threading.Tasks.Task<object> Space_Class_InvAsyncBytes () => await global::Space.Class.InvAsyncBytes();");
219+
Contains("""JSImport("Space.Class.funAsyncBytesSerialized", "Bootsharp")] [return: JSMarshalAs<JSType.Promise<JSType.Any>>] internal static partial global::System.Threading.Tasks.Task<object> Space_Class_FunAsyncBytes ();""");
220220
}
221221

222222
[Fact]

src/cs/Bootsharp.Publish.Test/Emit/SerializerTest.cs

Lines changed: 2 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void WhenNoSerializableTypesIsEmpty ()
1919
WithClass("[JSInvokable] public static byte[] Bar (int[] a, double[] b, string[] c) => default;")
2020
);
2121
Execute();
22-
Assert.DoesNotContain("JsonSerializable", TestedContent);
22+
DoesNotContain("JsonSerializable");
2323
}
2424

2525
[Fact]
@@ -43,7 +43,7 @@ public class Class
4343
}
4444
"""));
4545
Execute();
46-
Assert.DoesNotContain("JsonSerializable", TestedContent);
46+
DoesNotContain("JsonSerializable");
4747
}
4848

4949
[Fact] // .NET's generator indexes types by short names (w/o namespace) and fails on duplicates.
@@ -65,64 +65,4 @@ public void AddsOnlyTopLevelTypesAndCrawledDuplicates ()
6565
Contains("[JsonSerializable(typeof(global::n.Baz)");
6666
Contains("[JsonSerializable(typeof(global::y.Struct)");
6767
}
68-
69-
[Fact]
70-
public void AddsProxiesForListInterface ()
71-
{
72-
AddAssembly(WithClass("[JSInvokable] public static void Foo (IList<string> a) {}"));
73-
Execute();
74-
Contains("[JsonSerializable(typeof(global::System.Collections.Generic.IList<global::System.String>)");
75-
Contains("[JsonSerializable(typeof(global::System.Collections.Generic.List<global::System.String>)");
76-
Contains("[JsonSerializable(typeof(global::System.String[])");
77-
}
78-
79-
[Fact]
80-
public void AddsProxiesForReadOnlyListInterface ()
81-
{
82-
AddAssembly(WithClass("[JSInvokable] public static void Foo (IReadOnlyList<string> a) {}"));
83-
Execute();
84-
Contains("[JsonSerializable(typeof(global::System.Collections.Generic.IReadOnlyList<global::System.String>)");
85-
Contains("[JsonSerializable(typeof(global::System.Collections.Generic.List<global::System.String>)");
86-
Contains("[JsonSerializable(typeof(global::System.String[])");
87-
}
88-
89-
[Fact]
90-
public void AddsProxiesForDictInterface ()
91-
{
92-
AddAssembly(WithClass("[JSInvokable] public static void Foo (IDictionary<string, int> a) {}"));
93-
Execute();
94-
Contains("[JsonSerializable(typeof(global::System.Collections.Generic.IDictionary<global::System.String, global::System.Int32>)");
95-
Contains("[JsonSerializable(typeof(global::System.Collections.Generic.Dictionary<global::System.String, global::System.Int32>)");
96-
}
97-
98-
[Fact]
99-
public void AddsProxiesForReadOnlyDictInterface ()
100-
{
101-
AddAssembly(WithClass("[JSInvokable] public static void Foo (IReadOnlyDictionary<string, int[]> a) {}"));
102-
Execute();
103-
Contains("[JsonSerializable(typeof(global::System.Collections.Generic.IReadOnlyDictionary<global::System.String, global::System.Int32[]>)");
104-
Contains("[JsonSerializable(typeof(global::System.Collections.Generic.Dictionary<global::System.String, global::System.Int32[]>)");
105-
}
106-
107-
[Fact]
108-
public void DoesntAddProxiesForTaskWithoutResult ()
109-
{
110-
AddAssembly(WithClass("[JSInvokable] public static Task Foo (Task bar) => default;"));
111-
Execute();
112-
Assert.DoesNotContain("JsonSerializable", TestedContent);
113-
}
114-
115-
[Fact]
116-
public void AddsProxiesForTaskWithResult ()
117-
{
118-
AddAssembly(
119-
With("public record Info;"),
120-
WithClass("[JSInvokable] public static Task<Info> Foo () => default;"),
121-
WithClass("[JSInvokable] public static Task<IReadOnlyList<bool>> Bar () => default;"));
122-
Execute();
123-
Contains("[JsonSerializable(typeof((global::Info, byte))");
124-
Contains("[JsonSerializable(typeof((global::System.Collections.Generic.IReadOnlyList<global::System.Boolean>, byte))");
125-
Contains("[JsonSerializable(typeof(global::System.Collections.Generic.List<global::System.Boolean>)");
126-
Contains("[JsonSerializable(typeof(global::System.Boolean[])");
127-
}
12868
}

0 commit comments

Comments
 (0)