From a47bf223a1e7d2aaca7216c0162ac751ef0626bd Mon Sep 17 00:00:00 2001 From: Dennis Jensen Date: Sun, 27 Aug 2023 10:14:28 +0200 Subject: [PATCH] Project foundation --- .envrc | 1 + .github/workflows/ci.yml | 21 +++ .gitignore | 10 ++ .vscode/settings.json | 3 + apps/EnergyAnalyzer/.config/dotnet-tools.json | 12 ++ .../EnergyAnalyzer.Tests.csproj | 30 ++++ .../EnergyAnalyzer.Tests/UnitTest1.cs | 40 +++++ .../EnergyAnalyzer.Tests/Usings.cs | 1 + .../coverage.opencover.xml | 154 ++++++++++++++++++ apps/EnergyAnalyzer/EnergyAnalyzer.sln | 31 ++++ .../Controllers/WeatherForecastController.cs | 32 ++++ .../EnergyAnalyzer.csproj | 13 ++ .../EnergyAnalyzerWebApp/Program.cs | 23 +++ .../Properties/launchSettings.json | 31 ++++ .../EnergyAnalyzerWebApp/WeatherForecast.cs | 12 ++ .../appsettings.Development.json | 8 + .../EnergyAnalyzerWebApp/appsettings.json | 9 + apps/EnergyAnalyzer/justfile | 8 + shell.nix | 17 ++ 19 files changed, 456 insertions(+) create mode 100644 .envrc create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 apps/EnergyAnalyzer/.config/dotnet-tools.json create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzer.Tests/EnergyAnalyzer.Tests.csproj create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzer.Tests/UnitTest1.cs create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzer.Tests/Usings.cs create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzer.Tests/coverage.opencover.xml create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzer.sln create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Controllers/WeatherForecastController.cs create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzerWebApp/EnergyAnalyzer.csproj create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Program.cs create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Properties/launchSettings.json create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzerWebApp/WeatherForecast.cs create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzerWebApp/appsettings.Development.json create mode 100644 apps/EnergyAnalyzer/EnergyAnalyzerWebApp/appsettings.json create mode 100644 apps/EnergyAnalyzer/justfile create mode 100644 shell.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..1d953f4 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0abce0a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] +jobs: + backend-ci: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Nix + uses: cachix/install-nix-action@v20 + + - name: Load Nix shell + working-directory: ./apps/EnergyAnalyzer + run: nix-shell ../../shell.nix --run "just test" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7899008 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Nix environment +.config + +# C# +bin/ +obj/ + +# Test results +TestResults/ +coveragereport diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b8ca224 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dotnet.defaultSolution": "apps/EnergyAnalyzer/EnergyAnalyzer.sln" +} \ No newline at end of file diff --git a/apps/EnergyAnalyzer/.config/dotnet-tools.json b/apps/EnergyAnalyzer/.config/dotnet-tools.json new file mode 100644 index 0000000..8fa99bf --- /dev/null +++ b/apps/EnergyAnalyzer/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-reportgenerator-globaltool": { + "version": "5.1.24", + "commands": [ + "reportgenerator" + ] + } + } +} \ No newline at end of file diff --git a/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/EnergyAnalyzer.Tests.csproj b/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/EnergyAnalyzer.Tests.csproj new file mode 100644 index 0000000..6c2a00e --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/EnergyAnalyzer.Tests.csproj @@ -0,0 +1,30 @@ + + + + net6.0 + enable + enable + + false + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + diff --git a/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/UnitTest1.cs b/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/UnitTest1.cs new file mode 100644 index 0000000..d6b2a5e --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/UnitTest1.cs @@ -0,0 +1,40 @@ +using System.Linq; +using EnergyAnalyzer.Controllers; +using Microsoft.Extensions.Logging; +using Moq; +using Xunit; + +namespace EnergyAnalyzer.Tests +{ + public class WeatherForecastControllerTests + { + private readonly WeatherForecastController _controller; + private readonly Mock> _loggerMock; + + public WeatherForecastControllerTests() + { + _loggerMock = new Mock>(); + _controller = new WeatherForecastController(_loggerMock.Object); + } + + [Fact] + public void Get_ReturnsWeatherForecasts() + { + // Arrange + // Setup is done in the constructor + + // Act + var result = _controller.Get(); + + // Assert + Assert.NotNull(result); + Assert.Equal(5, result.Count()); + foreach (var forecast in result) + { + Assert.NotNull(forecast); + Assert.True(forecast.TemperatureC >= -20 && forecast.TemperatureC <= 55); + Assert.True(WeatherForecastController.Summaries.Contains(forecast.Summary)); + } + } + } +} diff --git a/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/Usings.cs b/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/Usings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/coverage.opencover.xml b/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/coverage.opencover.xml new file mode 100644 index 0000000..dfeb464 --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzer.Tests/coverage.opencover.xml @@ -0,0 +1,154 @@ + + + + + + EnergyAnalyzer.dll + 2023-08-27T07:35:56 + EnergyAnalyzer + + + + + + + + + Program + + + + + System.Void Program::<Main>$(System.String[]) + + + + + + + + + + + + + + + + + + + + + + + + + + + + EnergyAnalyzer.WeatherForecast + + + + + System.DateTime EnergyAnalyzer.WeatherForecast::get_Date() + + + + + + + + + + + System.Int32 EnergyAnalyzer.WeatherForecast::get_TemperatureC() + + + + + + + + + + + System.Int32 EnergyAnalyzer.WeatherForecast::get_TemperatureF() + + + + + + + + + + + System.String EnergyAnalyzer.WeatherForecast::get_Summary() + + + + + + + + + + + + EnergyAnalyzer.Controllers.WeatherForecastController + + + + + System.Collections.Generic.IEnumerable`1<EnergyAnalyzer.WeatherForecast> EnergyAnalyzer.Controllers.WeatherForecastController::Get() + + + + + + + + + + + + + + + + + + + System.Void EnergyAnalyzer.Controllers.WeatherForecastController::.ctor(Microsoft.Extensions.Logging.ILogger`1<EnergyAnalyzer.Controllers.WeatherForecastController>) + + + + + + + + + + + + + + System.Void EnergyAnalyzer.Controllers.WeatherForecastController::.cctor() + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/EnergyAnalyzer/EnergyAnalyzer.sln b/apps/EnergyAnalyzer/EnergyAnalyzer.sln new file mode 100644 index 0000000..6cf5863 --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzer.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnergyAnalyzer", "EnergyAnalyzer.csproj", "{4CDB4CAE-43F7-4141-AE9B-A5652181A68C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnergyAnalyzer.Tests", "EnergyAnalyzer.Tests\EnergyAnalyzer.Tests.csproj", "{852A3BCD-ADED-47C0-9C97-44DC3ADD842F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4CDB4CAE-43F7-4141-AE9B-A5652181A68C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4CDB4CAE-43F7-4141-AE9B-A5652181A68C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4CDB4CAE-43F7-4141-AE9B-A5652181A68C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4CDB4CAE-43F7-4141-AE9B-A5652181A68C}.Release|Any CPU.Build.0 = Release|Any CPU + {852A3BCD-ADED-47C0-9C97-44DC3ADD842F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {852A3BCD-ADED-47C0-9C97-44DC3ADD842F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {852A3BCD-ADED-47C0-9C97-44DC3ADD842F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {852A3BCD-ADED-47C0-9C97-44DC3ADD842F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {766591C1-0883-4222-BEEF-EF47465A40F6} + EndGlobalSection +EndGlobal diff --git a/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Controllers/WeatherForecastController.cs b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..91f48d2 --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Controllers/WeatherForecastController.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.Mvc; + +namespace EnergyAnalyzer.Controllers; + +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase +{ + public static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } +} diff --git a/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/EnergyAnalyzer.csproj b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/EnergyAnalyzer.csproj new file mode 100644 index 0000000..4289e82 --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/EnergyAnalyzer.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Program.cs b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Program.cs new file mode 100644 index 0000000..a2649f7 --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Program.cs @@ -0,0 +1,23 @@ +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Properties/launchSettings.json b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Properties/launchSettings.json new file mode 100644 index 0000000..5b175c5 --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:52315", + "sslPort": 44375 + } + }, + "profiles": { + "EnergyAnalyzer": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7031;http://localhost:5221", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/WeatherForecast.cs b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/WeatherForecast.cs new file mode 100644 index 0000000..5a24f7a --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/WeatherForecast.cs @@ -0,0 +1,12 @@ +namespace EnergyAnalyzer; + +public class WeatherForecast +{ + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } +} diff --git a/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/appsettings.Development.json b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/appsettings.Development.json new file mode 100644 index 0000000..ff66ba6 --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/appsettings.json b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/appsettings.json new file mode 100644 index 0000000..4d56694 --- /dev/null +++ b/apps/EnergyAnalyzer/EnergyAnalyzerWebApp/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/apps/EnergyAnalyzer/justfile b/apps/EnergyAnalyzer/justfile new file mode 100644 index 0000000..fc0b42e --- /dev/null +++ b/apps/EnergyAnalyzer/justfile @@ -0,0 +1,8 @@ +run-app: + @echo "Running app..." + dotnet run --project EnergyAnalyzerWebApp + +test: + @echo "Running tests..." + rm -rf EnergyAnalyzer.Tests/TestResults + cd EnergyAnalyzer.Tests && dotnet test --collect:"XPlat Code Coverage" --results-directory ./TestResults \ No newline at end of file diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..0879536 --- /dev/null +++ b/shell.nix @@ -0,0 +1,17 @@ +with import { }; + +mkShell { + name = "dotnet-env"; + buildInputs = [ dotnet-sdk ]; + shellHook = '' + # Initialize a local tool manifest if it doesn't exist + if [ ! -f .config/dotnet-tools.json ]; then + dotnet new tool-manifest + fi + + # Install ReportGenerator tool locally if not installed + if ! dotnet tool list --local | grep -q 'dotnet-reportgenerator-globaltool'; then + dotnet tool install dotnet-reportgenerator-globaltool --local + fi + ''; +}