Skip to content

Commit

Permalink
Merge pull request #147 from tmenier/dev
Browse files Browse the repository at this point in the history
Flurl.Http 1.1
  • Loading branch information
tmenier authored Nov 21, 2016
2 parents f8498c0 + 2c5a458 commit a025bf2
Show file tree
Hide file tree
Showing 29 changed files with 404 additions and 275 deletions.
3 changes: 2 additions & 1 deletion Build/nuspec/Flurl.Http.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package >
<metadata>
<id>Flurl.Http</id>
<version>1.0.3</version>
<version>1.1.0-pre</version>
<title>Flurl.Http</title>
<authors>Todd Menier</authors>
<projectUrl>http://tmenier.github.io/Flurl</projectUrl>
Expand All @@ -13,6 +13,7 @@
A fluent, portable, testable HTTP client library that extends Flurl's URL builder chain.
</description>
<releaseNotes>
1.1.0 - Parallel testing (github #67), better DI/IoC/mocking support (github #146), assert query params (github #102)
1.0.3 - .NET Core 1.0.1, fixed assembly references (github #131)
1.0.2 - Updated Flurl dependency to 2.2.1 https://www.nuget.org/packages/Flurl/2.2.1
1.0.1 - Updated Flurl dependency to 2.2 https://www.nuget.org/packages/Flurl/2.2.0
Expand Down
32 changes: 12 additions & 20 deletions Test/Flurl.Test.Shared/Http/ClientLifetimeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,37 @@

namespace Flurl.Test.Http
{
[TestFixture]
[TestFixture, Parallelizable]
public class ClientLifetimeTests
{
private readonly TestHttpClientFactoryWithCounter _fac;

public ClientLifetimeTests() {
_fac = new TestHttpClientFactoryWithCounter();
FlurlHttp.Configure(settings => settings.HttpClientFactory = _fac);
}

[SetUp]
public void CreateHttpTest() {
_fac.NewClientCount = 0;
}

[Test]
public async Task autodispose_true_creates_new_httpclients() {
var fc = new FlurlClient("http://www.mysite.com", true);
var fac = new TestHttpClientFactoryWithCounter();
var fc = new FlurlClient("http://www.mysite.com") {
Settings = { HttpClientFactory = fac, AutoDispose = true }
};
var x = await fc.GetAsync();
var y = await fc.GetAsync();
var z = await fc.GetAsync();
Assert.AreEqual(3, _fac.NewClientCount);
Assert.AreEqual(3, fac.NewClientCount);
}

[Test]
public async Task autodispose_false_resues_httpclient() {
var fc = new FlurlClient("http://www.mysite.com", false);
public async Task autodispose_false_reuses_httpclient() {
var fac = new TestHttpClientFactoryWithCounter();
var fc = new FlurlClient("http://www.mysite.com") {
Settings = { HttpClientFactory = fac, AutoDispose = false }
};
var x = await fc.GetAsync();
var y = await fc.GetAsync();
var z = await fc.GetAsync();
Assert.AreEqual(1, _fac.NewClientCount);
Assert.AreEqual(1, fac.NewClientCount);
}

private class TestHttpClientFactoryWithCounter : TestHttpClientFactory
{
public int NewClientCount { get; set; }

public TestHttpClientFactoryWithCounter() : base(new HttpTest()) { }

public override HttpClient CreateClient(Url url, HttpMessageHandler handler) {
NewClientCount++;
return base.CreateClient(url, handler);
Expand Down
2 changes: 1 addition & 1 deletion Test/Flurl.Test.Shared/Http/FlurlClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Flurl.Test.Http
{
[TestFixture]
[TestFixture, Parallelizable]
public class FlurlClientTests
{
[Test]
Expand Down
1 change: 0 additions & 1 deletion Test/Flurl.Test.Shared/Http/GetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Text;
using System.Threading.Tasks;
using Flurl.Http;
using Flurl.Http.Testing;
using NUnit.Framework;

namespace Flurl.Test.Http
Expand Down
1 change: 1 addition & 0 deletions Test/Flurl.Test.Shared/Http/GlobalConfigTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Flurl.Test.Http
/// All global settings can also be set at the client level, so this base class allows ClientConfigTests to
/// inherit all the same tests.
/// </summary>
[Parallelizable]
public abstract class ConfigTestsBase
{
protected abstract FlurlHttpSettings GetSettings();
Expand Down
2 changes: 1 addition & 1 deletion Test/Flurl.Test.Shared/Http/HttpStatusRangeParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Flurl.Test.Http
{
[TestFixture]
[TestFixture, Parallelizable]
public class HttpStatusRangeParserTests
{
[TestCase("4**", 399, ExpectedResult = false)]
Expand Down
1 change: 1 addition & 0 deletions Test/Flurl.Test.Shared/Http/HttpTestFixtureBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace Flurl.Test.Http
{
[Parallelizable]
public abstract class HttpTestFixtureBase
{
protected HttpTest HttpTest { get; private set; }
Expand Down
2 changes: 1 addition & 1 deletion Test/Flurl.Test.Shared/Http/MultipartTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Flurl.Test.Http
{
[TestFixture]
[TestFixture, Parallelizable]
public class MultipartTests
{
[Test]
Expand Down
2 changes: 1 addition & 1 deletion Test/Flurl.Test.Shared/Http/RealHttpTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Flurl.Test.Http
/// http://httpbin.org. One important aspect these verify is that AutoDispose behavior is not preventing us from getting
/// stuff out of the response (i.e. that we're not disposing too early).
/// </summary>
[TestFixture]
[TestFixture, Parallelizable]
public class RealHttpTests
{
[Test]
Expand Down
47 changes: 46 additions & 1 deletion Test/Flurl.Test.Shared/Http/TestingTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System.Linq;
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Flurl.Http;
using Flurl.Http.Testing;
using NUnit.Framework;

namespace Flurl.Test.Http
Expand Down Expand Up @@ -63,6 +65,25 @@ public async Task can_setup_multiple_responses() {
HttpTest.ShouldNotHaveCalled("http://www.otherapi.com/*");
}

[Test]
public async Task can_assert_query_params() {
await "http://www.api.com?x=111&y=222&z=333".GetAsync();

HttpTest.ShouldHaveCalled("http://www.api.com*").WithQueryParam("x");
HttpTest.ShouldHaveCalled("http://www.api.com*").WithQueryParam("y", 222);
HttpTest.ShouldHaveCalled("*").WithQueryParam("z", "*3");
HttpTest.ShouldHaveCalled("*").WithQueryParams(new { z = 333, y = 222 });

Assert.Throws<HttpCallAssertException>(() =>
HttpTest.ShouldHaveCalled("http://www.api.com*").WithQueryParam("w"));
Assert.Throws<HttpCallAssertException>(() =>
HttpTest.ShouldHaveCalled("http://www.api.com*").WithQueryParam("y", 223));
Assert.Throws<HttpCallAssertException>(() =>
HttpTest.ShouldHaveCalled("*").WithQueryParam("z", "*4"));
Assert.Throws<HttpCallAssertException>(() =>
HttpTest.ShouldHaveCalled("*").WithQueryParams(new { x = 111, y = 666 }));
}

[Test]
public async Task can_simulate_timeout() {
HttpTest.SimulateTimeout();
Expand Down Expand Up @@ -95,5 +116,29 @@ public async Task can_fake_cookies() {
Assert.AreEqual(1, fc.Cookies.Count());
Assert.AreEqual("foo", fc.Cookies["c1"].Value);
}

// parallel testing not supported in PCL
#if !PORTABLE
[Test]
public async Task can_test_in_parallel() {
await Task.WhenAll(
CallAndAssertCountAsync(7),
CallAndAssertCountAsync(5),
CallAndAssertCountAsync(3),
CallAndAssertCountAsync(4),
CallAndAssertCountAsync(6));
}
#endif

private async Task CallAndAssertCountAsync(int calls) {
using (var test = new HttpTest()) {
for (int i = 0; i < calls; i++) {
await "http://www.api.com".GetAsync();
await Task.Delay(100);
}
test.ShouldHaveCalled("http://www.api.com").Times(calls);
//Console.WriteLine($"{calls} calls expected, {test.CallLog.Count} calls made");
}
}
}
}
4 changes: 2 additions & 2 deletions src/Flurl.Http.CodeGen/ExtensionMethodModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public static IEnumerable<ExtensionMethodModel> GetAll() {
return
from httpVerb in new[] { null, "Get", "Post", "Head", "Put", "Delete", "Patch" }
from bodyType in new[] { null, "Json", /*"Xml",*/ "String", "UrlEncoded" }
from extensionType in new[] { "FlurlClient", "Url", "string" }
from extensionType in new[] { "IFlurlClient", "Url", "string" }
where SupportedCombo(httpVerb, bodyType, extensionType)
from deserializeType in new[] { null, "Json", "JsonList", /*"Xml",*/ "String", "Stream", "Bytes" }
where httpVerb == "Get" || deserializeType == null
Expand All @@ -27,7 +27,7 @@ where AllowDeserializeToGeneric(deserializeType) || !isGeneric
private static bool SupportedCombo(string verb, string bodyType, string extensionType) {
switch (verb) {
case null: // Send
return bodyType != null || extensionType != "FlurlClient";
return bodyType != null || extensionType != "IFlurlClient";
case "Post":
return true;
case "Put":
Expand Down
14 changes: 7 additions & 7 deletions src/Flurl.Http.CodeGen/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ private static void WriteExtensionMethods(CodeWriter writer)
name = xm.Name;
}
writer.WriteLine("/// <summary>");
var summaryStart = (xm.ExtentionOfType == "FlurlClient") ? "Sends" : "Creates a FlurlClient from the URL and sends";
var summaryStart = (xm.ExtentionOfType == "IFlurlClient") ? "Sends" : "Creates a FlurlClient from the URL and sends";
if (xm.HttpVerb == null)
writer.WriteLine("/// @0 an asynchronous request.", summaryStart);
else
writer.WriteLine("/// @0 an asynchronous @1 request.", summaryStart, xm.HttpVerb.ToUpperInvariant());
writer.WriteLine("/// </summary>");
if (xm.ExtentionOfType == "FlurlClient")
writer.WriteLine("/// <param name=\"client\">The Flurl client.</param>");
if (xm.ExtentionOfType == "IFlurlClient")
writer.WriteLine("/// <param name=\"client\">The IFlurlClient instance.</param>");
if (xm.ExtentionOfType == "Url" || xm.ExtentionOfType == "string")
writer.WriteLine("/// <param name=\"url\">The URL.</param>");
if (xm.HttpVerb == null)
Expand All @@ -87,7 +87,7 @@ private static void WriteExtensionMethods(CodeWriter writer)
writer.WriteLine("/// <returns>A Task whose result is @0.</returns>", xm.ReturnTypeDescription);

var args = new List<string>();
args.Add("this " + xm.ExtentionOfType + (xm.ExtentionOfType == "FlurlClient" ? " client" : " url"));
args.Add("this " + xm.ExtentionOfType + (xm.ExtentionOfType == "IFlurlClient" ? " client" : " url"));
if (xm.HttpVerb == null)
args.Add("HttpMethod verb");
if (xm.BodyType != null)
Expand All @@ -101,7 +101,7 @@ private static void WriteExtensionMethods(CodeWriter writer)

writer.WriteLine("public static Task<@0> @1@2(@3) {", xm.TaskArg, xm.Name, xm.IsGeneric ? "<T>" : "", string.Join(", ", args));

if (xm.ExtentionOfType == "FlurlClient")
if (xm.ExtentionOfType == "IFlurlClient")
{
args.Clear();
args.Add(
Expand All @@ -118,10 +118,10 @@ private static void WriteExtensionMethods(CodeWriter writer)
if (xm.BodyType != null) {
writer.WriteLine("var content = new Captured@0Content(@1);",
xm.BodyType,
xm.BodyType == "String" ? "data" : string.Format("client.Settings.{0}Serializer.Serialize(data)", xm.BodyType));
xm.BodyType == "String" ? "data" : $"client.Settings.{xm.BodyType}Serializer.Serialize(data)");
}

var client = (xm.ExtentionOfType == "FlurlClient") ? "client" : "new FlurlClient(url, false)";
var client = (xm.ExtentionOfType == "IFlurlClient") ? "client" : "new FlurlClient(url, false)";
var receive = (xm.DeserializeToType == null) ? "" : string.Format(".Receive{0}{1}()", xm.DeserializeToType, xm.IsGeneric ? "<T>" : "");
writer.WriteLine("return @0.SendAsync(@1)@2;", client, string.Join(", ", args), receive);
}
Expand Down
Loading

0 comments on commit a025bf2

Please sign in to comment.