Skip to content

Commit

Permalink
#176: Adding support for aggregated/interhited interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Steffen committed Jul 13, 2018
1 parent ee7a8f0 commit 3943d36
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
16 changes: 15 additions & 1 deletion InterfaceStubGenerator.Core/InterfaceStubGenerator.cs
Expand Up @@ -4,7 +4,6 @@
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
Expand Down Expand Up @@ -83,6 +82,7 @@ public ClassTemplateInfo GenerateClassInfoForInterface(InterfaceDeclarationSynta
ret.InterfaceName = GetInterfaceName(interfaceTree.Identifier);
ret.GeneratedClassSuffix = ret.InterfaceName.Replace(".", "");
ret.Modifiers = interfaceTree.Modifiers.Select(t => t.ValueText).FirstOrDefault(m => m == "public" || m == "internal");
ret.BaseClassNames = interfaceTree.BaseList?.Types.Select(t => t.ToString()).ToList();

if (interfaceTree.TypeParameterList != null)
{
Expand Down Expand Up @@ -168,6 +168,19 @@ public TemplateInformation GenerateTemplateInfoForInterfaceList(List<InterfaceDe
UsingList = usings.ToList()
};

ret = AddInheritedMethods(ret);

return ret;
}

private TemplateInformation AddInheritedMethods(TemplateInformation ret)
{
foreach (var c in ret.ClassList.Where(c => c.BaseClassNames != null && c.BaseClassNames.Any()))
{
var methodsToAdd = ret.ClassList.Where(oc => c.BaseClassNames.Contains(oc.InterfaceName)).SelectMany(oc => oc.MethodList);
c.MethodList.AddRange(methodsToAdd);
}

return ret;
}

Expand Down Expand Up @@ -227,6 +240,7 @@ public class ClassTemplateInfo
public string ConstraintClauses { get; set; }
public string GeneratedClassSuffix { get; set; }
public string InterfaceName { get; set; }
public List<string> BaseClassNames { get; set; }
public List<MethodTemplateInfo> MethodList { get; set; }
public string Modifiers { get; set; }
public string Namespace { get; set; }
Expand Down
27 changes: 27 additions & 0 deletions Refit.Tests/InheritedInterfacesApi.cs
@@ -0,0 +1,27 @@
using System.Threading.Tasks;
using Refit; // InterfaceStubGenerator looks for this
using static System.Math; // This is here to verify https://github.com/paulcbetts/refit/issues/283

namespace Refit.Tests
{
[Headers("User-Agent: Refit Integration Tests")]
public interface IAmInterfaceA
{
[Get("/ping")]
Task<string> Ping();
}

[Headers("User-Agent: Refit Integration Tests")]
public interface IAmInterfaceB
{
[Get("/pong")]
Task<string> Pong();
}

[Headers("User-Agent: Refit Integration Tests")]
public interface IAmInterfaceC : IAmInterfaceB, IAmInterfaceA
{
[Get("/pang")]
Task<string> Pang();
}
}
38 changes: 33 additions & 5 deletions Refit.Tests/InterfaceStubGenerator.cs
Expand Up @@ -27,9 +27,11 @@ public void GenerateInterfaceStubsSmokeTest()
var result = fixture.GenerateInterfaceStubs(new[] {
IntegrationTestHelper.GetPath("RestService.cs"),
IntegrationTestHelper.GetPath("GitHubApi.cs"),
IntegrationTestHelper.GetPath("InheritedInterfacesApi.cs"),
});

Assert.Contains("IGitHubApi", result);
Assert.Contains("IAmInterfaceC", result);
}

[Fact]
Expand Down Expand Up @@ -92,7 +94,7 @@ public void GenerateClassInfoForInterfaceSmokeTest()
Assert.Equal("IGitHubApi", result.InterfaceName);
Assert.Equal("IGitHubApi", result.GeneratedClassSuffix);
}

[Fact]
public void GenerateClassInfoForNestedInterfaceSmokeTest()
{
Expand All @@ -104,14 +106,14 @@ public void GenerateClassInfoForNestedInterfaceSmokeTest()
.First(x => x.Identifier.ValueText == "INestedGitHubApi");

var result = fixture.GenerateClassInfoForInterface(input);
Assert.Equal("TestNested.INestedGitHubApi",result.InterfaceName);
Assert.Equal("TestNestedINestedGitHubApi",result.GeneratedClassSuffix);

Assert.Equal("TestNested.INestedGitHubApi", result.InterfaceName);
Assert.Equal("TestNestedINestedGitHubApi", result.GeneratedClassSuffix);
Assert.Equal(8, result.MethodList.Count);
Assert.Equal("GetUser", result.MethodList[0].Name);
Assert.Equal("string userName", result.MethodList[0].ArgumentListWithTypes);
}

[Fact]
public void GenerateTemplateInfoForInterfaceListSmokeTest()
{
Expand All @@ -126,6 +128,32 @@ public void GenerateTemplateInfoForInterfaceListSmokeTest()
Assert.Equal(10, result.ClassList.Count);
}

[Fact]
public void GenerateTemplateInfoForInheritedInterfacesListSmokeTest()
{
var file = CSharpSyntaxTree.ParseText(File.ReadAllText(IntegrationTestHelper.GetPath("InheritedInterfacesApi.cs")));
var fixture = new InterfaceStubGenerator();

var input = file.GetRoot().DescendantNodes()
.OfType<InterfaceDeclarationSyntax>()
.ToList();

var result = fixture.GenerateTemplateInfoForInterfaceList(input);
Assert.Equal(3, result.ClassList.Count);

var inherited = result.ClassList.First(c => c.InterfaceName == "IAmInterfaceC");

Assert.Equal(3, inherited.MethodList.Count);
var methodNames = inherited.MethodList.Select(m => m.Name).ToList();

Assert.Contains("Ping", methodNames);
Assert.Contains("Pong", methodNames);
Assert.Contains("Pang", methodNames);

Assert.Equal("IAmInterfaceC", inherited.InterfaceName);
Assert.Equal("IAmInterfaceC", inherited.GeneratedClassSuffix);
}

[Fact]
public void RetainsAliasesInUsings()
{
Expand Down

0 comments on commit 3943d36

Please sign in to comment.