Initial commit
This commit is contained in:
commit
eab553c714
16 changed files with 5080 additions and 0 deletions
34
BuildingDirectory.Test/BuildingDirectory.Test.csproj
Normal file
34
BuildingDirectory.Test/BuildingDirectory.Test.csproj
Normal 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>
|
||||
101
BuildingDirectory.Test/BuildingInformationTests.cs
Normal file
101
BuildingDirectory.Test/BuildingInformationTests.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
52
BuildingDirectory.Test/BusinessCardTests.cs
Normal file
52
BuildingDirectory.Test/BusinessCardTests.cs
Normal 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")
|
||||
];
|
||||
}
|
||||
45
BuildingDirectory.Test/CompanyTests.cs
Normal file
45
BuildingDirectory.Test/CompanyTests.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
195
BuildingDirectory.Test/MyDictionaryTests.cs
Normal file
195
BuildingDirectory.Test/MyDictionaryTests.cs
Normal 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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue