From dbbfa96d8c3b31c6e16b043181e9481954a6dd71 Mon Sep 17 00:00:00 2001 From: Mayuki Sawatari Date: Tue, 12 Dec 2023 18:25:57 +0900 Subject: [PATCH] Restore MethodCollector tests --- .../CodeAnalysis/MethodCollector.cs | 2 +- .../Collector/MethodCollectorHelper.cs | 24 + .../Collector/MethodCollectorServicesTest.cs | 436 ++++++------------ .../MethodCollectorStreamingHubsTest.cs | 318 ++++--------- 4 files changed, 259 insertions(+), 521 deletions(-) create mode 100644 tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorHelper.cs diff --git a/src/MagicOnion.Client.SourceGenerator/CodeAnalysis/MethodCollector.cs b/src/MagicOnion.Client.SourceGenerator/CodeAnalysis/MethodCollector.cs index 0ca6ab8f8..249241c01 100644 --- a/src/MagicOnion.Client.SourceGenerator/CodeAnalysis/MethodCollector.cs +++ b/src/MagicOnion.Client.SourceGenerator/CodeAnalysis/MethodCollector.cs @@ -8,7 +8,7 @@ namespace MagicOnion.Client.SourceGenerator.CodeAnalysis; /// /// Provides logic to collect MagicOnion Services and StreamingHubs from a compilation. /// -public class MethodCollector +public static class MethodCollector { public static (MagicOnionServiceCollection ServiceCollection, IReadOnlyList Diagnostics) Collect(ImmutableArray interfaceSymbols, ReferenceSymbols referenceSymbols, CancellationToken cancellationToken) { diff --git a/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorHelper.cs b/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorHelper.cs new file mode 100644 index 000000000..3a9f0189e --- /dev/null +++ b/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorHelper.cs @@ -0,0 +1,24 @@ +using Microsoft.CodeAnalysis; + +namespace MagicOnion.Client.SourceGenerator.Tests.Collector; + +public static class MethodCollectorTestHelper +{ + public static IEnumerable Traverse(INamespaceOrTypeSymbol rootNamespaceOrTypeSymbol) + { + foreach (var namespaceOrTypeSymbol in rootNamespaceOrTypeSymbol.GetMembers()) + { + if (namespaceOrTypeSymbol is INamedTypeSymbol { TypeKind: TypeKind.Interface } typeSymbol) + { + yield return typeSymbol; + } + else if (namespaceOrTypeSymbol is INamespaceSymbol namespaceSymbol) + { + foreach (var t in Traverse(namespaceSymbol)) + { + yield return t; + } + } + } + } +} diff --git a/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorServicesTest.cs b/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorServicesTest.cs index a5da56ac5..69f67687a 100644 --- a/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorServicesTest.cs +++ b/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorServicesTest.cs @@ -1,108 +1,13 @@ -#if FALSE -using MagicOnion.Generator.CodeAnalysis; +using MagicOnion.Client.SourceGenerator.CodeAnalysis; +using MessagePack; using Microsoft.CodeAnalysis; +using System.Collections.Immutable; using Xunit.Abstractions; namespace MagicOnion.Client.SourceGenerator.Tests.Collector; public class MethodCollectorServicesTest { - readonly ITestOutputHelper testOutputHelper; - - public MethodCollectorServicesTest(ITestOutputHelper testOutputHelper) - { - this.testOutputHelper = testOutputHelper; - } - - [Fact] - public void FileScopedNamespace() - { - // Arrange - var source = @" -using System; -using System.Threading.Tasks; -using MagicOnion; -using MessagePack; - -namespace MyNamespace; - -public interface IMyService : IService -{ - UnaryResult NilAsync(); -} -"; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; - - // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); - - // Assert - compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); - serviceCollection.Should().NotBeNull(); - serviceCollection.Hubs.Should().BeEmpty(); - serviceCollection.Services.Should().HaveCount(1); - serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); - serviceCollection.Services[0].Methods.Should().HaveCount(1); - // UnaryResult NilAsync(); - serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); - serviceCollection.Services[0].Methods[0].MethodName.Should().Be("NilAsync"); - serviceCollection.Services[0].Methods[0].RequestType.Should().Be(MagicOnionTypeInfo.CreateFromType()); - serviceCollection.Services[0].Methods[0].ResponseType.Should().Be(MagicOnionTypeInfo.CreateFromType()); - serviceCollection.Services[0].Methods[0].Parameters.Should().BeEmpty(); - serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>()); - } - - [Fact] - public void IfDirectives() - { - // Arrange - var source = @" -using System; -using System.Threading.Tasks; -using MagicOnion; -using MessagePack; - -namespace MyNamespace; - -[GenerateIfDirective(""DEBUG || CONST_1 || CONST_2"")] -public interface IMyService : IService -{ - [GenerateDefineDebug] - UnaryResult MethodA(); - - [GenerateIfDirective(""CONST_3"")] - UnaryResult MethodB(); - - UnaryResult MethodC(); -} -"; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; - - // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); - - // Assert - compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); - serviceCollection.Should().NotBeNull(); - serviceCollection.Hubs.Should().BeEmpty(); - serviceCollection.Services.Should().HaveCount(1); - serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeTrue(); - serviceCollection.Services[0].IfDirectiveCondition.Should().Be("DEBUG || CONST_1 || CONST_2"); - serviceCollection.Services[0].Methods[0].HasIfDirectiveCondition.Should().BeTrue(); - serviceCollection.Services[0].Methods[0].IfDirectiveCondition.Should().Be("DEBUG"); - serviceCollection.Services[0].Methods[1].HasIfDirectiveCondition.Should().BeTrue(); - serviceCollection.Services[0].Methods[1].IfDirectiveCondition.Should().Be("CONST_3"); - serviceCollection.Services[0].Methods[2].HasIfDirectiveCondition.Should().BeFalse(); - } - [Fact] public void Ignore_Method() { @@ -125,13 +30,12 @@ public interface IMyService : IService UnaryResult MethodC(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -166,13 +70,12 @@ public interface IMyService : IService UnaryResult MethodC(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -180,7 +83,7 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().BeEmpty(); } - + [Fact] public void Unary_NonGenericResult() { @@ -199,13 +102,12 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -232,13 +134,12 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -265,13 +166,12 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -298,13 +198,12 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -312,7 +211,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(1); // UnaryResult MethodA(); serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); @@ -323,7 +221,7 @@ public interface IMyService : IService serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>()); } - + [Fact] public void Unary_Parameter_Zero_ReturnValue() { @@ -342,13 +240,12 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -356,7 +253,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(1); // UnaryResult MethodA(); serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); @@ -365,8 +261,8 @@ public interface IMyService : IService serviceCollection.Services[0].Methods[0].ResponseType.Should().Be(MagicOnionTypeInfo.CreateFromType()); serviceCollection.Services[0].Methods[0].Parameters.Should().BeEmpty(); serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>()); - } - + } + [Fact] public void Unary_Parameter_One_ReturnNil() { @@ -385,13 +281,12 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -399,7 +294,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(1); // UnaryResult MethodA(string arg1); serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); @@ -410,7 +304,7 @@ public interface IMyService : IService serviceCollection.Services[0].Methods[0].Parameters[0].Name.Should().Be("arg1"); serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>()); } - + [Fact] public void Unary_Parameter_Many_ReturnNil() { @@ -429,13 +323,12 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -443,7 +336,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(1); // UnaryResult MethodA(string arg1, int arg2); serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); @@ -451,11 +343,11 @@ public interface IMyService : IService serviceCollection.Services[0].Methods[0].RequestType.Should().Be(MagicOnionTypeInfo.CreateFromType>()); serviceCollection.Services[0].Methods[0].ResponseType.Should().Be(MagicOnionTypeInfo.CreateFromType()); serviceCollection.Services[0].Methods[0].Parameters[0].Type.Should().Be(MagicOnionTypeInfo.CreateFromType()); - serviceCollection.Services[0].Methods[0].Parameters[1].Type.Should().Be( MagicOnionTypeInfo.CreateFromType()); + serviceCollection.Services[0].Methods[0].Parameters[1].Type.Should().Be(MagicOnionTypeInfo.CreateFromType()); serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>()); } - + [Fact] public void Unary_HasDefaultValue() { @@ -474,30 +366,29 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); serviceCollection.Services[0].Methods[0].Parameters[0].Type.Should().Be(MagicOnionTypeInfo.CreateFromType()); serviceCollection.Services[0].Methods[0].Parameters[0].HasExplicitDefaultValue.Should().BeTrue(); serviceCollection.Services[0].Methods[0].Parameters[0].DefaultValue.Should().Be("\"Hello\""); - serviceCollection.Services[0].Methods[0].Parameters[1].Type.Should().Be( MagicOnionTypeInfo.CreateFromType()); + serviceCollection.Services[0].Methods[0].Parameters[1].Type.Should().Be(MagicOnionTypeInfo.CreateFromType()); serviceCollection.Services[0].Methods[0].Parameters[1].DefaultValue.Should().Be("1234"); serviceCollection.Services[0].Methods[0].Parameters[1].HasExplicitDefaultValue.Should().BeTrue(); - serviceCollection.Services[0].Methods[0].Parameters[2].Type.Should().Be( MagicOnionTypeInfo.CreateFromType()); + serviceCollection.Services[0].Methods[0].Parameters[2].Type.Should().Be(MagicOnionTypeInfo.CreateFromType()); serviceCollection.Services[0].Methods[0].Parameters[2].DefaultValue.Should().Be("0"); serviceCollection.Services[0].Methods[0].Parameters[2].HasExplicitDefaultValue.Should().BeTrue(); - serviceCollection.Services[0].Methods[0].Parameters[3].Type.Should().Be( MagicOnionTypeInfo.CreateFromType()); + serviceCollection.Services[0].Methods[0].Parameters[3].Type.Should().Be(MagicOnionTypeInfo.CreateFromType()); serviceCollection.Services[0].Methods[0].Parameters[3].DefaultValue.Should().Be("null"); serviceCollection.Services[0].Methods[0].Parameters[3].HasExplicitDefaultValue.Should().BeTrue(); } - + [Fact] public void Unary_Methods() { @@ -519,13 +410,12 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -533,7 +423,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(4); } @@ -555,15 +444,18 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); - // Act & Assert - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - Assert.Throws(() => collector.Collect(compilation)); + // Act + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); + + // Assert + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.UnaryUnsupportedMethodReturnType.Id); } - + [Fact] public void Unary_InvalidReturnType_ClientStreamingResult() { @@ -582,15 +474,18 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); + + // Act + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); - // Act & Assert - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - Assert.Throws(() => collector.Collect(compilation)); + // Assert + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.UnaryUnsupportedMethodReturnType.Id); } - + [Fact] public void Unary_InvalidReturnType_DuplexStreamingResult() { @@ -609,15 +504,18 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); - // Act & Assert - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - Assert.Throws(() => collector.Collect(compilation)); + // Act + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); + + // Assert + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.UnaryUnsupportedMethodReturnType.Id); } - + [Fact] public void UnsupportedType() { @@ -636,13 +534,16 @@ public interface IMyService : IService } } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); - // Act & Assert - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - Assert.Throws(() => collector.Collect(compilation)); + // Act + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); + + // Assert + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.ServiceUnsupportedMethodReturnType.Id); } [Fact] @@ -662,13 +563,12 @@ public interface IMyService : IService Task> ServerStreaming(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -676,7 +576,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(1); // Task> ServerStreamingNoArg(); serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); @@ -686,7 +585,7 @@ public interface IMyService : IService serviceCollection.Services[0].Methods[0].Parameters.Should().BeEmpty(); serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>>()); } - + [Fact] public void ServerStreaming_Parameter_One() { @@ -704,13 +603,12 @@ public interface IMyService : IService Task> ServerStreaming(string arg1); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -718,7 +616,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(1); // Task> ServerStreamingNoArg(); serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); @@ -729,7 +626,7 @@ public interface IMyService : IService serviceCollection.Services[0].Methods[0].Parameters[0].Name.Should().Be("arg1"); serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>>()); } - + [Fact] public void ServerStreaming_Parameter_Many() { @@ -747,13 +644,12 @@ public interface IMyService : IService Task> ServerStreaming(string arg1, int arg2); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -761,7 +657,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(1); // Task> ServerStreamingNoArg(); serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); @@ -774,7 +669,7 @@ public interface IMyService : IService serviceCollection.Services[0].Methods[0].Parameters[1].Name.Should().Be("arg2"); serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>>()); } - + [Fact] public void ServerStreaming_ShouldNotBeTask() { @@ -792,16 +687,19 @@ public interface IMyService : IService ServerStreamingResult ServerStreaming(string arg1, int arg2); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); + + // Act + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); - // Act & Assert - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - Assert.Throws(() => collector.Collect(compilation)); + // Assert + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.ServiceUnsupportedMethodReturnType.Id); } - + [Fact] public void DuplexStreaming() { @@ -819,13 +717,12 @@ public interface IMyService : IService Task> MethodA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -833,7 +730,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(1); // Task> MethodA(); serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); @@ -843,7 +739,7 @@ public interface IMyService : IService serviceCollection.Services[0].Methods[0].Parameters.Should().BeEmpty(); serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>>()); } - + [Fact] public void DuplexStreaming_ParameterNotSupported() { @@ -861,13 +757,16 @@ public interface IMyService : IService Task> MethodA(string arg1); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); - // Act & Assert - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - Assert.Throws(() => collector.Collect(compilation)); + // Act + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); + + // Assert + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.StreamingMethodMustHaveNoParameters.Id); } [Fact] @@ -887,13 +786,12 @@ public interface IMyService : IService Task> MethodA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); @@ -901,7 +799,6 @@ public interface IMyService : IService serviceCollection.Hubs.Should().BeEmpty(); serviceCollection.Services.Should().HaveCount(1); serviceCollection.Services[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyService")); - serviceCollection.Services[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Services[0].Methods.Should().HaveCount(1); // Task> MethodA(); serviceCollection.Services[0].Methods[0].ServiceName.Should().Be("IMyService"); @@ -911,7 +808,7 @@ public interface IMyService : IService serviceCollection.Services[0].Methods[0].Parameters.Should().BeEmpty(); serviceCollection.Services[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType>>()); } - + [Fact] public void ClientStreaming_ParameterNotSupported() { @@ -929,54 +826,15 @@ public interface IMyService : IService Task> MethodA(string arg1); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; - - // Act & Assert - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - Assert.Throws(() => collector.Collect(compilation)); - } - - [Fact] - public void GlobalUsings() - { - // Arrange - var source = @" -using MagicOnion; -using MessagePack; - -namespace MyNamespace; - -public interface IMyService : IService -{ - UnaryResult NilAsync(); - UnaryResult StringAsync(); - UnaryResult OneParameter(string arg1); - UnaryResult TwoParameter(string arg1, int arg2); - Task> ServerStreaming(string arg1, int arg2); -} -"; - using var tempWorkspace = TemporaryProjectWorkarea.Create(new TemporaryProjectWorkareaOptions() - { - TargetFramework = "netstandard2.0", - }); - tempWorkspace.AddFileToProject("Usings.cs", """ - global using System; - global using System.Threading.Tasks; - global using System.Collections.Generic; - """); - tempWorkspace.AddFileToProject("IMyService.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(new MagicOnionGeneratorTestOutputLogger(testOutputHelper)); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert - compilation.GetDiagnostics().Should().NotContain(x => x.Severity == DiagnosticSeverity.Error); - serviceCollection.Should().NotBeNull(); - serviceCollection.Services.Should().NotBeEmpty(); + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.StreamingMethodMustHaveNoParameters.Id); } } -#endif diff --git a/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorStreamingHubsTest.cs b/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorStreamingHubsTest.cs index f83b9aec8..588c5a5da 100644 --- a/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorStreamingHubsTest.cs +++ b/tests/MagicOnion.Client.SourceGenerator.Tests/Collector/MethodCollectorStreamingHubsTest.cs @@ -1,55 +1,11 @@ -#if FALSE -using MagicOnion.Generator.CodeAnalysis; +using System.Collections.Immutable; +using MagicOnion.Client.SourceGenerator.CodeAnalysis; +using MessagePack; namespace MagicOnion.Client.SourceGenerator.Tests.Collector; public class MethodCollectorStreamingHubsTest { - [Fact] - public void FileScopedNamespace() - { - // Arrange - var source = @" -using System; -using System.Threading.Tasks; -using MagicOnion; -using MessagePack; - -namespace MyNamespace; - -public interface IMyHub : IStreamingHub -{ - Task MethodA(); -} - -public interface IMyHubReceiver -{ - void EventA(); -} -"; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; - - // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); - - // Assert - serviceCollection.Should().NotBeNull(); - serviceCollection.Hubs.Should().HaveCount(1); - serviceCollection.Services.Should().BeEmpty(); - serviceCollection.Hubs[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyHub")); - serviceCollection.Hubs[0].HasIfDirectiveCondition.Should().BeFalse(); - serviceCollection.Hubs[0].Methods.Should().HaveCount(1); - // Task MethodA(); - serviceCollection.Hubs[0].Methods[0].MethodName.Should().Be("MethodA"); - serviceCollection.Hubs[0].Methods[0].RequestType.Should().Be(MagicOnionTypeInfo.CreateFromType()); - serviceCollection.Hubs[0].Methods[0].ResponseType.Should().Be(MagicOnionTypeInfo.CreateFromType()); - serviceCollection.Hubs[0].Methods[0].Parameters.Should().BeEmpty(); - serviceCollection.Hubs[0].Methods[0].MethodReturnType.Should().Be(MagicOnionTypeInfo.CreateFromType()); - } - [Fact] public void Ignore_Method() { @@ -77,25 +33,23 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert serviceCollection.Should().NotBeNull(); serviceCollection.Hubs.Should().HaveCount(1); serviceCollection.Services.Should().BeEmpty(); serviceCollection.Hubs[0].ServiceType.Should().Be(MagicOnionTypeInfo.Create("MyNamespace", "IMyHub")); - serviceCollection.Hubs[0].HasIfDirectiveCondition.Should().BeFalse(); serviceCollection.Hubs[0].Methods.Should().HaveCount(2); serviceCollection.Hubs[0].Methods[0].MethodName.Should().Be("MethodA"); serviceCollection.Hubs[0].Methods[1].MethodName.Should().Be("MethodC"); } - + [Fact] public void Ignore_Interface() { @@ -119,13 +73,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert serviceCollection.Should().NotBeNull(); @@ -156,13 +109,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert // Task MethodA(); @@ -170,7 +122,7 @@ public interface IMyHubReceiver serviceCollection.Hubs[0].Methods[0].RequestType.Should().Be(MagicOnionTypeInfo.CreateFromType()); serviceCollection.Hubs[0].Methods[0].Parameters.Should().BeEmpty(); } - + [Fact] public void Parameter_One() { @@ -193,13 +145,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert // Task MethodA(); @@ -211,7 +162,7 @@ public interface IMyHubReceiver serviceCollection.Hubs[0].Methods[0].Parameters[0].HasExplicitDefaultValue.Should().BeFalse(); serviceCollection.Hubs[0].Methods[0].Parameters[0].DefaultValue.Should().Be("default(int)"); } - + [Fact] public void Parameter_Many() { @@ -234,13 +185,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert // Task MethodA(); @@ -257,7 +207,7 @@ public interface IMyHubReceiver serviceCollection.Hubs[0].Methods[0].Parameters[1].DefaultValue.Should().Be("default(string)"); } - + [Fact] public void Parameter_HasDefaultValue() { @@ -280,13 +230,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert // Task MethodA(); @@ -325,13 +274,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert serviceCollection.Should().NotBeNull(); @@ -344,7 +292,7 @@ public interface IMyHubReceiver serviceCollection.Hubs[0].Receiver.Methods[0].MethodName.Should().Be("EventA"); serviceCollection.Hubs[0].Receiver.Methods[0].HubId.Should().Be(842297178); } - + [Fact] public void HubId_Explicit() { @@ -371,13 +319,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert serviceCollection.Should().NotBeNull(); @@ -390,7 +337,7 @@ public interface IMyHubReceiver serviceCollection.Hubs[0].Receiver.Methods[0].MethodName.Should().Be("EventA"); serviceCollection.Hubs[0].Receiver.Methods[0].HubId.Should().Be(67890); } - + [Fact] public void ReturnType_NotSupported_Void() { @@ -413,15 +360,18 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); + + // Act + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); - // Act & Assert - var collector = new MethodCollector(); - var ex = Assert.Throws(() => collector.Collect(compilation)); + // Assert + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.StreamingHubUnsupportedMethodReturnType.Id); } - + [Fact] public void ReturnType_NotSupported_NotTaskOfT() { @@ -444,13 +394,16 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); - // Act & Assert - var collector = new MethodCollector(); - var ex = Assert.Throws(() => collector.Collect(compilation)); + // Act + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); + + // Assert + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.StreamingHubUnsupportedMethodReturnType.Id); } [Fact] @@ -475,13 +428,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert serviceCollection.Hubs[0].Methods[0].MethodName.Should().Be("MethodA"); @@ -511,13 +463,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert serviceCollection.Hubs[0].Methods[0].MethodName.Should().Be("MethodA"); @@ -547,13 +498,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert serviceCollection.Hubs[0].Methods[0].MethodName.Should().Be("MethodA"); @@ -583,13 +533,12 @@ public interface IMyHubReceiver void EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert serviceCollection.Hubs[0].Methods[0].MethodName.Should().Be("MethodA"); @@ -621,13 +570,12 @@ public interface IMyHubReceiver void EventC(string arg1, int arg2); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert serviceCollection.Should().NotBeNull(); @@ -654,7 +602,7 @@ public interface IMyHubReceiver serviceCollection.Hubs[0].Receiver.Methods[2].ResponseType.Should().Be(MagicOnionTypeInfo.KnownTypes.MessagePack_Nil); serviceCollection.Hubs[0].Receiver.Methods[2].MethodReturnType.Should().Be(MagicOnionTypeInfo.KnownTypes.System_Void); } - + [Fact] public void Receiver_NonVoidReturnType() { @@ -677,107 +625,15 @@ public interface IMyHubReceiver int EventA(); } "; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; - - // Act & Assert - var collector = new MethodCollector(); - var ex = Assert.Throws(() => collector.Collect(compilation)); - } - - [Fact] - public void IfDirectives() - { - // Arrange - var source = @" -using System; -using System.Threading.Tasks; -using MagicOnion; -using MessagePack; - -namespace MyNamespace; - -[GenerateIfDirective(""DEBUG || CONST_1 || CONST_2"")] -public interface IMyHub : IStreamingHub -{ - [GenerateDefineDebug] - Task MethodA(); - [GenerateIfDirective(""CONST_3"")] - Task MethodB(); - Task MethodC(); -} - -public interface IMyHubReceiver -{ - void EventA(); - void EventB(Nil nil); - void EventC(string arg1, int arg2); -} -"; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; + var (compilation, semModel) = CompilationHelper.Create(source); + if (!ReferenceSymbols.TryCreate(compilation, out var referenceSymbols)) throw new InvalidOperationException("Cannot create the reference symbols."); + var interfaceSymbols = MethodCollectorTestHelper.Traverse(compilation.Assembly.GlobalNamespace).ToImmutableArray(); // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); + var (serviceCollection, diagnostics) = MethodCollector.Collect(interfaceSymbols, referenceSymbols, CancellationToken.None); // Assert - serviceCollection.Hubs[0].HasIfDirectiveCondition.Should().BeTrue(); - serviceCollection.Hubs[0].IfDirectiveCondition.Should().Be("DEBUG || CONST_1 || CONST_2"); - serviceCollection.Hubs[0].Methods[0].HasIfDirectiveCondition.Should().BeTrue(); - serviceCollection.Hubs[0].Methods[0].IfDirectiveCondition.Should().Be("DEBUG"); - serviceCollection.Hubs[0].Methods[1].HasIfDirectiveCondition.Should().BeTrue(); - serviceCollection.Hubs[0].Methods[1].IfDirectiveCondition.Should().Be("CONST_3"); - serviceCollection.Hubs[0].Methods[2].HasIfDirectiveCondition.Should().BeFalse(); + diagnostics.Should().HaveCount(1); + diagnostics[0].Id.Should().Be(MagicOnionDiagnosticDescriptors.StreamingHubUnsupportedReceiverMethodReturnType.Id); } - - [Fact] - public void IfDirectives_Receiver() - { - // Arrange - var source = @" -using System; -using System.Threading.Tasks; -using MagicOnion; -using MessagePack; - -namespace MyNamespace; - -public interface IMyHub : IStreamingHub -{ - Task MethodA(); - Task MethodB(); - Task MethodC(); } - -[GenerateIfDirective(""DEBUG || CONST_1 || CONST_2"")] -public interface IMyHubReceiver -{ - [GenerateDefineDebug] - void EventA(); - [GenerateIfDirective(""CONST_3"")] - void EventB(Nil nil); - void EventC(string arg1, int arg2); -} -"; - using var tempWorkspace = TemporaryProjectWorkarea.Create(); - tempWorkspace.AddFileToProject("IMyHub.cs", source); - var compilation = tempWorkspace.GetOutputCompilation().Compilation; - - // Act - var collector = new MethodCollector(); - var serviceCollection = collector.Collect(compilation); - - // Assert - serviceCollection.Hubs[0].Receiver.HasIfDirectiveCondition.Should().BeTrue(); - serviceCollection.Hubs[0].Receiver.IfDirectiveCondition.Should().Be("DEBUG || CONST_1 || CONST_2"); - serviceCollection.Hubs[0].Receiver.Methods[0].HasIfDirectiveCondition.Should().BeTrue(); - serviceCollection.Hubs[0].Receiver.Methods[0].IfDirectiveCondition.Should().Be("DEBUG"); - serviceCollection.Hubs[0].Receiver.Methods[1].HasIfDirectiveCondition.Should().BeTrue(); - serviceCollection.Hubs[0].Receiver.Methods[1].IfDirectiveCondition.Should().Be("CONST_3"); - serviceCollection.Hubs[0].Receiver.Methods[2].HasIfDirectiveCondition.Should().BeFalse(); - } -} -#endif