Initial commit

This commit is contained in:
github-classroom[bot] 2025-02-25 16:59:47 +00:00 committed by GitHub
commit 67196c7395
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 4693 additions and 0 deletions

3553
.editorconfig Normal file

File diff suppressed because it is too large Load diff

583
.gitignore vendored Normal file
View file

@ -0,0 +1,583 @@
# Created by https://www.toptal.com/developers/gitignore/api/csharp,visualstudio
# Edit at https://www.toptal.com/developers/gitignore?templates=csharp,visualstudio
### Csharp ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
### VisualStudio ###
# User-specific files
# User-specific files (MonoDevelop/Xamarin Studio)
# Mono auto generated files
# Build results
# Visual Studio 2015/2017 cache/options directory
# Uncomment if you have tasks that create the project's static files in wwwroot
# Visual Studio 2017 auto generated files
# MSTest test Results
# NUnit
# Build Results of an ATL Project
# Benchmark Results
# .NET Core
# ASP.NET Scaffolding
# StyleCop
# Files built by Visual Studio
# Chutzpah Test files
# Visual C++ cache files
# Visual Studio profiler
# Visual Studio Trace Files
# TFS 2012 Local Workspace
# Guidance Automation Toolkit
# ReSharper is a .NET coding add-in
# TeamCity is a build add-in
# DotCover is a Code Coverage Tool
# AxoCover is a Code Coverage Tool
# Coverlet is a free, cross platform Code Coverage Tool
# Visual Studio code coverage results
# NCrunch
# MightyMoose
# Web workbench (sass)
# Installshield output folder
# DocProject is a documentation generator add-in
# Click-Once directory
# Publish Web Output
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
# NuGet Packages
# NuGet Symbol Packages
# The packages folder can be ignored because of Package Restore
# except build/, which is used as an MSBuild target.
# Uncomment if necessary however generally it will be regenerated when needed
# NuGet v3's project.json files produces more ignorable files
# Microsoft Azure Build Output
# Microsoft Azure Emulator
# Windows Store app package directories and files
# Visual Studio cache files
# files ending in .cache can be ignored
# but keep track of directories ending in .cache
# Others
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
# RIA/Silverlight projects
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
# SQL Server files
# Business Intelligence projects
# Microsoft Fakes
# GhostDoc plugin setting file
# Node.js Tools for Visual Studio
# Visual Studio 6 build log
# Visual Studio 6 workspace options file
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
# Visual Studio 6 technical files
# Visual Studio LightSwitch build output
# Paket dependency manager
# FAKE - F# Make
# CodeRush personal settings
# Python Tools for Visual Studio (PTVS)
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
# Telerik's JustMock configuration file
# BizTalk build output
# OpenCover UI analysis results
# Azure Stream Analytics local run output
# MSBuild Binary and Structured Log
# NVidia Nsight GPU debugger configuration file
# MFractors (Xamarin productivity tool) working folder
# Local History for Visual Studio
# Visual Studio History (VSHistory) files
# BeatPulse healthcheck temp database
# Backup folder for Package Reference Convert tool in Visual Studio 2017
# Ionide (cross platform F# VS Code tools) working folder
# Fody - auto-generated XML schema
# VS Code files for those working on multiple tools
# Local History for Visual Studio Code
# Windows Installer files from build outputs
# JetBrains Rider
### VisualStudio Patch ###
# Additional files built by Visual Studio
# End of https://www.toptal.com/developers/gitignore/api/csharp,visualstudio

View file

@ -0,0 +1,65 @@
namespace PetsAndFleas.Test;
public sealed class CatTests
{
/*
private readonly Cat _cat = new();
[Fact]
public void ClimbOnTree_Simple()
{
_cat.TreesClimbed.Should().Be(0, "no trees climbed yet");
_cat.ClimbOnTree().Should().BeTrue("was not on tree, could climb");
_cat.TreesClimbed.Should().Be(1, "1 tree climbed");
}
[Fact]
public void ClimbOnTree_AlreadyOnTree()
{
_cat.TreesClimbed.Should().Be(0, "no trees climbed yet");
_cat.ClimbOnTree().Should().BeTrue("was not on tree, could climb");
_cat.ClimbOnTree().Should().BeFalse("already on tree");
_cat.TreesClimbed.Should().Be(1, "1 tree climbed");
}
[Fact]
public void ClimbDown_NotOnTree()
{
_cat.ClimbDown()
.Should().BeFalse("was not on tree, cannot climb down");
}
[Fact]
public void ClimbDown_OnTree()
{
_cat.ClimbOnTree();
_cat.ClimbDown()
.Should().BeTrue("was on tree, could climb down");
}
[Fact]
public void ClimbOnTreeAndDown_Simple()
{
_cat.TreesClimbed.Should().Be(0, "no trees climbed yet");
_cat.ClimbOnTree().Should().BeTrue("was not on tree, could climb");
_cat.ClimbDown().Should().BeTrue("was on tree, could climb down");
_cat.TreesClimbed.Should().Be(1, "1 tree climbed");
}
[Fact]
public void ClimbOnTreeAndDown_Multiple()
{
_cat.TreesClimbed.Should().Be(0, "no trees climbed yet");
_cat.ClimbOnTree();
_cat.ClimbDown();
_cat.ClimbOnTree();
_cat.ClimbDown();
_cat.TreesClimbed.Should().Be(2, "two trees climbed");
}
[Fact]
public void StringRepresentation() => new Cat().ToString().Should().Be("I'm a cat");
*/
}

View file

@ -0,0 +1,56 @@
namespace PetsAndFleas.Test;
public sealed class DogTests
{
/*
private readonly Dog _dog = new(new DateTimeProvider());
[Fact]
public void Construction()
{
_dog.HuntedAnimals.Should().Be(0, "no animals hunted yet");
_dog.RemainingBites.Should().Be(100, "set by Pet ctor");
}
[Fact]
public void HuntAnimal_Simple()
{
_dog.HuntAnimal().Should().BeTrue("has never hunted, can hunt immediately");
_dog.HuntedAnimals.Should().Be(1, "hunted one time");
}
[Fact]
public void HuntAnimal_Wait()
{
_dog.HuntAnimal().Should().BeTrue();
_dog.HuntAnimal().Should().BeFalse("cannot hunt again right away, has to wait and recover");
_dog.HuntedAnimals.Should().Be(1, "only hunted once");
}
[Fact]
public void HuntAnimal_Waited()
{
var dtp = new DateTimeProvider();
var time1 = new DateTime(2023, 02, 27, 18, 30, 00);
var time2 = new DateTime(2023, 02, 27, 18, 30, 46);
var time3 = new DateTime(2023, 02, 27, 18, 31, 10);
var dog = new Dog(dtp);
dtp.Now = time1;
dog.HuntAnimal().Should().BeTrue("can hunt");
dog.HuntedAnimals.Should().Be(1);
dtp.Now = time2;
dog.HuntAnimal().Should().BeFalse("cannot hunt again, has to wait 1 minute");
dog.HuntedAnimals.Should().Be(1);
dtp.Now = time3;
dog.HuntAnimal().Should().BeTrue("enough time has passed, can hunt again");
dog.HuntedAnimals.Should().Be(2);
}
[Fact]
public void StringRepresentation() => _dog.ToString().Should().Be("I'm a dog");
*/
}

View file

@ -0,0 +1,122 @@
namespace PetsAndFleas.Test;
public sealed class FleaTests
{
/*
private readonly Flea _flea = new();
[Fact]
public void JumpOnPet()
{
Pet pet = new Cat();
_flea.CurrentPet.Should().BeNull("did not yet jump on a pet");
_flea.JumpOnPet(pet);
_flea.CurrentPet.Should().NotBeNull().And.BeSameAs(pet);
_flea.TotalBites.Should().Be(0, "no bites yet");
}
[Fact]
public void JumpOnPet_Leave()
{
Pet pet = new Cat();
_flea.JumpOnPet(pet);
_flea.CurrentPet.Should().NotBeNull().And.BeSameAs(pet);
_flea.JumpOnPet(null);
_flea.CurrentPet.Should().BeNull("flea left pet");
}
[Fact]
public void BitePet_Simple()
{
const int BiteAmount = 15;
Pet pet = new Dog(new DateTimeProvider());
_flea.JumpOnPet(pet);
_flea.BitePet(BiteAmount)
.Should().Be(BiteAmount, "flea sits on pet and pet has sufficient 'free bites'");
_flea.TotalBites.Should().Be(BiteAmount);
pet.RemainingBites.Should().Be(85, "100 - 15 = 85");
}
[Fact]
public void BitePet_NoPet()
{
_flea.BitePet(10).Should().Be(0, "flea not sitting on a pet");
}
[Fact]
public void BitePet_NegativeBites()
{
Pet pet = new Cat();
_flea.JumpOnPet(pet);
_flea.BitePet(-10)
.Should().Be(0, "negative bites are not executed");
_flea.TotalBites.Should().Be(0, "no bites performed");
pet.RemainingBites.Should().Be(100, "no bites occurred");
}
[Fact]
public void BitePet_NotEnoughAvailableBites()
{
Pet pet = new Cat();
_flea.JumpOnPet(pet);
_flea.BitePet(60);
_flea.BitePet(50)
.Should().Be(40, "there were only 40 'free bites' remaining");
_flea.TotalBites.Should().Be(100, "60 + 40");
}
[Fact]
public void BitePet_MultiplePets()
{
Pet pet1 = new Dog(new DateTimeProvider());
Pet pet2 = new Cat();
_flea.JumpOnPet(pet1);
_flea.BitePet(20);
_flea.BitePet(15);
_flea.JumpOnPet(pet2);
_flea.BitePet(40);
_flea.JumpOnPet(pet1);
_flea.BitePet(10);
_flea.JumpOnPet(null);
_flea.TotalBites.Should().Be(85, "spread across two pets");
pet1.RemainingBites.Should().Be(55);
pet2.RemainingBites.Should().Be(60);
_flea.CurrentPet.Should().BeNull();
}
[Fact]
public void StringRepresentation() => new Flea().ToString().Should().Be("I'm a flea");
#region you wouldn't normally write such tests, only for school context
[Fact]
public void IsSealed()
{
typeof(Flea).IsSealed
.Should().BeTrue("nothing inherits from Flea");
}
[Fact]
public void InheritsDirectlyFromObject()
{
typeof(Flea).BaseType.Should().Be<object>("does not inherit from anything except object");
}
#endregion
*/
}

View file

@ -0,0 +1,90 @@
namespace PetsAndFleas.Test;
public sealed class PetTests
{
/*
[Fact]
public void PetId()
{
int initialId = Pet.NextPetId;
for (var i = 1; i < 5; i++)
{
int expectedId = initialId + i;
Pet pet = i % 2 == 0
? new Dog(new DateTimeProvider())
: new Cat();
pet.PetId.Should().Be(expectedId, "each pet gets a unique id by incrementing a static counter");
}
}
[Fact]
public void RemainingBites_Initial()
{
Pet pet = new Cat();
pet.RemainingBites
.Should().Be(100, "initial value set by Pet ctor");
}
[Theory]
[MemberData(nameof(GetBittenData))]
public void GetBitten(Pet pet, int amountBites, int expectedActualBites, int expectedRemaining,
string reasonActualBites, string reasonRemainingBites)
{
pet.GetBitten(amountBites)
.Should().Be(expectedActualBites, reasonActualBites);
pet.RemainingBites
.Should().Be(expectedRemaining, reasonRemainingBites);
}
public static TheoryData<Pet, int, int, int, string, string> GetBittenData()
{
Pet pet = new Dog(new DateTimeProvider());
return new TheoryData<Pet, int, int, int, string, string>
{
{ pet, 40, 40, 60, "40 < 100, can perform all bites", "100 - 40 = 60" },
{ pet, 70, 60, 0, "70 > 60, can only perform 60 bytes", "no more bites possible" },
{ new Cat(), 200, 100, 0, "200 > 100, performing 100 bites", "all bites 'spent'" },
{ new Dog(new DateTimeProvider()), -50, 0, 100, "negative amount, ignored", "no bites have happened yet" }
};
}
#region you wouldn't normally write such tests, only for school context
[Fact]
public void IsAbstract()
{
typeof(Pet).IsAbstract
.Should().BeTrue("Pet has to be abstract");
}
[Fact]
public void InheritsDirectlyFromObject()
{
typeof(Pet).BaseType.Should().Be<object>("does not inherit from anything except object");
}
[Fact]
public void HasInheritors()
{
var dogType = typeof(Dog);
var catType = typeof(Cat);
var petType = typeof(Pet);
petType.IsAssignableFrom(dogType)
.Should().BeTrue("Pet is base class of Dog");
petType.IsAssignableFrom(catType)
.Should().BeTrue("Pet is base class of Cat");
dogType.IsSealed
.Should().BeTrue("nothing inherits from Dog");
catType.IsSealed
.Should().BeTrue("nothing inherits from Cat");
}
#endregion
*/
}

View file

@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<Using Include="FluentAssertions" />
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AwesomeAssertions" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PetsAndFleas\PetsAndFleas.csproj" />
</ItemGroup>
</Project>

31
PetsAndFleas.sln Normal file
View file

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33103.184
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PetsAndFleas", "PetsAndFleas\PetsAndFleas.csproj", "{7F30E637-BAFE-42FA-A173-F42B3902ED3B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PetsAndFleas.Test", "PetsAndFleas.Test\PetsAndFleas.Test.csproj", "{161D9B2A-4E8B-43B6-A77E-40BED559521F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7F30E637-BAFE-42FA-A173-F42B3902ED3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F30E637-BAFE-42FA-A173-F42B3902ED3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F30E637-BAFE-42FA-A173-F42B3902ED3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F30E637-BAFE-42FA-A173-F42B3902ED3B}.Release|Any CPU.Build.0 = Release|Any CPU
{161D9B2A-4E8B-43B6-A77E-40BED559521F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{161D9B2A-4E8B-43B6-A77E-40BED559521F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{161D9B2A-4E8B-43B6-A77E-40BED559521F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{161D9B2A-4E8B-43B6-A77E-40BED559521F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D322E690-379C-4802-8F7E-1AC6AD090D59}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,19 @@
namespace PetsAndFleas;
/// <summary>
/// Provides the current time
/// </summary>
public sealed class DateTimeProvider
{
private DateTime? _overriddenDateTime;
/// <summary>
/// Gets the current time.
/// Can be set to a specific value which will then be returned in the future.
/// </summary>
public DateTime Now
{
get => _overriddenDateTime ?? DateTime.Now;
set => _overriddenDateTime = value;
}
}

View file

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HTLLeonding.Utility.LeoAnalyzers" Version="1.0.2" />
</ItemGroup>
</Project>

11
PetsAndFleas/Program.cs Normal file
View file

@ -0,0 +1,11 @@
using PetsAndFleas;
Console.WriteLine("*** PetsAndFleas ***");
/*
var pluto = new Dog(new DateTimeProvider());
var garfield = new Cat();
Console.WriteLine(pluto);
Console.WriteLine(garfield);
*/

BIN
pics/sample_run.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

114
readme.adoc Normal file
View file

@ -0,0 +1,114 @@
:sectnums:
:nofooter:
:toc: left
:icons: font
:data-uri:
:source-highlighter: highlightjs
:stem: latexmath
= Inh.02 -- Pets & Fleas
We are keeping cats & dogs as pets.
Sometimes those are infested by fleas, who bite them.
== Specification
.Class Diagram
[plantuml]
----
@startuml
hide empty methods
class Cat {
-bool _isOnTree
+int TreesClimbed [private set]
+Cat()
+bool ClimbOnTree()
+bool ClimbDown()
+string ToString() [override]
}
class DateTimeProvider {
-DateTime? _overrideDateTime
+DateTime Now
}
class Dog {
{static} -TimeSpan huntingWaitInterval [readonly]
-DateTimeProvider _dateTimeProvider [readonly]
-DateTime? _lastHuntedTime
+int HuntedAnimals [private set]
+Dog(DateTimeProvider)
+bool HuntAnimal()
+string ToString() [override]
}
class Flea {
+Pet? CurrentPet [private set]
+int TotalBites [private set]
+void JumpOnPet(Pet?)
+int BitePet(int)
+string ToString() [override]
}
abstract class Pet {
{static} +int NextPetId [private set]
+int PetId [readonly]
+int RemainingBites [private set]
#Pet()
+int GetBitten(int)
{static} #void PrintCtorInfo(string)
}
Pet <|-- Cat
Pet <|-- Dog
Dog *-- DateTimeProvider
Flea o-l- Pet
@enduml
----
=== Pet
* Every animal kept as a pet is... a pet
* Each pet has a unique id
** This is assigned upon creation
** The next id is the previous +1
* A pet can be bitten at most 100 times (then it is out of blood 🧛)
=== Cat
* A cat is a pet
* It can climb on trees
** It cannot climb two trees at the same time
* And it can climb down from a tree
** If it was up on a tree
* It represents itself as `I'm a cat`
=== Dog
* A dog is a pet
* It can go on the hunt for animals
** Between hunts, it has to rest for at least one minute
* It represents itself as `I'm a dog`
=== Flea
* A flea is _not_ a pet
* It can jump on pets and bite them
* It can switch to other pets or even none
* It represents itself as `I'm a flea`
== Tasks
. Implement the necessary classes and logic to fulfill the requirements
** Extensive unit tests have been provided to guide you
*** Make sure to use the correct names for classes, methods and properties to ensure that those will work with your implementation
** Mind the class diagram and specification above
. Create full XMLDoc for your code
. Ensure that the provided `Program` produces the following output
.Sample Run
image::pics/sample_run.png[Sample Run]
WARNING: Unit tests & `Program` logic are commented to ensure the solution compiles -- enable them as needed while your implementation extends