Initial commit

This commit is contained in:
github-classroom[bot] 2025-01-02 16:52:58 +00:00 committed by GitHub
commit eab553c714
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 5080 additions and 0 deletions

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="FluentAssertions" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BuildingDirectory\BuildingDirectory.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,101 @@
using BuildingDirectory.Model;
namespace BuildingDirectory.Test;
public sealed class BuildingInformationTests
{
private static readonly string[] companyNames = ["Foo Inc.", "Bar GmbH", "Baz AG"];
private static readonly (BusinessCard Card, int Room)[] employees =
[
(new BusinessCard("A", "B", "Sales", null, "b@x.com"), 301),
(new BusinessCard("A", "C", "Development", null, "c@x.com"), 444),
(new BusinessCard("A", "D", "HR", null, "d@x.com"), 2),
(new BusinessCard("A", "E", "Maintenance", null, "e@x.com"), 102)
];
[Fact]
public void GetFloorSelection()
{
var info = CreateSampleInfo();
info.GetFloorSelection()
.Should().NotBeNullOrEmpty()
.And.HaveCount(2, "two floors defined")
.And.Contain([Floor.Ground, Floor.First]);
}
[Fact]
public void GetCompaniesOnFloor()
{
var info = CreateSampleInfo();
info.GetCompaniesOnFloor(Floor.Ground)
.Should().NotBeNullOrEmpty()
.And.HaveCount(1, "only one company on this floor")
.And.Contain([companyNames[1]]);
info.GetCompaniesOnFloor(Floor.First)
.Should().NotBeNullOrEmpty()
.And.HaveCount(2, "two companies on this floor")
.And.Contain([companyNames[0], companyNames[2]]);
info.GetCompaniesOnFloor(Floor.Second)
.Should().BeNull("no companies on this floor");
}
[Fact]
public void GetCompany_Exists()
{
var info = CreateSampleInfo();
var company1 = info.GetCompany(Floor.First, companyNames[0]);
company1.Should().NotBeNull();
company1!.Name.Should().Be(companyNames[0]);
company1.NoOfEmployees.Should().Be(1);
var company2 = info.GetCompany(Floor.Ground, companyNames[1]);
company2.Should().NotBeNull();
company2!.Name.Should().Be(companyNames[1]);
company2.NoOfEmployees.Should().Be(2);
var company3 = info.GetCompany(Floor.First, companyNames[2]);
company3.Should().NotBeNull();
company3!.Name.Should().Be(companyNames[2]);
company3.NoOfEmployees.Should().Be(1);
}
[Fact]
public void GetCompany_NotExists()
{
var info = CreateSampleInfo();
info.GetCompany(Floor.Ground, companyNames[0])
.Should().BeNull("company does not reside at this floor");
info.GetCompany(Floor.Second, companyNames[2])
.Should().BeNull("no companies on this floor");
}
private static BuildingInformation CreateSampleInfo()
{
var companiesGround = new MyDictionary<string, Company>();
var companiesFirst = new MyDictionary<string, Company>();
var employees1 = new MyDictionary<BusinessCard, int>();
var employees2 = new MyDictionary<BusinessCard, int>();
var employees3 = new MyDictionary<BusinessCard, int>();
AddEmployee(employees1, 0);
AddEmployee(employees2, 1);
AddEmployee(employees2, 2);
AddEmployee(employees3, 3);
companiesFirst.Add(companyNames[0], new Company(employees1, companyNames[0]));
companiesGround.Add(companyNames[1], new Company(employees2, companyNames[1]));
companiesFirst.Add(companyNames[2], new Company(employees3, companyNames[2]));
var floors = new MyDictionary<Floor, MyDictionary<string, Company>>();
floors.Add(Floor.Ground, companiesGround);
floors.Add(Floor.First, companiesFirst);
return new BuildingInformation(floors);
void AddEmployee(MyDictionary<BusinessCard, int> dic, int idx)
{
(var card, int room) = employees[idx];
dic.Add(card, room);
}
}
}

View file

@ -0,0 +1,52 @@
using BuildingDirectory.Model;
namespace BuildingDirectory.Test;
public sealed class BusinessCardTests
{
[Fact]
public void Equals_Equal()
{
BusinessCard[] cards = CreateSampleCards();
cards[0].Equals(cards[1]).Should().BeTrue("only name is considered");
cards[2].Equals(cards[3]).Should().BeTrue("only name is considered");
}
[Fact]
public void Equals_NotEqual()
{
BusinessCard[] cards = CreateSampleCards();
cards[1].Equals(cards[2]).Should().BeFalse("different people");
}
[Fact]
public void HashCode_Value()
{
var card = CreateSampleCards()[0];
card.GetHashCode()
.Should().Be(card.GetHashCode(), "has to return same value for same input every time");
}
[Fact]
public void HashCode_RelevantProperties()
{
BusinessCard[] cards = CreateSampleCards();
var card1 = cards[2];
var card2 = cards[3];
card1.GetHashCode()
.Should().Be(card2.GetHashCode(), "hash code only based on relevant properties");
}
private static BusinessCard[] CreateSampleCards() =>
[
new("Horst", "Fuchs", "Sales", null, "h.fuchs@foo.com"),
new("Horst", "Fuchs", "KeyAccounting", "1234", "horst.fuchs@foo.com"),
new("Susi", "Sonne", "Development", null, "s.sonne@foo.com"),
new("Susi", "Sonne", "Research", null, "s.sonne@foo.com")
];
}

View file

@ -0,0 +1,45 @@
using BuildingDirectory.Model;
namespace BuildingDirectory.Test;
public sealed class CompanyTests
{
private const string Name = "Foo Inc.";
[Fact]
public void Construction()
{
var company = new Company(CreateSampleDic(), Name);
company.Name.Should().Be(Name);
company.NoOfEmployees.Should().Be(2);
}
[Fact]
public void AskForRoom()
{
List<BusinessCard> employees = CreateSampleCards();
MyDictionary<BusinessCard, int>? dic = CreateSampleDic();
var company = new Company(dic, Name);
company.AskForRoom(employees[0]).Should().Be(101, "person B resides in room 101");
company.AskForRoom(employees[1]).Should().Be(202, "person C resides in room 202");
company.AskForRoom(new BusinessCard("X", "Y", "Z", null, "u@w.com"))
.Should().BeNull("person X is unknown");
}
private static List<BusinessCard> CreateSampleCards() =>
[
new("A", "B", "C", null, "B@D.at"),
new("A", "C", "C", null, "C@D.at")
];
private static MyDictionary<BusinessCard, int> CreateSampleDic()
{
List<BusinessCard> cards = CreateSampleCards();
var dic = new MyDictionary<BusinessCard, int>();
dic.Add(cards[0], 101);
dic.Add(cards[1], 202);
return dic;
}
}

View file

@ -0,0 +1,195 @@
namespace BuildingDirectory.Test;
public sealed class MyDictionaryTests
{
[Fact]
public void Add_Single()
{
const string Value = "test";
const int Key = 5;
var dic = new MyDictionary<int, string>();
dic.Add(Key, Value);
dic.Count.Should().Be(1, "single item added");
dic.ContainsKey(Key).Should().BeTrue();
}
[Fact]
public void Add_Single_Object()
{
var value = new Foo(6, "hello");
const int Key = 5;
var dic = new MyDictionary<int, Foo>();
dic.Add(Key, value);
dic.Count.Should().Be(1, "not only value but also reference types can be added");
dic.ContainsKey(Key).Should().BeTrue();
dic.TryGetValue(Key, out var returnedValue).Should().BeTrue();
returnedValue.Should().BeSameAs(value, "same reference returned");
}
[Fact]
public void Add_Single_Object_Null()
{
const int Key = 5;
var dic = new MyDictionary<int, Foo?>();
dic.Add(Key, null);
dic.Count.Should().Be(1, "null value can be valid if TValue is nullable");
dic.ContainsKey(Key).Should().BeTrue();
dic.TryGetValue(Key, out var returnedValue).Should().BeTrue();
returnedValue.Should().Be(null);
}
[Fact]
public void Add_Multiple()
{
int[] keys = [10, 11, 12];
bool[] values = [true, false, true];
var dic = new MyDictionary<int, bool>();
for (var i = 0; i < keys.Length; i++)
{
dic.Add(keys[i], values[i]);
}
dic.Count.Should().Be(3, "three different items added");
for (var i = 0; i < keys.Length; i++)
{
int key = keys[i];
dic.ContainsKey(key).Should().BeTrue();
dic.TryGetValue(key, out bool value).Should().BeTrue();
value.Should().Be(values[i], "values can occur more than once");
}
}
[Fact]
public void Add_Single_AlreadyExists()
{
const string Value1 = "test1";
const string Value2 = "test2";
const int Key = 5;
var dic = new MyDictionary<int, string>();
dic.Add(Key, Value1);
dic.Add(Key, Value2);
dic.Count.Should().Be(1, "single item added, then updated");
dic.ContainsKey(Key).Should().BeTrue();
dic.TryGetValue(Key, out string? value).Should().BeTrue("can be retrieved by key");
value.Should().Be(Value2, "initial value got updated");
}
[Fact]
public void GetKeys()
{
string[] keys = ["A", "B", "C"];
double[] values = [4D, 12.8D, -98.12D];
var dic = new MyDictionary<string, double>();
for (var i = 0; i < keys.Length; i++)
{
dic.Add(keys[i], values[i]);
}
dic.GetKeys().Should().Contain(keys, "contains all added keys in unspecified order")
.And.HaveCount(keys.Length);
}
[Fact]
public void GetValues()
{
string[] keys = ["A", "B", "C"];
double[] values = [4D, 12.8D, -98.12D];
var dic = new MyDictionary<string, double>();
for (var i = 0; i < keys.Length; i++)
{
dic.Add(keys[i], values[i]);
}
dic.GetValues().Should().Contain(values, "contains all added values in unspecified order")
.And.HaveCount(values.Length);
}
[Fact]
public void ContainsKey_NotExists()
{
var dic = new MyDictionary<int, decimal>();
dic.Add(44, 120M);
dic.ContainsKey(55).Should().BeFalse();
}
[Fact]
public void TryGetValue_NotExists()
{
var dic = new MyDictionary<int, decimal>();
dic.Add(44, 120M);
dic.TryGetValue(55, out decimal value).Should().BeFalse();
value.Should().Be(0, "if key not found assign default to out parameter");
}
[Fact]
public void Remove_Exists()
{
const int Key = 44;
var dic = new MyDictionary<int, decimal>();
dic.Add(Key, 120M);
dic.Remove(Key).Should().BeTrue("could be removed");
dic.Count.Should().Be(0, "count reduced due to removal");
}
[Fact]
public void Remove_NotExists()
{
var dic = new MyDictionary<int, decimal>();
dic.Add(44, 120M);
dic.Remove(1234).Should().BeFalse("key not present in dictionary");
dic.Count.Should().Be(1, "count unchanged");
}
[Fact]
public void Indexer_Exists()
{
const int Key = 44;
const decimal Value = 120M;
var dic = new MyDictionary<int, decimal>();
dic.Add(Key, Value);
dic[Key].Should().Be(Value, "indexer access is possible");
}
[Fact]
public void Indexer_NotExists_Value()
{
var dic = new MyDictionary<int, decimal>();
dic[44].Should().Be(0M, "not found so default decimal returned");
}
[Fact]
public void Indexer_NotExists_Object()
{
var dic = new MyDictionary<int, decimal?>();
dic[44].Should().BeNull("not found so default nullable returned");
}
private record Foo(int Bar, string Baz);
}