diff --git a/InterfaceGenerator.Tests/AccessorsGenerationTests.cs b/InterfaceGenerator.Tests/AccessorsGenerationTests.cs index 75b0c25..7e61ee2 100644 --- a/InterfaceGenerator.Tests/AccessorsGenerationTests.cs +++ b/InterfaceGenerator.Tests/AccessorsGenerationTests.cs @@ -3,163 +3,163 @@ using FluentAssertions; using FluentAssertions.Common; using Xunit; -namespace InterfaceGenerator.Tests +namespace InterfaceGenerator.Tests; + +public class AccessorsGenerationTests { - public class AccessorsGenerationTests + private readonly IAccessorsTestsService _sut; + + public AccessorsGenerationTests() { - private readonly IAccessorsTestsService _sut; + _sut = new AccessorsTestsService(); + } - public AccessorsGenerationTests() + [Fact] + public void GetSetIndexer_IsImplemented() + { + var indexer = typeof(IAccessorsTestsService).GetIndexerByParameterTypes(new[] { typeof(string) }); + + indexer.Should().NotBeNull(); + + indexer.GetMethod.Should().NotBeNull(); + indexer.SetMethod.Should().NotBeNull(); + + var _ = _sut[string.Empty]; + _sut[string.Empty] = 0; + } + + [Fact] + public void PublicProperty_IsImplemented() + { + var prop = typeof(IAccessorsTestsService) + .GetProperty(nameof(IAccessorsTestsService.PublicProperty))!; + + prop.Should().NotBeNull(); + + prop.GetMethod.Should().NotBeNull(); + prop.SetMethod.Should().NotBeNull(); + + var _ = _sut.PublicProperty; + _sut.PublicProperty = string.Empty; + } + + [Fact] + public void InitProperty_IsImplemented() + { + var prop = typeof(IAccessorsTestsService) + .GetProperty(nameof(IAccessorsTestsService.InitOnlyProperty))!; + + prop.Should().NotBeNull(); + + prop.GetMethod.Should().NotBeNull(); + prop.SetMethod.Should().NotBeNull(); + + prop.SetMethod!.ReturnParameter!.GetRequiredCustomModifiers().Should().Contain(typeof(IsExternalInit)); + + var _ = _sut.InitOnlyProperty; + } + + [Fact] + public void PrivateSetter_IsOmitted() + { + var prop = typeof(IAccessorsTestsService) + .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateSetter))!; + + prop.Should().NotBeNull(); + + prop.GetMethod.Should().NotBeNull(); + prop.SetMethod.Should().BeNull(); + + var _ = _sut.PropertyWithPrivateSetter; + } + + [Fact] + public void PrivateGetter_IsOmitted() + { + var prop = typeof(IAccessorsTestsService) + .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateGetter))!; + + prop.Should().NotBeNull(); + + prop.SetMethod.Should().NotBeNull(); + prop.GetMethod.Should().BeNull(); + + _sut.PropertyWithPrivateGetter = string.Empty; + } + + [Fact] + public void ProtectedSetter_IsOmitted() + { + var prop = typeof(IAccessorsTestsService) + .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedSetter))!; + + prop.Should().NotBeNull(); + + prop.GetMethod.Should().NotBeNull(); + prop.SetMethod.Should().BeNull(); + + var _ = _sut.PropertyWithProtectedSetter; + } + + [Fact] + public void ProtectedGetter_IsOmitted() + { + var prop = typeof(IAccessorsTestsService) + .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedGetter))!; + + prop.Should().NotBeNull(); + + prop.SetMethod.Should().NotBeNull(); + prop.GetMethod.Should().BeNull(); + + _sut.PropertyWithProtectedGetter = string.Empty; + } + + [Fact] + public void IgnoredProperty_IsOmitted() + { + var prop = typeof(IAccessorsTestsService) + .GetProperty(nameof(AccessorsTestsService.IgnoredProperty)); + + prop.Should().BeNull(); + } + + [Fact] + public void StaticProperty_IsOmitted() + { + var prop = typeof(IAccessorsTestsService) + .GetProperty(nameof(AccessorsTestsService.StaticProperty)); + + prop.Should().BeNull(); + } +} + +// ReSharper disable UnusedMember.Local, ValueParameterNotUsed +[GenerateAutoInterface] +internal class AccessorsTestsService : IAccessorsTestsService +{ + public int this[string x] + { + get => 0; + set { - _sut = new AccessorsTestsService(); - } - - [Fact] - public void GetSetIndexer_IsImplemented() - { - var indexer = typeof(IAccessorsTestsService).GetIndexerByParameterTypes(new[] { typeof(string) }); - - indexer.Should().NotBeNull(); - - indexer.GetMethod.Should().NotBeNull(); - indexer.SetMethod.Should().NotBeNull(); - - int _ = _sut[string.Empty]; - _sut[string.Empty] = 0; - } - - [Fact] - public void PublicProperty_IsImplemented() - { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PublicProperty))!; - - prop.Should().NotBeNull(); - - prop.GetMethod.Should().NotBeNull(); - prop.SetMethod.Should().NotBeNull(); - - string _ = _sut.PublicProperty; - _sut.PublicProperty = string.Empty; - } - - [Fact] - public void InitProperty_IsImplemented() - { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.InitOnlyProperty))!; - - prop.Should().NotBeNull(); - - prop.GetMethod.Should().NotBeNull(); - prop.SetMethod.Should().NotBeNull(); - - prop.SetMethod!.ReturnParameter!.GetRequiredCustomModifiers().Should().Contain(typeof(IsExternalInit)); - - string _ = _sut.InitOnlyProperty; - } - - [Fact] - public void PrivateSetter_IsOmitted() - { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateSetter))!; - - prop.Should().NotBeNull(); - - prop.GetMethod.Should().NotBeNull(); - prop.SetMethod.Should().BeNull(); - - string _ = _sut.PropertyWithPrivateSetter; - } - - [Fact] - public void PrivateGetter_IsOmitted() - { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateGetter))!; - - prop.Should().NotBeNull(); - - prop.SetMethod.Should().NotBeNull(); - prop.GetMethod.Should().BeNull(); - - _sut.PropertyWithPrivateGetter = string.Empty; - } - - [Fact] - public void ProtectedSetter_IsOmitted() - { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedSetter))!; - - prop.Should().NotBeNull(); - - prop.GetMethod.Should().NotBeNull(); - prop.SetMethod.Should().BeNull(); - - string _ = _sut.PropertyWithProtectedSetter; - } - - [Fact] - public void ProtectedGetter_IsOmitted() - { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedGetter))!; - - prop.Should().NotBeNull(); - - prop.SetMethod.Should().NotBeNull(); - prop.GetMethod.Should().BeNull(); - - _sut.PropertyWithProtectedGetter = string.Empty; - } - - [Fact] - public void IgnoredProperty_IsOmitted() - { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(AccessorsTestsService.IgnoredProperty)); - - prop.Should().BeNull(); - } - - [Fact] - public void StaticProperty_IsOmitted() - { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(AccessorsTestsService.StaticProperty)); - - prop.Should().BeNull(); } } - // ReSharper disable UnusedMember.Local, ValueParameterNotUsed - [GenerateAutoInterface] - internal class AccessorsTestsService : IAccessorsTestsService - { - public int this[string x] - { - get => 0; - set { } - } - - public string PublicProperty { get; set; } - - public string InitOnlyProperty { get; init; } + public string PublicProperty { get; set; } - public string PropertyWithPrivateSetter { get; private set; } - - public string PropertyWithPrivateGetter { private get; set; } - - public string PropertyWithProtectedSetter { get; protected set; } - - public string PropertyWithProtectedGetter { protected get; set; } + public string InitOnlyProperty { get; init; } - [AutoInterfaceIgnore] - public string IgnoredProperty { get; set; } - - public static string StaticProperty { get; set; } - } - // ReSharper enable UnusedMember.Local, ValueParameterNotUsed -} \ No newline at end of file + public string PropertyWithPrivateSetter { get; private set; } + + public string PropertyWithPrivateGetter { private get; set; } + + public string PropertyWithProtectedSetter { get; protected set; } + + public string PropertyWithProtectedGetter { protected get; set; } + + [AutoInterfaceIgnore] public string IgnoredProperty { get; set; } + + public static string StaticProperty { get; set; } +} +// ReSharper enable UnusedMember.Local, ValueParameterNotUsed \ No newline at end of file diff --git a/InterfaceGenerator.Tests/GenericInterfaceTests.cs b/InterfaceGenerator.Tests/GenericInterfaceTests.cs index fb5575c..8642e3b 100644 --- a/InterfaceGenerator.Tests/GenericInterfaceTests.cs +++ b/InterfaceGenerator.Tests/GenericInterfaceTests.cs @@ -3,35 +3,36 @@ using System.Reflection; using FluentAssertions; using Xunit; -namespace InterfaceGenerator.Tests +namespace InterfaceGenerator.Tests; + +public class GenericInterfaceTests { - public class GenericInterfaceTests + [Fact] + public void GenericParametersGeneratedCorrectly() { - [Fact] - public void GenericParametersGeneratedCorrectly() - { - var genericArgs = typeof(IGenericInterfaceTestsService<,>).GetGenericArguments(); + var genericArgs = typeof(IGenericInterfaceTestsService<,>).GetGenericArguments(); - genericArgs.Should().HaveCount(2); - genericArgs[0].Name.Should().Be("TX"); - genericArgs[1].Name.Should().Be("TY"); + genericArgs.Should().HaveCount(2); + genericArgs[0].Name.Should().Be("TX"); + genericArgs[1].Name.Should().Be("TY"); - genericArgs[0].IsClass.Should().BeTrue(); - genericArgs[0].GenericParameterAttributes - .Should().HaveFlag(GenericParameterAttributes.DefaultConstructorConstraint); + genericArgs[0].IsClass.Should().BeTrue(); + genericArgs[0] + .GenericParameterAttributes + .Should() + .HaveFlag(GenericParameterAttributes.DefaultConstructorConstraint); - var iEquatableOfTx = typeof(IEquatable<>).MakeGenericType(genericArgs[0]); - genericArgs[0].GetGenericParameterConstraints().Should().HaveCount(1).And.Contain(iEquatableOfTx); + var iEquatableOfTx = typeof(IEquatable<>).MakeGenericType(genericArgs[0]); + genericArgs[0].GetGenericParameterConstraints().Should().HaveCount(1).And.Contain(iEquatableOfTx); - genericArgs[1].IsValueType.Should().BeTrue(); - } + genericArgs[1].IsValueType.Should().BeTrue(); } +} - [GenerateAutoInterface] - // ReSharper disable once UnusedType.Global - internal class GenericInterfaceTestsService : IGenericInterfaceTestsService - where TX : class, IEquatable, new() - where TY : struct - { - } +[GenerateAutoInterface] +// ReSharper disable once UnusedType.Global +internal class GenericInterfaceTestsService : IGenericInterfaceTestsService + where TX : class, IEquatable, new() + where TY : struct +{ } \ No newline at end of file diff --git a/InterfaceGenerator.Tests/InterfaceGenerator.Tests.csproj b/InterfaceGenerator.Tests/InterfaceGenerator.Tests.csproj index 912fbda..db3e2fe 100644 --- a/InterfaceGenerator.Tests/InterfaceGenerator.Tests.csproj +++ b/InterfaceGenerator.Tests/InterfaceGenerator.Tests.csproj @@ -1,7 +1,7 @@ - net5.0 + net6.0 false diff --git a/InterfaceGenerator.Tests/MethodGenerationTests.cs b/InterfaceGenerator.Tests/MethodGenerationTests.cs index 05edbd9..a59a1f3 100644 --- a/InterfaceGenerator.Tests/MethodGenerationTests.cs +++ b/InterfaceGenerator.Tests/MethodGenerationTests.cs @@ -5,341 +5,339 @@ using System.Text; using FluentAssertions; using Xunit; -namespace InterfaceGenerator.Tests +namespace InterfaceGenerator.Tests; + +public class MethodGenerationTests { - public class MethodGenerationTests + private readonly IMethodsTestService _sut; + + public MethodGenerationTests() { - private readonly IMethodsTestService _sut; - - public MethodGenerationTests() - { - _sut = new MethodsTestService(); - } - - [Fact] - public void VoidMethod_IsImplemented() - { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethod))!; - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Should().BeEmpty(); - - _sut.VoidMethod(); - } - - [Fact] - public void VoidMethodWithKeywordParam_IsImplemented() - { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithKeywordParam))!; - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string)); - parameters.Should().HaveCount(1); - - parameters[0].Name.Should().Be("void"); - - _sut.VoidMethodWithKeywordParam(""); - } - - [Fact] - public void VoidMethodWithParams_IsImplemented() - { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithParams), - new[] { typeof(string), typeof(string) })!; - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string)); - parameters.Should().HaveCount(2); - - _sut.VoidMethodWithParams(string.Empty, string.Empty); - } - - [Fact] - public void VoidMethodWithOutParam_IsImplemented() - { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithOutParam), - new[] { typeof(string).MakeByRefType() })!; - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string).MakeByRefType()); - parameters.Should().HaveCount(1); - parameters[0].IsOut.Should().BeTrue(); - - _sut.VoidMethodWithOutParam(out var _); - } - - [Fact] - public void VoidMethodWithInParam_IsImplemented() - { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithInParam), - new[] { typeof(string).MakeByRefType() })!; - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string).MakeByRefType()); - parameters.Should().HaveCount(1); - parameters[0].IsIn.Should().BeTrue(); - - var stub = string.Empty; - _sut.VoidMethodWithInParam(in stub); - } - - [Fact] - public void VoidMethodWithRefParam_IsImplemented() - { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithRefParam), - new[] { typeof(string).MakeByRefType() })!; - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string).MakeByRefType()); - parameters.Should().HaveCount(1); - parameters[0].IsIn.Should().BeFalse(); - parameters[0].IsOut.Should().BeFalse(); - - var stub = string.Empty; - _sut.VoidMethodWithRefParam(ref stub); - } - - [Fact] - public void StringMethod_IsImplemented() - { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.StringMethod))!; - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(string)); - - var parameters = method.GetParameters(); - parameters.Should().BeEmpty(); - - var _ = _sut.StringMethod(); - } - - [Fact] - public void GenericVoidMethod_IsImplemented() - { - var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethod)); - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - method.GetParameters().Should().BeEmpty(); - - var genericArgs = method.GetGenericArguments(); - genericArgs.Should().HaveCount(2); - - _sut.GenericVoidMethod(); - } - - [Fact] - public void GenericVoidMethodWithGenericParam_IsImplemented() - { - var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithGenericParam)); - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - var genericArgs = method.GetGenericArguments(); - genericArgs.Should().HaveCount(2); - - var parameters = method.GetParameters(); - parameters.Should().HaveCount(1); - parameters[0].ParameterType.Should().Be(genericArgs[0]); - - _sut.GenericVoidMethodWithGenericParam(string.Empty); - } - - [Fact] - public void GenericVoidMethodWithConstraints_IsImplemented() - { - var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithConstraints)); - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - var genericArgs = method.GetGenericArguments(); - genericArgs.Should().HaveCount(2); - - genericArgs[0].IsClass.Should().BeTrue(); - genericArgs[0].GetGenericParameterConstraints().Should().HaveCount(0); - - genericArgs[1].IsClass.Should().BeTrue(); - genericArgs[1].GetGenericParameterConstraints().Should().HaveCount(1); - genericArgs[1].GetGenericParameterConstraints()[0].Should().Be(genericArgs[0]); - genericArgs[1].GenericParameterAttributes.Should() - .HaveFlag(GenericParameterAttributes.DefaultConstructorConstraint); - - _sut.GenericVoidMethodWithConstraints(); - } - - [Fact] - public void VoidMethodWithOptionalParams_IsImplemented() - { - var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.VoidMethodWithOptionalParams)); - - method.Should().NotBeNull(); - method.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Should().HaveCount(7); - parameters.Select(x => x.IsOptional).Should().AllBeEquivalentTo(true); - - parameters[0].DefaultValue.Should().Be("cGFyYW0="); - parameters[1].DefaultValue.Should().Be(MethodsTestService.StringConstant); - parameters[2].DefaultValue.Should().Be(0.1f); - parameters[3].DefaultValue.Should().Be(0.2d); - parameters[4].DefaultValue.Should().Be(0.3d); - parameters[5].DefaultValue.Should().Be(true); - parameters[6].DefaultValue.Should().Be(false); - - _sut.VoidMethodWithOptionalParams(); - } - - [Fact] - public void VoidMethodWithExpandingParam_IsImplemented() - { - var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.VoidMethodWithExpandingParam)); - - method.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Should().HaveCount(1); - parameters[0].ParameterType.Should().Be(typeof(string[])); - parameters[0].GetCustomAttribute().Should().NotBeNull(); - } - - [Fact] - public void IgnoreMethod_IsOmitted() - { - var method = typeof(IMethodsTestService) - .GetMethods() - .FirstOrDefault(x => x.Name == nameof(MethodsTestService.IgnoredMethod)); - - method.Should().BeNull(); - } - - [Fact] - public void StaticMethod_IsOmitted() - { - var method = typeof(IMethodsTestService) - .GetMethods() - .FirstOrDefault(x => x.Name == nameof(MethodsTestService.StaticMethod)); - - method.Should().BeNull(); - } + _sut = new MethodsTestService(); } - [GenerateAutoInterface] - internal class MethodsTestService : IMethodsTestService + [Fact] + public void VoidMethod_IsImplemented() { - public const string StringConstant = "Const"; + var method = typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethod))!; - public void VoidMethod() - { - } + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); - public void VoidMethodWithParams(string a, string b) - { - } - - public void VoidMethodWithKeywordParam(string @void) - { - } + var parameters = method.GetParameters(); + parameters.Should().BeEmpty(); - public void VoidMethodWithOutParam(out string a) - { - a = default; - } - - public void VoidMethodWithRefParam(ref string a) - { - } - - public void VoidMethodWithInParam(in string a) - { - } - - public string StringMethod() - { - return string.Empty; - } - - public void GenericVoidMethod() - { - } - - public void GenericVoidMethodWithGenericParam(TX a) - { - } - - public void GenericVoidMethodWithConstraints() - where TX : class - where TY : class, TX, new() - { - } - - public void VoidMethodWithOptionalParams( - string stringLiteral = "cGFyYW0=", - string stringConstant = StringConstant, - float floatLiteral = 0.1f, - double doubleLiteral = 0.2, - decimal decimalLiteral = 0.3m, - bool trueLiteral = true, - bool falseLiteral = false) - { - } - - public void VoidMethodWithExpandingParam(params string[] strings) - { - } - - [AutoInterfaceIgnore] - public void IgnoredMethod() - { - - } - - public static void StaticMethod() - { - - } + _sut.VoidMethod(); } - [GenerateAutoInterface] - internal class MethodsTestServiceGeneric : IMethodsTestServiceGeneric where T : class + [Fact] + public void VoidMethodWithKeywordParam_IsImplemented() + { + var method = typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithKeywordParam))!; + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string)); + parameters.Should().HaveCount(1); + + parameters[0].Name.Should().Be("void"); + + _sut.VoidMethodWithKeywordParam(""); + } + + [Fact] + public void VoidMethodWithParams_IsImplemented() + { + var method = typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithParams), + new[] { typeof(string), typeof(string) })!; + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string)); + parameters.Should().HaveCount(2); + + _sut.VoidMethodWithParams(string.Empty, string.Empty); + } + + [Fact] + public void VoidMethodWithOutParam_IsImplemented() + { + var method = typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithOutParam), + new[] { typeof(string).MakeByRefType() })!; + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string).MakeByRefType()); + parameters.Should().HaveCount(1); + parameters[0].IsOut.Should().BeTrue(); + + _sut.VoidMethodWithOutParam(out var _); + } + + [Fact] + public void VoidMethodWithInParam_IsImplemented() + { + var method = typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithInParam), + new[] { typeof(string).MakeByRefType() })!; + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string).MakeByRefType()); + parameters.Should().HaveCount(1); + parameters[0].IsIn.Should().BeTrue(); + + var stub = string.Empty; + _sut.VoidMethodWithInParam(in stub); + } + + [Fact] + public void VoidMethodWithRefParam_IsImplemented() + { + var method = typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithRefParam), + new[] { typeof(string).MakeByRefType() })!; + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string).MakeByRefType()); + parameters.Should().HaveCount(1); + parameters[0].IsIn.Should().BeFalse(); + parameters[0].IsOut.Should().BeFalse(); + + var stub = string.Empty; + _sut.VoidMethodWithRefParam(ref stub); + } + + [Fact] + public void StringMethod_IsImplemented() + { + var method = typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.StringMethod))!; + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(string)); + + var parameters = method.GetParameters(); + parameters.Should().BeEmpty(); + + var _ = _sut.StringMethod(); + } + + [Fact] + public void GenericVoidMethod_IsImplemented() + { + var method = typeof(IMethodsTestService) + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethod)); + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + method.GetParameters().Should().BeEmpty(); + + var genericArgs = method.GetGenericArguments(); + genericArgs.Should().HaveCount(2); + + _sut.GenericVoidMethod(); + } + + [Fact] + public void GenericVoidMethodWithGenericParam_IsImplemented() + { + var method = typeof(IMethodsTestService) + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithGenericParam)); + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var genericArgs = method.GetGenericArguments(); + genericArgs.Should().HaveCount(2); + + var parameters = method.GetParameters(); + parameters.Should().HaveCount(1); + parameters[0].ParameterType.Should().Be(genericArgs[0]); + + _sut.GenericVoidMethodWithGenericParam(string.Empty); + } + + [Fact] + public void GenericVoidMethodWithConstraints_IsImplemented() + { + var method = typeof(IMethodsTestService) + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithConstraints)); + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var genericArgs = method.GetGenericArguments(); + genericArgs.Should().HaveCount(2); + + genericArgs[0].IsClass.Should().BeTrue(); + genericArgs[0].GetGenericParameterConstraints().Should().HaveCount(0); + + genericArgs[1].IsClass.Should().BeTrue(); + genericArgs[1].GetGenericParameterConstraints().Should().HaveCount(1); + genericArgs[1].GetGenericParameterConstraints()[0].Should().Be(genericArgs[0]); + genericArgs[1] + .GenericParameterAttributes.Should() + .HaveFlag(GenericParameterAttributes.DefaultConstructorConstraint); + + _sut.GenericVoidMethodWithConstraints(); + } + + [Fact] + public void VoidMethodWithOptionalParams_IsImplemented() + { + var method = typeof(IMethodsTestService) + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.VoidMethodWithOptionalParams)); + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Should().HaveCount(7); + parameters.Select(x => x.IsOptional).Should().AllBeEquivalentTo(true); + + parameters[0].DefaultValue.Should().Be("cGFyYW0="); + parameters[1].DefaultValue.Should().Be(MethodsTestService.StringConstant); + parameters[2].DefaultValue.Should().Be(0.1f); + parameters[3].DefaultValue.Should().Be(0.2d); + parameters[4].DefaultValue.Should().Be(0.3d); + parameters[5].DefaultValue.Should().Be(true); + parameters[6].DefaultValue.Should().Be(false); + + _sut.VoidMethodWithOptionalParams(); + } + + [Fact] + public void VoidMethodWithExpandingParam_IsImplemented() + { + var method = typeof(IMethodsTestService) + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.VoidMethodWithExpandingParam)); + + method.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Should().HaveCount(1); + parameters[0].ParameterType.Should().Be(typeof(string[])); + parameters[0].GetCustomAttribute().Should().NotBeNull(); + } + + [Fact] + public void IgnoreMethod_IsOmitted() + { + var method = typeof(IMethodsTestService) + .GetMethods() + .FirstOrDefault(x => x.Name == nameof(MethodsTestService.IgnoredMethod)); + + method.Should().BeNull(); + } + + [Fact] + public void StaticMethod_IsOmitted() + { + var method = typeof(IMethodsTestService) + .GetMethods() + .FirstOrDefault(x => x.Name == nameof(MethodsTestService.StaticMethod)); + + method.Should().BeNull(); + } +} + +[GenerateAutoInterface] +internal class MethodsTestService : IMethodsTestService +{ + public const string StringConstant = "Const"; + + public void VoidMethod() { } + + public void VoidMethodWithParams(string a, string b) + { + } + + public void VoidMethodWithKeywordParam(string @void) + { + } + + public void VoidMethodWithOutParam(out string a) + { + a = default; + } + + public void VoidMethodWithRefParam(ref string a) + { + } + + public void VoidMethodWithInParam(in string a) + { + } + + public string StringMethod() + { + return string.Empty; + } + + public void GenericVoidMethod() + { + } + + public void GenericVoidMethodWithGenericParam(TX a) + { + } + + public void GenericVoidMethodWithConstraints() + where TX : class + where TY : class, TX, new() + { + } + + public void VoidMethodWithOptionalParams( + string stringLiteral = "cGFyYW0=", + string stringConstant = StringConstant, + float floatLiteral = 0.1f, + double doubleLiteral = 0.2, + decimal decimalLiteral = 0.3m, + bool trueLiteral = true, + bool falseLiteral = false) + { + } + + public void VoidMethodWithExpandingParam(params string[] strings) + { + } + + [AutoInterfaceIgnore] + public void IgnoredMethod() + { + } + + public static void StaticMethod() + { + } +} + +[GenerateAutoInterface] +internal class MethodsTestServiceGeneric : IMethodsTestServiceGeneric where T : class +{ } \ No newline at end of file diff --git a/InterfaceGenerator.Tests/Partial/PartialClass.1.cs b/InterfaceGenerator.Tests/Partial/PartialClass.1.cs new file mode 100644 index 0000000..02ff0de --- /dev/null +++ b/InterfaceGenerator.Tests/Partial/PartialClass.1.cs @@ -0,0 +1,7 @@ +namespace InterfaceGenerator.Tests.Partial; + +[GenerateAutoInterface] +internal partial class PartialClass : IPartialClass +{ + +} \ No newline at end of file diff --git a/InterfaceGenerator.Tests/Partial/PartialClass.2.cs b/InterfaceGenerator.Tests/Partial/PartialClass.2.cs new file mode 100644 index 0000000..9bcf3b9 --- /dev/null +++ b/InterfaceGenerator.Tests/Partial/PartialClass.2.cs @@ -0,0 +1,8 @@ +namespace InterfaceGenerator.Tests.Partial; + +internal partial class PartialClass +{ + public void SomeMethodThatShouldGenerate() + { + } +} \ No newline at end of file diff --git a/InterfaceGenerator.Tests/PartialClassTests.cs b/InterfaceGenerator.Tests/PartialClassTests.cs new file mode 100644 index 0000000..a290724 --- /dev/null +++ b/InterfaceGenerator.Tests/PartialClassTests.cs @@ -0,0 +1,16 @@ +using System; +using FluentAssertions; +using InterfaceGenerator.Tests.Partial; +using Xunit; + +namespace InterfaceGenerator.Tests; + +public class PartialClassTests +{ + [Fact] + public void GeneratesMethodFromOtherParts() + { + var tInterface = typeof(IPartialClass); + tInterface.GetMethods().Should().Contain(x => x.Name == nameof(PartialClass.SomeMethodThatShouldGenerate)); + } +} \ No newline at end of file diff --git a/InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs b/InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs index 161bd80..8274723 100644 --- a/InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs +++ b/InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs @@ -2,70 +2,69 @@ using System.Runtime.CompilerServices; using FluentAssertions; using Xunit; -namespace InterfaceGenerator.Tests +namespace InterfaceGenerator.Tests; + +public class RecordInterfaceGenerationTests { - public class RecordInterfaceGenerationTests + private readonly ITestRecord _sut; + + public RecordInterfaceGenerationTests() { - private readonly ITestRecord _sut; - - public RecordInterfaceGenerationTests() - { - _sut = new TestRecord(420); - } - - [Fact] - public void RecordProperty_IsGenerated() - { - var prop = typeof(ITestRecord) - .GetProperty(nameof(TestRecord.RecordProperty))!; - - prop.Should().NotBeNull(); - - prop.GetMethod.Should().NotBeNull(); - prop.SetMethod.Should().NotBeNull(); - prop.SetMethod!.ReturnParameter!.GetRequiredCustomModifiers().Should().Contain(typeof(IsExternalInit)); - - _sut.RecordProperty.Should().Be(420); - } - - [Fact] - public void RecordMethod_IsGenerated() - { - var method = typeof(ITestRecord).GetMethod( - nameof(TestRecord.RecordMethod)); - - method.Should().NotBeNull(); - method!.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Should().BeEmpty(); - - _sut.RecordMethod(); - } - - [Fact] - public void Deconstruct_IsGenerated() - { - var method = typeof(ITestRecord).GetMethod( - nameof(TestRecord.Deconstruct)); - - method.Should().NotBeNull(); - method!.ReturnType.Should().Be(typeof(void)); - - var parameters = method.GetParameters(); - parameters.Length.Should().Be(1); - - var parameter = parameters[0]; - parameter.ParameterType.Should().Be(typeof(int).MakeByRefType()); - parameter.IsOut.Should().BeTrue(); - } + _sut = new TestRecord(420); } - [GenerateAutoInterface] - internal record TestRecord(int RecordProperty) : ITestRecord + [Fact] + public void RecordProperty_IsGenerated() + { + var prop = typeof(ITestRecord) + .GetProperty(nameof(TestRecord.RecordProperty))!; + + prop.Should().NotBeNull(); + + prop.GetMethod.Should().NotBeNull(); + prop.SetMethod.Should().NotBeNull(); + prop.SetMethod!.ReturnParameter!.GetRequiredCustomModifiers().Should().Contain(typeof(IsExternalInit)); + + _sut.RecordProperty.Should().Be(420); + } + + [Fact] + public void RecordMethod_IsGenerated() + { + var method = typeof(ITestRecord).GetMethod( + nameof(TestRecord.RecordMethod)); + + method.Should().NotBeNull(); + method!.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Should().BeEmpty(); + + _sut.RecordMethod(); + } + + [Fact] + public void Deconstruct_IsGenerated() + { + var method = typeof(ITestRecord).GetMethod( + nameof(TestRecord.Deconstruct)); + + method.Should().NotBeNull(); + method!.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Length.Should().Be(1); + + var parameter = parameters[0]; + parameter.ParameterType.Should().Be(typeof(int).MakeByRefType()); + parameter.IsOut.Should().BeTrue(); + } +} + +[GenerateAutoInterface] +internal record TestRecord(int RecordProperty) : ITestRecord +{ + public void RecordMethod() { - public void RecordMethod() - { - } } } \ No newline at end of file diff --git a/InterfaceGenerator.Tests/VisibilityModifierTests.cs b/InterfaceGenerator.Tests/VisibilityModifierTests.cs index 5751fd9..33c9e08 100644 --- a/InterfaceGenerator.Tests/VisibilityModifierTests.cs +++ b/InterfaceGenerator.Tests/VisibilityModifierTests.cs @@ -2,56 +2,55 @@ using FluentAssertions; using Xunit; -namespace InterfaceGenerator.Tests +namespace InterfaceGenerator.Tests; + +public class VisibilityModifierTests { - public class VisibilityModifierTests + [Fact] + public void IExplicitlyPublicService_IsPublic() { - [Fact] - public void IExplicitlyPublicService_IsPublic() - { - var type = typeof(IExplicitlyPublicService); - type.Attributes.Should().HaveFlag(TypeAttributes.Public); - } - - [Fact] - public void IExplicitlyInternalService_IsInternal() - { - var type = typeof(IExplicitlyInternalService); - type.Attributes.Should().HaveFlag(TypeAttributes.NotPublic); - } - - [Fact] - public void IImplicitlyPublicService_IsPublic() - { - var type = typeof(IImplicitlyPublicService); - type.Attributes.Should().HaveFlag(TypeAttributes.Public); - } - - [Fact] - public void IImplicitlyInternalService_IsInternal() - { - var type = typeof(IImplicitlyInternalService); - type.Attributes.Should().HaveFlag(TypeAttributes.NotPublic); - } + var type = typeof(IExplicitlyPublicService); + type.Attributes.Should().HaveFlag(TypeAttributes.Public); } - [GenerateAutoInterface(VisibilityModifier = "public")] - internal class ExplicitlyPublicService : IExplicitlyPublicService + [Fact] + public void IExplicitlyInternalService_IsInternal() { + var type = typeof(IExplicitlyInternalService); + type.Attributes.Should().HaveFlag(TypeAttributes.NotPublic); } - - [GenerateAutoInterface(VisibilityModifier = "internal")] - public class ExplicitlyInternalService : IExplicitlyInternalService + + [Fact] + public void IImplicitlyPublicService_IsPublic() { + var type = typeof(IImplicitlyPublicService); + type.Attributes.Should().HaveFlag(TypeAttributes.Public); } - - [GenerateAutoInterface] - public class ImplicitlyPublicService : IImplicitlyPublicService - { - } - - [GenerateAutoInterface] - internal class ImplicitlyInternalService : IImplicitlyInternalService + + [Fact] + public void IImplicitlyInternalService_IsInternal() { + var type = typeof(IImplicitlyInternalService); + type.Attributes.Should().HaveFlag(TypeAttributes.NotPublic); } +} + +[GenerateAutoInterface(VisibilityModifier = "public")] +internal class ExplicitlyPublicService : IExplicitlyPublicService +{ +} + +[GenerateAutoInterface(VisibilityModifier = "internal")] +public class ExplicitlyInternalService : IExplicitlyInternalService +{ +} + +[GenerateAutoInterface] +public class ImplicitlyPublicService : IImplicitlyPublicService +{ +} + +[GenerateAutoInterface] +internal class ImplicitlyInternalService : IImplicitlyInternalService +{ } \ No newline at end of file diff --git a/InterfaceGenerator/AutoInterfaceGenerator.cs b/InterfaceGenerator/AutoInterfaceGenerator.cs index 376448b..c470612 100644 --- a/InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/InterfaceGenerator/AutoInterfaceGenerator.cs @@ -24,6 +24,34 @@ namespace InterfaceGenerator } public void Execute(GeneratorExecutionContext context) + { + try + { + ExecuteCore(context); + } + catch (Exception exception) + { + RaiseExceptionDiagnostic(context, exception); + } + } + + private static void RaiseExceptionDiagnostic(GeneratorExecutionContext context, Exception exception) + { + var descriptor = new DiagnosticDescriptor( + "InterfaceGenerator.CriticalError", + "Exception thrown in InterfaceGenerator", + $"{exception.Message} {exception.StackTrace}", + "InterfaceGenerator", + DiagnosticSeverity.Error, + true, + customTags: WellKnownDiagnosticTags.AnalyzerException); + + var diagnostic = Diagnostic.Create(descriptor, null); + + context.ReportDiagnostic(diagnostic); + } + + private void ExecuteCore(GeneratorExecutionContext context) { // setting the culture to invariant prevents errors such as emitting a decimal comma (0,1) instead of // a decimal point (0.1) in certain cultures diff --git a/InterfaceGenerator/InterfaceGenerator.csproj b/InterfaceGenerator/InterfaceGenerator.csproj index 3ba41c3..0a39408 100644 --- a/InterfaceGenerator/InterfaceGenerator.csproj +++ b/InterfaceGenerator/InterfaceGenerator.csproj @@ -3,7 +3,7 @@ netstandard2 9.0 enable - 1.0.8 + 1.0.9 true false