Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: generate code for derived non refit methods. #1875

Merged
merged 1 commit into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion InterfaceStubGenerator.Shared/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ bool nullableEnabled
.Where(m => IsRefitMethod(m, httpMethodBaseAttributeSymbol))
.ToArray();
var derivedNonRefitMethods = derivedMethods
.Except(derivedMethods, SymbolEqualityComparer.Default)
.Except(derivedRefitMethods, SymbolEqualityComparer.Default)
.Cast<IMethodSymbol>()
.ToArray();

Expand Down
3 changes: 1 addition & 2 deletions Refit.GeneratorTests/Incremental/InheritanceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ public interface IGitHubApi : IDisposable
[Fact]
public void InheritFromInterfaceDoesRegenerate()
{
// TODO: this currently generates invalid code see issue #1801 for more information
var syntaxTree = CSharpSyntaxTree.ParseText(TwoInterface, CSharpParseOptions.Default);
var compilation1 = Fixture.CreateLibrary(syntaxTree);

Expand All @@ -94,6 +93,6 @@ public interface IGitHubApi : IBaseInterface
"""
);
var driver2 = driver1.RunGenerators(compilation2);
TestHelper.AssertRunReasons(driver2, IncrementalGeneratorRunReasons.Cached);
TestHelper.AssertRunReasons(driver2, IncrementalGeneratorRunReasons.Modified);
}
}
1 change: 0 additions & 1 deletion Refit.GeneratorTests/InterfaceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public interface IBaseInterface
[Fact]
public Task RefitInterfaceDerivedFromBaseTest()
{
// TODO: this currently generates invalid code see issue #1801 for more information
return Fixture.VerifyForType(
"""
public interface IGeneratedInterface : IBaseInterface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ public RefitGeneratorTestIGeneratedInterface(global::System.Net.Http.HttpClient

return await ((global::System.Threading.Tasks.Task<string>)______func(this.Client, ______arguments)).ConfigureAwait(false);
}

/// <inheritdoc />
void global::RefitGeneratorTest.IBaseInterface.NonRefitMethod()
{
throw new global::System.NotImplementedException("Either this method has no Refit HTTP method attribute or you've used something other than a string literal for the 'path' argument.");
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
Diagnostics: [
{
Location: /*
{
void NonRefitMethod();
^^^^^^^^^^^^^^
}
*/
: (19,9)-(19,23),
Message: Method IBaseInterface.NonRefitMethod either has no Refit HTTP method attribute or you've used something other than a string literal for the 'path' argument,
Severity: Warning,
WarningLevel: 1,
Descriptor: {
Id: RF001,
Title: Refit types must have Refit HTTP method attributes,
MessageFormat: Method {0}.{1} either has no Refit HTTP method attribute or you've used something other than a string literal for the 'path' argument,
Category: Refit,
DefaultSeverity: Warning,
IsEnabledByDefault: true
}
}
]
}
8 changes: 8 additions & 0 deletions Refit.Tests/InheritedInterfacesApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ public interface IImplementTheInterfaceAndUseRefit : IAmInterfaceEWithNoRefit<in
[Get("/DoSomethingElse")]
public new Task DoSomethingElse();
}

public interface IImplementTheInterfaceAndDontUseRefit : IAmInterfaceD
{
#pragma warning disable CS0108 // Member hides inherited member; missing new keyword
Task<string> Test();
#pragma warning restore CS0108 // Member hides inherited member; missing new keyword
}

public interface IMyClient
{
[Get("/")]
Expand Down
38 changes: 31 additions & 7 deletions Refit.Tests/RestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1974,19 +1974,43 @@ public async Task InheritedInterfaceWithoutRefitInBaseMethodsTest()
await fixture.DoSomethingElse();
mockHttp.VerifyNoOutstandingExpectation();

mockHttp
.Expect(HttpMethod.Get, "https://httpbin.org/DoSomethingElse")
.Respond("application/json", nameof(IImplementTheInterfaceAndUseRefit.DoSomethingElse));
await ((IAmInterfaceEWithNoRefit<int>)fixture).DoSomethingElse();
// base non refit method should throw NotImplementedException
await Assert.ThrowsAsync<NotImplementedException>(
() => ((IAmInterfaceEWithNoRefit<int>)fixture).DoSomethingElse()
);
mockHttp.VerifyNoOutstandingExpectation();
}

[Fact]
public async Task InheritedInterfaceWithoutRefitMethodsOverrideBaseTest()
{
var mockHttp = new MockHttpMessageHandler();

var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp };

Assert.Throws<InvalidOperationException>(
() => RestService.For<IAmInterfaceEWithNoRefit<int>>("https://httpbin.org")
var fixture = RestService.For<IImplementTheInterfaceAndDontUseRefit>(
"https://httpbin.org",
settings
);

// inherited non refit method should throw NotImplementedException
await Assert.ThrowsAsync<NotImplementedException>(
() => fixture.Test()
);
mockHttp.VerifyNoOutstandingExpectation();

// base Refit method should respond
mockHttp
.Expect(HttpMethod.Get, "https://httpbin.org/get")
.WithQueryString("result", "Test")
.Respond("application/json", nameof(IAmInterfaceD.Test));

await ((IAmInterfaceD)fixture).Test();
mockHttp.VerifyNoOutstandingExpectation();
}

[Fact]
public async Task DictionaryDynamicQueryparametersTest()
public async Task DictionaryDynamicQueryParametersTest()
{
var mockHttp = new MockHttpMessageHandler();

Expand Down
Loading