diff --git a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/AspNetCoreHostFixture.cs b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/AspNetCoreHostFixture.cs index 07a9495..6bae8cb 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/AspNetCoreHostFixture.cs +++ b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/AspNetCoreHostFixture.cs @@ -1,8 +1,6 @@ using System; using System.IO; using System.Threading.Tasks; -using Cuemon; -using Cuemon.Collections.Generic; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.StaticWebAssets; @@ -40,8 +38,8 @@ public AspNetCoreHostFixture() /// public override void ConfigureHost(Test hostTest) { - Validator.ThrowIfNull(hostTest); - Validator.ThrowIfNotContainsType(hostTest, Arguments.ToArrayOf(typeof(AspNetCoreHostTest<>)), $"{nameof(hostTest)} is not assignable from AspNetCoreHostTest."); + if (hostTest == null) { throw new ArgumentNullException(nameof(hostTest)); } + if (!HasTypes(hostTest.GetType(), typeof(HostTest<>))) { throw new ArgumentOutOfRangeException(nameof(hostTest), typeof(HostTest<>), $"{nameof(hostTest)} is not assignable from AspNetCoreHostTest."); } var hb = new HostBuilder() .ConfigureWebHost(webBuilder => diff --git a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Codebelt.Extensions.Xunit.Hosting.AspNetCore.csproj b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Codebelt.Extensions.Xunit.Hosting.AspNetCore.csproj index 0de0868..eb1f7ad 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Codebelt.Extensions.Xunit.Hosting.AspNetCore.csproj +++ b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Codebelt.Extensions.Xunit.Hosting.AspNetCore.csproj @@ -23,10 +23,6 @@ - - - - diff --git a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Http/FakeHttpContextAccessor.cs b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Http/FakeHttpContextAccessor.cs index 65437f6..2304910 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Http/FakeHttpContextAccessor.cs +++ b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Http/FakeHttpContextAccessor.cs @@ -2,7 +2,6 @@ using System.IO; using System.Text; using Codebelt.Extensions.Xunit.Hosting.AspNetCore.Http.Features; -using Cuemon; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; @@ -29,15 +28,33 @@ public FakeHttpContextAccessor() private Stream MakeGreeting(string greeting) { - return Patterns.SafeInvoke(() => new MemoryStream(), ms => + Stream interim = null; + Stream result = null; + try { - var sw = new StreamWriter(ms, Encoding.UTF8); - sw.Write(greeting); - sw.Flush(); - ms.Flush(); - ms.Position = 0; - return ms; - }, ex => throw new InvalidOperationException("There is an error in the Stream being written.", ex)); + interim = new MemoryStream(); + + using (var sw = new StreamWriter(interim, Encoding.UTF8, leaveOpen: true)) + { + sw.Write(greeting); + sw.Flush(); + } + + interim.Flush(); + interim.Position = 0; + + result = interim; + interim = null; + } + catch (Exception ex) + { + throw new InvalidOperationException("There is an error in the Stream being written.", ex); + } + finally + { + interim?.Dispose(); + } + return result; } /// diff --git a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/HttpClientExtensions.cs b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/HttpClientExtensions.cs index 8fa9820..272a4a5 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/HttpClientExtensions.cs +++ b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/HttpClientExtensions.cs @@ -1,7 +1,6 @@ using System; using System.Net.Http; using System.Threading.Tasks; -using Cuemon; namespace Codebelt.Extensions.Xunit.Hosting.AspNetCore { @@ -22,7 +21,7 @@ public static class HttpClientExtensions /// Designed to be used in conjunction with and . public static async Task ToHttpResponseMessageAsync(this HttpClient client, Func> responseFactory = null) { - Validator.ThrowIfNull(client); + if (client == null) { throw new ArgumentNullException(nameof(client)); } responseFactory ??= c => c.GetAsync("/"); return await responseFactory(client).ConfigureAwait(false); } diff --git a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Tweaker.cs b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Tweaker.cs new file mode 100644 index 0000000..83e3a7a --- /dev/null +++ b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Tweaker.cs @@ -0,0 +1,12 @@ +using System; + +namespace Codebelt.Extensions.Xunit.Hosting.AspNetCore +{ + internal static class Tweaker + { + internal static T Adjust(T value, Func converter) + { + return converter == null ? value : converter.Invoke(value); + } + } +} diff --git a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/WebHostTest.cs b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/WebHostTest.cs index 71bd836..0d722bf 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/WebHostTest.cs +++ b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/WebHostTest.cs @@ -1,5 +1,4 @@ using System; -using Cuemon; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/src/Codebelt.Extensions.Xunit.Hosting/Codebelt.Extensions.Xunit.Hosting.csproj b/src/Codebelt.Extensions.Xunit.Hosting/Codebelt.Extensions.Xunit.Hosting.csproj index 2fb51d3..d8b4cf5 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting/Codebelt.Extensions.Xunit.Hosting.csproj +++ b/src/Codebelt.Extensions.Xunit.Hosting/Codebelt.Extensions.Xunit.Hosting.csproj @@ -35,7 +35,6 @@ - diff --git a/src/Codebelt.Extensions.Xunit.Hosting/GenericHostTest.cs b/src/Codebelt.Extensions.Xunit.Hosting/GenericHostTest.cs index 074dc4f..9e9cda9 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting/GenericHostTest.cs +++ b/src/Codebelt.Extensions.Xunit.Hosting/GenericHostTest.cs @@ -1,5 +1,4 @@ using System; -using Cuemon; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/src/Codebelt.Extensions.Xunit.Hosting/HostFixture.cs b/src/Codebelt.Extensions.Xunit.Hosting/HostFixture.cs index 572fdac..7b6ac24 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting/HostFixture.cs +++ b/src/Codebelt.Extensions.Xunit.Hosting/HostFixture.cs @@ -1,7 +1,5 @@ using System; using System.IO; -using Cuemon; -using Cuemon.Collections.Generic; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -34,8 +32,8 @@ public HostFixture() /// public virtual void ConfigureHost(Test hostTest) { - Validator.ThrowIfNull(hostTest); - Validator.ThrowIfNotContainsType(hostTest, Arguments.ToArrayOf(typeof(HostTest<>)), $"{nameof(hostTest)} is not assignable from HostTest."); + if (hostTest == null) { throw new ArgumentNullException(nameof(hostTest)); } + if (!HasTypes(hostTest.GetType(), typeof(HostTest<>))) { throw new ArgumentOutOfRangeException(nameof(hostTest), typeof(HostTest<>), $"{nameof(hostTest)} is not assignable from HostTest."); } var hb = new HostBuilder() .UseContentRoot(Directory.GetCurrentDirectory()) @@ -65,6 +63,27 @@ public virtual void ConfigureHost(Test hostTest) Host = hb.Build(); } + /// + /// Determines whether the specified contains one or more of the specified target . + /// + /// The to validate. + /// The target types to be matched against. + /// true if the contains one or more of the specified target types; otherwise, false. + protected static bool HasTypes(Type type, params Type[] types) + { + foreach (var tt in types) + { + var st = type; + while (st != null) + { + if (st.IsGenericType && tt == st.GetGenericTypeDefinition()) { return true; } + if (st == tt) { return true; } + st = st.BaseType; + } + } + return false; + } + #if NETSTANDARD2_0_OR_GREATER /// /// Gets or sets the delegate that initializes the test class. diff --git a/src/Codebelt.Extensions.Xunit.Hosting/HostTest.cs b/src/Codebelt.Extensions.Xunit.Hosting/HostTest.cs index fcc3415..6d4c287 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting/HostTest.cs +++ b/src/Codebelt.Extensions.Xunit.Hosting/HostTest.cs @@ -1,5 +1,4 @@ using System; -using Cuemon; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -25,7 +24,7 @@ public abstract class HostTest : Test, IClassFixture where T : class, IHos /// The of caller that ends up invoking this instance. protected HostTest(T hostFixture, ITestOutputHelper output = null, Type callerType = null) : base(output, callerType) { - Validator.ThrowIfNull(hostFixture); + if (hostFixture == null) { throw new ArgumentNullException(nameof(hostFixture)); } InitializeHostFixture(hostFixture); } diff --git a/src/Codebelt.Extensions.Xunit.Hosting/LoggerExtensions.cs b/src/Codebelt.Extensions.Xunit.Hosting/LoggerExtensions.cs index 90943b9..edfd5aa 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting/LoggerExtensions.cs +++ b/src/Codebelt.Extensions.Xunit.Hosting/LoggerExtensions.cs @@ -1,7 +1,7 @@ using System; using System.Collections; using System.Linq; -using Cuemon; +using System.Reflection; using Microsoft.Extensions.Logging; namespace Codebelt.Extensions.Xunit.Hosting @@ -24,13 +24,13 @@ public static class LoggerExtensions /// public static ITestStore GetTestStore(this ILogger logger) { - Validator.ThrowIfNull(logger); + if (logger == null) { throw new ArgumentNullException(nameof(logger)); } var loggerType = logger.GetType(); - var internalLogger = Decorator.Enclose(loggerType).GetAllFields().SingleOrDefault(fi => fi.Name == "_logger")?.GetValue(logger); + var internalLogger = loggerType.GetRuntimeFields().SingleOrDefault(fi => fi.Name == "_logger")?.GetValue(logger); if (internalLogger != null) { var internalLoggerType = internalLogger.GetType(); - var internalLoggers = Decorator.Enclose(internalLoggerType).GetAllProperties().SingleOrDefault(pi => pi.Name == "Loggers")?.GetValue(internalLogger); + var internalLoggers = internalLoggerType.GetRuntimeProperties().SingleOrDefault(pi => pi.Name == "Loggers")?.GetValue(internalLogger); if (internalLoggers != null) { foreach (var loggerInformation in (IEnumerable)internalLoggers) diff --git a/src/Codebelt.Extensions.Xunit.Hosting/ServiceCollectionExtensions.cs b/src/Codebelt.Extensions.Xunit.Hosting/ServiceCollectionExtensions.cs index 3f6a6ac..ea06662 100644 --- a/src/Codebelt.Extensions.Xunit.Hosting/ServiceCollectionExtensions.cs +++ b/src/Codebelt.Extensions.Xunit.Hosting/ServiceCollectionExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using Cuemon; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Xunit.Abstractions; @@ -25,8 +24,8 @@ public static class ServiceCollectionExtensions /// public static IServiceCollection AddXunitTestLogging(this IServiceCollection services, ITestOutputHelper output, LogLevel minimumLevel = LogLevel.Trace) { - Validator.ThrowIfNull(services); - Validator.ThrowIfNull(output); + if (services == null) { throw new ArgumentNullException(nameof(services)); } + if (output == null) { throw new ArgumentNullException(nameof(output)); } if (services.Any(sd => sd.ServiceType == typeof(ITestOutputHelperAccessor))) { services.AddLogging(builder => @@ -73,7 +72,7 @@ public static IServiceCollection AddXunitTestLoggingOutputHelperAccessor(this IS /// public static IServiceCollection AddXunitTestLoggingOutputHelperAccessor(this IServiceCollection services) where T : class, ITestOutputHelperAccessor { - Validator.ThrowIfNull(services); + if (services == null) { throw new ArgumentNullException(nameof(services)); } services.AddSingleton(); return services; } diff --git a/src/Codebelt.Extensions.Xunit.Hosting/Tweaker.cs b/src/Codebelt.Extensions.Xunit.Hosting/Tweaker.cs new file mode 100644 index 0000000..5e84692 --- /dev/null +++ b/src/Codebelt.Extensions.Xunit.Hosting/Tweaker.cs @@ -0,0 +1,12 @@ +using System; + +namespace Codebelt.Extensions.Xunit.Hosting +{ + internal static class Tweaker + { + internal static T Adjust(T value, Func converter) + { + return converter == null ? value : converter.Invoke(value); + } + } +} diff --git a/src/Codebelt.Extensions.Xunit/Codebelt.Extensions.Xunit.csproj b/src/Codebelt.Extensions.Xunit/Codebelt.Extensions.Xunit.csproj index 24867e4..45e0624 100644 --- a/src/Codebelt.Extensions.Xunit/Codebelt.Extensions.Xunit.csproj +++ b/src/Codebelt.Extensions.Xunit/Codebelt.Extensions.Xunit.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/Codebelt.Extensions.Xunit/DelimitedString.cs b/src/Codebelt.Extensions.Xunit/DelimitedString.cs new file mode 100644 index 0000000..9a54b72 --- /dev/null +++ b/src/Codebelt.Extensions.Xunit/DelimitedString.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Codebelt.Extensions.Xunit +{ + internal static class DelimitedString + { + internal static string Create(IEnumerable source, Action> setup = null) + { + if (source == null) { throw new ArgumentNullException(nameof(source)); } + + var options = new DelimitedStringOptions(); + setup?.Invoke(options); + + var delimitedValues = new StringBuilder(); + using (var enumerator = source.GetEnumerator()) + { + while (enumerator.MoveNext()) + { + delimitedValues.Append(FormattableString.Invariant($"{options.StringConverter(enumerator.Current)}{options.Delimiter}")); + } + } + return delimitedValues.Length > 0 ? delimitedValues.ToString(0, delimitedValues.Length - options.Delimiter.Length) : delimitedValues.ToString(); + } + } +} diff --git a/src/Codebelt.Extensions.Xunit/DelimitedStringOptions.cs b/src/Codebelt.Extensions.Xunit/DelimitedStringOptions.cs new file mode 100644 index 0000000..2cff67b --- /dev/null +++ b/src/Codebelt.Extensions.Xunit/DelimitedStringOptions.cs @@ -0,0 +1,17 @@ +using System; + +namespace Codebelt.Extensions.Xunit +{ + internal class DelimitedStringOptions + { + internal DelimitedStringOptions() + { + Delimiter = ","; + StringConverter = o => o.ToString(); + } + + internal Func StringConverter { get; set; } + + internal string Delimiter { get; set; } + } +} diff --git a/src/Codebelt.Extensions.Xunit/InMemoryTestStore.cs b/src/Codebelt.Extensions.Xunit/InMemoryTestStore.cs index 5f29377..1cb367c 100644 --- a/src/Codebelt.Extensions.Xunit/InMemoryTestStore.cs +++ b/src/Codebelt.Extensions.Xunit/InMemoryTestStore.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Cuemon; namespace Codebelt.Extensions.Xunit { @@ -49,7 +48,9 @@ public void Add(T item) /// An that satisfies the condition. public virtual IEnumerable Query(Func predicate = null) { - return Condition.TernaryIf(predicate == null, () => _store, () => _store.Where(predicate!)); + return predicate == null + ? _store + : _store.Where(predicate!); } /// diff --git a/src/Codebelt.Extensions.Xunit/TestOutputHelperExtensions.cs b/src/Codebelt.Extensions.Xunit/TestOutputHelperExtensions.cs index 7f63461..fdb91a2 100644 --- a/src/Codebelt.Extensions.Xunit/TestOutputHelperExtensions.cs +++ b/src/Codebelt.Extensions.Xunit/TestOutputHelperExtensions.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Cuemon; using Xunit.Abstractions; namespace Codebelt.Extensions.Xunit @@ -21,7 +20,7 @@ public static class TestOutputHelperExtensions /// public static void WriteLines(this ITestOutputHelper helper, params object[] values) { - Validator.ThrowIfNull(helper); + if (helper == null) { throw new ArgumentNullException(nameof(helper)); } helper.WriteLine(DelimitedString.Create(values, o => o.Delimiter = Environment.NewLine)); } @@ -48,7 +47,7 @@ public static void WriteLines(this ITestOutputHelper helper, T[] values) /// public static void WriteLines(this ITestOutputHelper helper, IEnumerable values) { - Validator.ThrowIfNull(helper); + if (helper == null) { throw new ArgumentNullException(nameof(helper)); } helper.WriteLine(DelimitedString.Create(values, o => o.Delimiter = Environment.NewLine)); } }