feat: initial commit

This commit is contained in:
Dylan R. E. Moonfire 2021-09-10 12:12:49 -05:00
commit abecc1f34c
17 changed files with 14125 additions and 0 deletions

122
.editorconfig Normal file
View File

@ -0,0 +1,122 @@
# EditorConfig is awesome: https://EditorConfig.org
root = true
[*]
charset=utf-8
end_of_line = lf
insert_final_newline=true
indent_style=space
indent_size=4
# Microsoft .NET properties
csharp_new_line_before_members_in_object_initializers=false
csharp_preferred_modifier_order=public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion
csharp_space_after_cast=false
csharp_style_var_elsewhere=false:hint
csharp_style_var_for_built_in_types=false:hint
csharp_style_var_when_type_is_apparent=true:hint
csharp_preserve_single_line_statements=false
csharp_preserve_single_line_blocks=true
dotnet_style_predefined_type_for_locals_parameters_members=true:hint
dotnet_style_predefined_type_for_member_access=true:hint
dotnet_style_qualification_for_event=true:hint
dotnet_style_qualification_for_field=true:hint
dotnet_style_qualification_for_method=true:hint
dotnet_style_qualification_for_property=true:hint
dotnet_style_require_accessibility_modifiers=for_non_interface_members:hint
# ReSharper properties
resharper_alignment_tab_fill_style=optimal_fill
resharper_apply_on_completion=true
resharper_blank_lines_after_control_transfer_statements=1
resharper_blank_lines_around_single_line_auto_property=1
resharper_blank_lines_around_single_line_property=1
resharper_blank_lines_before_single_line_comment=1
resharper_blank_lines_between_using_groups=1
resharper_braces_for_for=required
resharper_braces_for_foreach=required
resharper_braces_for_ifelse=required
resharper_braces_for_while=required
resharper_can_use_global_alias=false
resharper_csharp_blank_lines_around_single_line_field=1
resharper_csharp_blank_lines_around_single_line_invocable=1
resharper_csharp_indent_style=tab
resharper_csharp_insert_final_newline=true
resharper_csharp_keep_blank_lines_in_code=1
resharper_csharp_keep_blank_lines_in_declarations=1
resharper_csharp_new_line_before_while=true
resharper_csharp_use_indent_from_vs=false
resharper_csharp_wrap_arguments_style=chop_if_long
resharper_csharp_wrap_extends_list_style=chop_if_long
resharper_csharp_wrap_parameters_style=chop_if_long
resharper_css_insert_final_newline=false
resharper_enforce_line_ending_style=true
resharper_html_insert_final_newline=false
resharper_indent_nested_fixed_stmt=true
resharper_js_indent_style=tab
resharper_js_insert_final_newline=true
resharper_js_keep_blank_lines_in_code=1
resharper_js_stick_comment=false
resharper_js_use_indent_from_vs=false
resharper_js_wrap_before_binary_opsign=true
resharper_js_wrap_chained_method_calls=chop_if_long
resharper_keep_blank_lines_between_declarations=1
resharper_min_blank_lines_after_imports=1
resharper_place_attribute_on_same_line=False
resharper_place_constructor_initializer_on_same_line=false
resharper_place_type_constraints_on_same_line=false
resharper_protobuf_insert_final_newline=false
resharper_qualified_using_at_nested_scope=true
resharper_resx_insert_final_newline=false
resharper_space_within_single_line_array_initializer_braces=true
resharper_use_indents_from_main_language_in_file=false
resharper_vb_insert_final_newline=false
resharper_wrap_after_declaration_lpar=true
resharper_wrap_after_invocation_lpar=true
resharper_wrap_before_extends_colon=true
resharper_wrap_before_first_type_parameter_constraint=true
resharper_wrap_before_type_parameter_langle=true
resharper_xmldoc_indent_child_elements=ZeroIndent
resharper_xmldoc_indent_text=ZeroIndent
resharper_xmldoc_insert_final_newline=false
resharper_xml_insert_final_newline=false
# ReSharper inspection severities
resharper_check_namespace_highlighting=none
resharper_convert_to_auto_property_highlighting=none
resharper_localizable_element_highlighting=none
resharper_redundant_comma_in_attribute_list_highlighting=none
resharper_redundant_comma_in_enum_declaration_highlighting=none
resharper_redundant_comma_in_initializer_highlighting=none
resharper_string_compare_to_is_culture_specific_highlighting=none
resharper_string_index_of_is_culture_specific_1_highlighting=none
resharper_use_null_propagation_highlighting=none
resharper_use_object_or_collection_initializer_highlighting=hint
resharper_use_string_interpolation_highlighting=hint
# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style=space
indent_size=2
tab_width=2
[*.{cs,js,json,jsx,proto,resjson,ts,tsx}]
indent_style=space
indent_size=space
tab_width=4
[*.{asax,ascx,aspx,cshtml,css,htm,html,master,razor,skin,vb,xaml,xamlx,xoml}]
indent_style=space
indent_size=4
tab_width=4
[*.{appxmanifest,build,config,csproj,dbml,discomap,dtd,jsproj,lsproj,njsproj,nuspec,proj,props,resw,resx,StyleCop,targets,tasks,vbproj,xml,xsd}]
indent_style=space
indent_size=2
tab_width=2
[*.proto]
indent_style=space
indent_size=2
tab_width=2

1
.envrc Normal file
View File

@ -0,0 +1 @@
use asdf

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
launchSettings.json
*~
*.user
Directory.Build.props
obj/
[Bb]in/
.vs/
.vscode/
.idea/
_ReSharper.Caches/
node_modules/

51
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,51 @@
stages:
- build
default:
before_script:
- curl -sL https://deb.nodesource.com/setup_15.x | bash -
- apt-get install -y nodejs
build:
image: mcr.microsoft.com/dotnet/sdk:5.0
stage: build
script:
# Set up the environment.
- npx npm install --ci
- npx commitlint-gitlab-ci -x @commitlint/config-conventional
# Build and test everything.
- dotnet restore
- dotnet build
#- 'dotnet test --test-adapter-path:. --logger:"junit;LogFilePath=../artifacts/{assembly}-test-result.xml;MethodFormat=Default;FailureBodyFormat=Verbose" --collect:"XPlat Code Coverage"'
# Summarize the output for Gitlab CI reporting.
#- dotnet new tool-manifest
#- dotnet tool install dotnet-reportgenerator-globaltool
#- dotnet tool run reportgenerator -reports:src/*/TestResults/*/coverage.cobertura.xml -targetdir:./coverage "-reporttypes:Cobertura;TextSummary"
#- grep "Line coverage" coverage/Summary.txt
# Perform the release.
- npx semantic-release
rules:
- if: '$CI_COMMIT_TITLE =~ /^chore\(release\)/'
when: never
- if: '$CI_COMMIT_TAG'
when: never
- if: '$CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH'
when: never
- when: on_success
artifacts:
when: always
paths:
- ./**/*test-result.xml
- ./coverage/Cobertura.xml
- ./coverage/Summary.*
- ./**/*.nupkg
reports:
junit:
- ./**/*test-result.xml
cobertura:
- ./coverage/Cobertura.xml

4
.husky/commit-msg Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit $1

3
.tool-versions Normal file
View File

@ -0,0 +1,3 @@
dotnet-core 5.0.100
yarn 1.22.10
nodejs 15.0.1

21
LICENSE.txt Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) Moonfire Games
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

39
MfGames.TestSetup.sln Normal file
View File

@ -0,0 +1,39 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{17AB519F-FBB8-4241-ADE3-CB26CDA54C7F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.TestSetup", "src\MfGames.TestSetup\MfGames.TestSetup.csproj", "{C495F559-A498-4E2E-B700-130E67690AFC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C495F559-A498-4E2E-B700-130E67690AFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Debug|x64.ActiveCfg = Debug|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Debug|x64.Build.0 = Debug|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Debug|x86.ActiveCfg = Debug|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Debug|x86.Build.0 = Debug|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Release|Any CPU.Build.0 = Release|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Release|x64.ActiveCfg = Release|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Release|x64.Build.0 = Release|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Release|x86.ActiveCfg = Release|Any CPU
{C495F559-A498-4E2E-B700-130E67690AFC}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C495F559-A498-4E2E-B700-130E67690AFC} = {17AB519F-FBB8-4241-ADE3-CB26CDA54C7F}
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load Diff

4
README.md Normal file
View File

@ -0,0 +1,4 @@
MfGames.TestSetup
=================
An opininated setup for unit tests using Xunit, Autofac, and Serilog.

3
commitlint.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
extends: ["@commitlint/config-conventional"],
};

12304
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

21
package.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "mfgames-testsetup",
"version": "1.0.0",
"private": true,
"scripts": {
"prepare": "husky install"
},
"devDependencies": {
"@commitlint/cli": "^13.1.0",
"@commitlint/config-conventional": "^13.1.0",
"@semantic-release/changelog": "^5.0.1",
"@semantic-release/git": "^9.0.0",
"@semantic-release/gitlab": "^6.2.2",
"@semantic-release/npm": "^7.1.3",
"commitlint-gitlab-ci": "^0.0.4",
"husky": "^7.0.2",
"semantic-release": "^17.4.7",
"semantic-release-dotnet": "^1.0.0",
"semantic-release-nuget": "^1.1.0"
}
}

20
release.config.js Normal file
View File

@ -0,0 +1,20 @@
module.exports = {
branches: ["main"],
message: "chore(release): v${nextRelease.version}\n\n${nextRelease.notes}",
plugins: [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"semantic-release-dotnet",
[
"semantic-release-nuget",
{
packArguments: ["--include-symbols", "--include-source"],
pushFiles: ["src/*/bin/Debug/*.nupkg"],
},
],
"@semantic-release/changelog",
"@semantic-release/git",
"@semantic-release/gitlab",
],
};

View File

@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="Roslynator.Analyzers" Version="3.2.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="1.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="1.2.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Enrichers.Demystifier" Version="1.0.1" />
<PackageReference Include="Serilog.Exceptions" Version="7.0.0" />
<PackageReference Include="Serilog.Extensions.Autofac.DependencyInjection" Version="4.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.1.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="SerilogAnalyzer" Version="0.15.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>
</Project>

View File

@ -0,0 +1,46 @@
using Serilog;
using Serilog.Core;
using Serilog.Events;
using Serilog.Exceptions;
using Xunit.Abstractions;
namespace MfGames.TestSetup
{
/// <summary>
/// Sets up a test that uses Serilog for logging, Autofac as container
/// resolution, and other common configuration elements.
/// </summary>
public abstract class TestBase<TContext>
where TContext : TestContext, new()
{
protected TestBase(ITestOutputHelper output)
{
// Set up the logging output.
this.Output = output;
this.Logger = new LoggerConfiguration()
.Enrich.WithDemystifiedStackTraces()
.Enrich.WithExceptionDetails()
.Enrich.FromLogContext()
.MinimumLevel.Is(LogEventLevel.Debug)
.WriteTo.Console(
outputTemplate:
"[{Level:u3}] {Message}{NewLine}{Exception}")
.CreateLogger();
}
protected Logger Logger { get; }
protected ITestOutputHelper Output { get; }
protected virtual TContext CreateContext()
{
var context = new TContext();
context.SetLogger(this.Logger);
context.ConfigureContainer();
return context;
}
}
}

View File

@ -0,0 +1,69 @@
using System;
using Autofac;
using Serilog;
namespace MfGames.TestSetup
{
/// <summary>
/// A context for the test run that includes the container.
/// </summary>
public class TestContext : IDisposable
{
private IContainer? container;
private ILogger? logger;
public IContainer Container
{
get => this.container
?? throw new NullReferenceException(
"ConfigureContainer has not been called.");
private set => this.container = value;
}
public ILogger Logger
{
get => this.logger
?? throw new NullReferenceException(
"SetLogger has not been called.");
private set => this.logger = value;
}
public void ConfigureContainer()
{
var builder = new ContainerBuilder();
builder
.RegisterInstance(this.Logger)
.As<ILogger>()
.SingleInstance();
this.ConfigureContainer(builder);
this.Container = builder.Build();
}
/// <inheritdoc />
public void Dispose()
{
this.container?.Dispose();
}
public TType Resolve<TType>()
where TType : class
{
return this.Container.Resolve<TType>();
}
public void SetLogger(ILogger value)
{
this.Logger = value;
}
protected virtual void ConfigureContainer(ContainerBuilder builder)
{
}
}
}