Skip to content

Commit

Permalink
Add MicrosoftExtensions.Logging.Xunit
Browse files Browse the repository at this point in the history
  • Loading branch information
hcoona committed Sep 16, 2019
1 parent 2a2cca3 commit c47df89
Show file tree
Hide file tree
Showing 9 changed files with 446 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// <copyright file="AuthenticationServiceTests.cs" company="Shuai Zhang">
// Copyright Shuai Zhang. All rights reserved.
// Licensed under the GPLv3 license. See LICENSE file in the project root for full license information.
// </copyright>

using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace GeothermalResearchInstitute.ServerConsole.UnitTest
{
[TestClass]
public class AuthenticationServiceTests
{
private IHost Host { get; set; }

[ClassInitialize]
public void Init()
{
this.Host = new HostBuilder()
.ConfigureHostConfiguration(builder =>
{
builder.AddInMemoryCollection(new Dictionary<string, string>
{
{ "Environment", "UnitTest" },
});
})
.ConfigureAppConfiguration(builder =>
{

})
.ConfigureLogging(builder =>
{
})
.Build();
}

[ClassCleanup]
public void Cleanup()
{
this.Host.StopAsync().GetAwaiter().GetResult();
this.Host.Dispose();
this.Host = null;
}

[TestMethod]
public void TestMethod1()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>$(NetcoreCurrentTargetFramework)</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GeothermalResearchInstitute.ServerConsole\GeothermalResearchInstitute.ServerConsole.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>$(NetcoreCurrentTargetFramework)</TargetFramework>

<IsPackable>false</IsPackable>

<RootNamespace>Microsoft.Extensions.Logging.Xunit.Tests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MicrosoftExtensions.Logging.Xunit\MicrosoftExtensions.Logging.Xunit.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// <copyright file="UnitTest1.cs" company="Shuai Zhang">
// Copyright Shuai Zhang. All rights reserved.
// Licensed under the GPLv3 license. See LICENSE file in the project root for full license information.
// </copyright>

using System;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.Extensions.Logging.Xunit.Tests
{
public class UnitTest1 : IDisposable
{
private readonly LoggerFactory loggerFactory;
private readonly bool disposed = false;

public UnitTest1(ITestOutputHelper testOutputHelper)
{
this.loggerFactory = new LoggerFactory(new[] { new XunitLoggerProvider(testOutputHelper) });
}

~UnitTest1()
{
this.Dispose(false);
}

[Fact]
public void Test1()
{
var logger = this.loggerFactory.CreateLogger("Test1");
logger.LogInformation("Hello World!");
logger = this.loggerFactory.CreateLogger<UnitTest1>();
logger.LogInformation("Hello World!");
}

public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing && !this.disposed)
{
this.loggerFactory.Dispose();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(DefaultLibraryTargetFrameworks)</TargetFrameworks>
<RootNamespace>Microsoft.Extensions.Logging.Xunit</RootNamespace>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions">
<Version>1.1.2</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' != 'net45'">
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions">
<Version>2.2.0</Version>
</PackageReference>
</ItemGroup>

<ItemGroup>
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// <copyright file="XunitLogger.cs" company="Shuai Zhang">
// Copyright Shuai Zhang. All rights reserved.
// Licensed under the GPLv3 license. See LICENSE file in the project root for full license information.
// </copyright>

using System;
using System.Text;
using Microsoft.Extensions.Logging.Abstractions.Internal;
using Xunit.Abstractions;

namespace Microsoft.Extensions.Logging.Xunit
{
public class XunitLogger : ILogger
{
private const string LoglevelPadding = ": ";

private static readonly string MessagePadding = new string(
' ',
GetLogLevelString(LogLevel.Information).Length + LoglevelPadding.Length);

private static readonly string NewLineWithMessagePadding = Environment.NewLine + MessagePadding;

[ThreadStatic]
private static StringBuilder logBuilder;

private readonly ITestOutputHelper testOutputHelper;

public XunitLogger(ITestOutputHelper testOutputHelper, string name)
{
this.testOutputHelper = testOutputHelper;

this.Name = name;
}

public string Name { get; }

public IDisposable BeginScope<TState>(TState state)
{
return NullScope.Instance;
}

public bool IsEnabled(LogLevel logLevel) => true;

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (formatter == null)
{
throw new ArgumentNullException(nameof(formatter));
}

var message = formatter(state, exception);

if (!string.IsNullOrEmpty(message) || exception != null)
{
this.WriteMessage(logLevel, this.Name, eventId.Id, message, exception);
}
}

public virtual void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception exception)
{
var logBuilder = XunitLogger.logBuilder;
XunitLogger.logBuilder = null;

if (logBuilder == null)
{
logBuilder = new StringBuilder();
}

// Example:
// INFO: ConsoleApp.Program[10]
// Request received
var logLevelString = GetLogLevelString(logLevel);

// category and event id
logBuilder.Append(LoglevelPadding);
logBuilder.Append(logName);
logBuilder.Append("[");
logBuilder.Append(eventId);
logBuilder.AppendLine("]");

if (!string.IsNullOrEmpty(message))
{
// message
logBuilder.Append(MessagePadding);

var len = logBuilder.Length;
logBuilder.AppendLine(message);
logBuilder.Replace(Environment.NewLine, NewLineWithMessagePadding, len, message.Length);
}

// Example:
// System.InvalidOperationException
// at Namespace.Class.Function() in File:line X
if (exception != null)
{
// exception message
logBuilder.AppendLine(exception.ToString());
}

if (logBuilder.Length > 0)
{
var hasLevel = !string.IsNullOrEmpty(logLevelString);

// Queue log message
if (hasLevel)
{
this.testOutputHelper.WriteLine(logLevelString + logBuilder.ToString().TrimEnd());
}
else
{
this.testOutputHelper.WriteLine(logBuilder.ToString().TrimEnd());
}
}

logBuilder.Clear();
if (logBuilder.Capacity > 1024)
{
logBuilder.Capacity = 1024;
}

XunitLogger.logBuilder = logBuilder;
}

private static string GetLogLevelString(LogLevel logLevel)
{
switch (logLevel)
{
case LogLevel.Trace:
return "trce";
case LogLevel.Debug:
return "dbug";
case LogLevel.Information:
return "info";
case LogLevel.Warning:
return "warn";
case LogLevel.Error:
return "fail";
case LogLevel.Critical:
return "crit";
default:
throw new ArgumentOutOfRangeException(nameof(logLevel));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// <copyright file="XunitLoggerProvider.cs" company="Shuai Zhang">
// Copyright Shuai Zhang. All rights reserved.
// Licensed under the GPLv3 license. See LICENSE file in the project root for full license information.
// </copyright>

using Xunit.Abstractions;

namespace Microsoft.Extensions.Logging.Xunit
{
public sealed class XunitLoggerProvider : ILoggerProvider
{
private readonly ITestOutputHelper testOutputHelper;

public XunitLoggerProvider(ITestOutputHelper testOutputHelper)
{
this.testOutputHelper = testOutputHelper;
}

public ILogger CreateLogger(string categoryName) =>
new XunitLogger(this.testOutputHelper, categoryName);

public void Dispose()
{
}
}
}
28 changes: 28 additions & 0 deletions MicrosoftExtensions/Logging/Xunit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# MicrosoftExtensions.Logging.Xunit #

This C# project provide microsoft extensions style logger to help capture messages in xUnit.

## Getting Started ##

```csharp
public class UnitTest1
{
private readonly ITestOutputHelper testOutputHelper;
private readonly LoggerFactory loggerFactory;

public UnitTest1(ITestOutputHelper testOutputHelper)
{
this.testOutputHelper = testOutputHelper;
this.loggerFactory = new LoggerFactory(new[] { new XunitLoggerProvider(testOutputHelper) });
}

[Fact]
public void Test1()
{
var logger = loggerFactory.CreateLogger("Test1");
logger.LogInformation("Hello World!");
logger = loggerFactory.CreateLogger<UnitTest1>();
logger.LogInformation("Hello World!");
}
}
```
Loading

0 comments on commit c47df89

Please sign in to comment.