Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
Commit 66d7766c authored by Edouard Mangel's avatar Edouard Mangel
Browse files

Fin du live coding

parent 337def10
No related branches found
No related tags found
1 merge request!1Master
Showing
with 226 additions and 22 deletions
namespace Domain;
public class CreditComputer
{
public static decimal ComputeMonthlyPayment(int duration, decimal amount, decimal rate)
{
decimal monthlyRate = rate / 100 / 12;
decimal numerator = amount * monthlyRate;
double denominator = 1 - Math.Pow((double)(1 + monthlyRate), -(double)duration);
return Math.Round(numerator / (decimal)denominator, 2, MidpointRounding.ToZero);
}
}
\ No newline at end of file
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Domain;
public record CreditDurationInMonth
{
public CreditDurationInMonth(int value)
{
if (value < 108 || value > 300) throw new ArgumentOutOfRangeException("value");
this.value = value;
}
public CreditDurationInMonth(string input)
{
try
{
value = Convert.ToInt32(input);
if (value < 0)
throw new Exception();
} catch
{
throw new ArgumentException("input must be strictly positive integer");
}
}
public int value { get; init; }
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
......
namespace Domain;
public interface IClock
{
public DateTime Now { get; }
}
\ No newline at end of file
namespace Domain;
public interface IFileSystem
{
public void SaveResult(decimal monthlyPayment, string fileName);
public decimal GetInfoFromFile(string fileName);
}
\ No newline at end of file
namespace Domain;
public class ScheduleGenerator
{
private IFileSystem _fileSystemFake { get; }
private IClock _clock { get; }
public ScheduleGenerator(IFileSystem fileSystemFake, IClock clock)
{
_fileSystemFake = fileSystemFake;
_clock = clock;
}
public string generateSchedule(CreditDurationInMonth durationInMonth, decimal amount, decimal rate)
{
_fileSystemFake.SaveResult(CreditComputer.ComputeMonthlyPayment(durationInMonth.value, amount, rate), _clock.Now.ToShortDateString());
return _clock.Now.ToShortDateString();
}
}
\ No newline at end of file
namespace LiveCodingTP3.Tests;
using Domain;
using LiveCodingTP3.Console;
public class CreditComputerTest
{
[Theory]
[InlineData(120, 100000, 2d, 920.13)]
[InlineData(120, 100000, 4d, 1012.45)]
[InlineData(240, 200000, 3d, 1109.19)]
public void MonthlyamountShouldBeOk(int duration, decimal amount, decimal rate, decimal expectedMonthlyPayment)
{
decimal monthlyAmount = CreditComputer.ComputeMonthlyPayment(duration, amount, rate);
Assert.Equal(expectedMonthlyPayment, monthlyAmount);
}
}
\ No newline at end of file
using Domain;
namespace LiveCodingTP3.Tests.Fixtures;
public class FakeClock : IClock
{
private readonly DateTime fakeDateTime;
public FakeClock(DateTime fakeDateTime)
{
this.fakeDateTime = fakeDateTime;
}
public DateTime Now => fakeDateTime;
}
\ No newline at end of file
using Domain;
namespace LiveCodingTP3.Tests.Fixtures;
public class FileSystemFake : IFileSystem
{
public Dictionary<string, decimal> keyValuePairs { get; private set; } = new();
public decimal GetInfoFromFile(string fileName)
{
return keyValuePairs[fileName];
}
public void SaveResult(decimal monthlyPayment, string fileName)
{
keyValuePairs[fileName] = monthlyPayment;
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="xunit" Version="2.4.2" /> <PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5"> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\LiveCodingTP3\LiveCodingTP3.csproj" /> <ProjectReference Include="..\LiveCodingTP3\LiveCodingTP3.Console.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Domain;
using LiveCodingTP3.Console;
using LiveCodingTP3.Tests.Fixtures;
namespace LiveCodingTP3.Tests;
public class ScheduleGeneratorTest
{
[Theory]
[InlineData(120, 100000, 2d, 920.13)]
[InlineData(120, 100000, 4d, 1012.45)]
[InlineData(240, 200000, 3d, 1109.19)]
public void ShouldPersistMonthlyPaymentProperly(int duration, decimal amount, decimal rate, decimal expectedMonthlyPayment)
{
// Arrange
var fakeFileSystem = new FileSystemFake();
var sut = new ScheduleGenerator(fakeFileSystem, new FakeClock(DateTime.Now));
// Act
var fileName = sut.generateSchedule(new CreditDurationInMonth(duration), amount, rate);
// Assert
Assert.Equal(expectedMonthlyPayment, fakeFileSystem.GetInfoFromFile(fileName));
}
}
namespace LiveCodingTP3.Tests; namespace LiveCodingTP3.Tests;
using LiveCodingTP3.Console;
public class UserInputsTests public class UserInputsTests
{ {
[Fact] [Theory]
public void UserInput_ValidArgs_ArgsSet() [InlineData("108","100000", "4,1", 108, 100000, 4.1d)]
[InlineData("300","200000", "1,5", 300,200000, 1.5d)]
public void UserInput_ValidArgs_ArgsSet(string durationInMonths, string amount, string nomimalRate,
int expectedDuration, int expectedAmount, decimal expectedRate)
{ {
string durationInMonths = "108";
string amount = "100000";
string nomimalRate = "4,1";
string[] args = { durationInMonths, amount, nomimalRate }; string[] args = { durationInMonths, amount, nomimalRate };
var inputs = new UserInputs(args); var inputs = new UserInputs(args);
Assert.Equal(108, inputs.durationInMonths); Assert.Equal(expectedDuration, inputs.durationInMonths.value);
Assert.Equal(100000, inputs.amount); Assert.Equal(expectedAmount, inputs.amount);
Assert.Equal(4.1M, inputs.nomimalRate); Assert.Equal(expectedRate, inputs.nomimalRate);
}
[Fact]
public void UserInput_InvalidArgs_ThrowsException()
{
string durationInMonths = "-108";
string amount = "100000";
string nomimalRate = "4,1";
string[] args = { durationInMonths, amount, nomimalRate };
Assert.Throws<ArgumentException>(() => new UserInputs(args));
} }
} }
\ No newline at end of file
...@@ -3,10 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00 ...@@ -3,10 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.8.34511.84 VisualStudioVersion = 17.8.34511.84
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiveCodingTP3", "LiveCodingTP3\LiveCodingTP3.csproj", "{91C89BAE-5D26-4DF2-B30D-330408557A2D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiveCodingTP3.Console", "LiveCodingTP3\LiveCodingTP3.Console.csproj", "{91C89BAE-5D26-4DF2-B30D-330408557A2D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiveCodingTP3.Tests", "LiveCodingTP3.Tests\LiveCodingTP3.Tests.csproj", "{48159523-69C6-45D3-BD19-69C186D4897A}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiveCodingTP3.Tests", "LiveCodingTP3.Tests\LiveCodingTP3.Tests.csproj", "{48159523-69C6-45D3-BD19-69C186D4897A}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Domain", "Domain\Domain.csproj", "{EBB06A78-5FDD-4E85-A3B3-209BD16C17D3}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
...@@ -21,6 +23,10 @@ Global ...@@ -21,6 +23,10 @@ Global
{48159523-69C6-45D3-BD19-69C186D4897A}.Debug|Any CPU.Build.0 = Debug|Any CPU {48159523-69C6-45D3-BD19-69C186D4897A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48159523-69C6-45D3-BD19-69C186D4897A}.Release|Any CPU.ActiveCfg = Release|Any CPU {48159523-69C6-45D3-BD19-69C186D4897A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48159523-69C6-45D3-BD19-69C186D4897A}.Release|Any CPU.Build.0 = Release|Any CPU {48159523-69C6-45D3-BD19-69C186D4897A}.Release|Any CPU.Build.0 = Release|Any CPU
{EBB06A78-5FDD-4E85-A3B3-209BD16C17D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EBB06A78-5FDD-4E85-A3B3-209BD16C17D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EBB06A78-5FDD-4E85-A3B3-209BD16C17D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EBB06A78-5FDD-4E85-A3B3-209BD16C17D3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
......
<SolutionConfiguration>
<Settings>
<AllowParallelTestExecution>True</AllowParallelTestExecution>
<SolutionConfigured>True</SolutionConfigured>
</Settings>
</SolutionConfiguration>
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Domain\Domain.csproj" />
</ItemGroup>
</Project>
namespace LiveCodingTP3; 
using LiveCodingTP3.Console;
internal class Program public class Program
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
Console.WriteLine("Hello, World!"); var inputs = new UserInputs(args);
Console.WriteLine($"Duration : {inputs.durationInMonths.value}");
Console.WriteLine($"Amount : {inputs.amount}");
Console.WriteLine($"Rate : {inputs.nomimalRate}");
} }
} }
namespace LiveCodingTP3.Tests; using Domain;
internal class UserInputs namespace LiveCodingTP3.Console;
public class UserInputs
{ {
public readonly int durationInMonths; public readonly CreditDurationInMonth durationInMonths;
public readonly decimal amount; public readonly decimal amount;
public readonly decimal nomimalRate; public readonly decimal nomimalRate;
public UserInputs(string[] args): this(args[0], args[1], args[2]) public UserInputs(string[] args) : this(args[0], args[1], args[2])
{ } { }
public UserInputs(string durationInMonths, string amount, string nomimalRate) public UserInputs(string durationInMonths, string amount, string nomimalRate)
{ {
this.durationInMonths = Convert.ToInt32(durationInMonths); this.durationInMonths = new CreditDurationInMonth(durationInMonths);
this.amount = Convert.ToDecimal(amount); this.amount = Convert.ToDecimal(amount);
this.nomimalRate = Convert.ToDecimal(nomimalRate); this.nomimalRate = Convert.ToDecimal(nomimalRate);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment