diff --git a/.gitignore b/.gitignore index 9491a2fd..988f1af1 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,9 @@ # Mono auto generated files mono_crash.* +# Jetbrains Project Files +.idea/ + # Build results [Dd]ebug/ [Dd]ebugPublic/ diff --git a/csharp-tdd-oop-bobs-bagels.drawio.png b/csharp-tdd-oop-bobs-bagels.drawio.png new file mode 100644 index 00000000..91e197b9 Binary files /dev/null and b/csharp-tdd-oop-bobs-bagels.drawio.png differ diff --git a/csharp-tdd-oop-bobs-bagels.drawio.svg b/csharp-tdd-oop-bobs-bagels.drawio.svg new file mode 100644 index 00000000..0c43e82d --- /dev/null +++ b/csharp-tdd-oop-bobs-bagels.drawio.svg @@ -0,0 +1,4 @@ + + + +
Basket
Basket
-capacity: int
-contents: List<Bagel>
 
-capacity: int...
+AddBagel(Bagel)
+RemoveBagel(Bagel)
+AdjustCapacity(int)
+GetTotalCost() -> decimal
+
+AddBagel(Bagel)...
Bagel
Bagel

+bagelFilling: BagelFilling
+cost: decimal

+bagelFilling: BagelFillin...
+Type() -> string
+Filling() -> BagelFilling
+Name() -> string
+Abbreviation() -> string
+SetFilling(BagelFilling)
+GetTotalCost() -> decimal
+Type() -> string...
BagelFilling
BagelFilling
+Type() -> string
+Name() -> string
+Abbreviation() -> string
+Cost() -> decimal
+Type() -> string...
Egg
Egg
Bacon
Bacon
CreamCheese
CreamCheese
Ham
Ham
SmokedSalmon
SmokedSalmon
EverythingBagel
EverythingBagel
OnionBagel
OnionBagel
PlainBagel
PlainBagel
SesameBagel
SesameBagel
\ No newline at end of file diff --git a/domain_model.md b/domain_model.md new file mode 100644 index 00000000..c56f42e7 --- /dev/null +++ b/domain_model.md @@ -0,0 +1,10 @@ +## Core ## +| Methods/Properties | Scenario | Outputs | +|-----------------------------------------------------|---------------------------------------------------------------------------|--------------------------------------------------------------| +| Basket.AddBagel(Bagel bagel) | add specific type of bagel, should notify when full | A notification if full | +| Basket.RemoveBagel(Bagel bagel) | remove a bagel from the basket, should notify if the bagel does not exist | A notification if bagel does not exist | +| Basket.AdjustCapacity(int capacity) | change the capacity of the basket | None | +| Basket.GetTotalCost() | get the total cost of all bagels in the basket | The total cost of all bagels in the basket | +| Bagel.SetFilling(BagelFilling filling) | change filling of the bagel | None | +| BagelFilling.GetCost() | get the cost of the filling | The cost of the filling | + \ No newline at end of file diff --git a/exercise.main/BagelFillings/Bacon.cs b/exercise.main/BagelFillings/Bacon.cs new file mode 100644 index 00000000..82607f36 --- /dev/null +++ b/exercise.main/BagelFillings/Bacon.cs @@ -0,0 +1,8 @@ +namespace exercise.main.BagelFillings; + +public class Bacon : BagelFilling +{ + public override string Name() => "Bacon"; + public override string Abbreviation() => "FILB"; + public override decimal Cost() => new(0.12); +} \ No newline at end of file diff --git a/exercise.main/BagelFillings/BagelFilling.cs b/exercise.main/BagelFillings/BagelFilling.cs new file mode 100644 index 00000000..ecd0483c --- /dev/null +++ b/exercise.main/BagelFillings/BagelFilling.cs @@ -0,0 +1,9 @@ +namespace exercise.main.BagelFillings; + +public abstract class BagelFilling +{ + public string Type => "Filling"; + public abstract string Name(); + public abstract string Abbreviation(); + public abstract decimal Cost(); +} \ No newline at end of file diff --git a/exercise.main/BagelFillings/Cheese.cs b/exercise.main/BagelFillings/Cheese.cs new file mode 100644 index 00000000..113aa829 --- /dev/null +++ b/exercise.main/BagelFillings/Cheese.cs @@ -0,0 +1,8 @@ +namespace exercise.main.BagelFillings; + +public class Cheese : BagelFilling +{ + public override string Name() => "Cheese"; + public override string Abbreviation() => "FILC"; + public override decimal Cost() => new(0.12); +} \ No newline at end of file diff --git a/exercise.main/BagelFillings/CreamCheese.cs b/exercise.main/BagelFillings/CreamCheese.cs new file mode 100644 index 00000000..d78cefef --- /dev/null +++ b/exercise.main/BagelFillings/CreamCheese.cs @@ -0,0 +1,8 @@ +namespace exercise.main.BagelFillings; + +public class CreamCheese : BagelFilling +{ + public override string Name() => "CreamCheese"; + public override string Abbreviation() => "FILX"; + public override decimal Cost() => new(0.12); +} \ No newline at end of file diff --git a/exercise.main/BagelFillings/Egg.cs b/exercise.main/BagelFillings/Egg.cs new file mode 100644 index 00000000..e7ca3a5f --- /dev/null +++ b/exercise.main/BagelFillings/Egg.cs @@ -0,0 +1,8 @@ +namespace exercise.main.BagelFillings; + +public class Egg : BagelFilling +{ + public override string Name() => "Egg"; + public override string Abbreviation() => "FILE"; + public override decimal Cost() => new(0.12); +} \ No newline at end of file diff --git a/exercise.main/BagelFillings/Ham.cs b/exercise.main/BagelFillings/Ham.cs new file mode 100644 index 00000000..b2d05e7c --- /dev/null +++ b/exercise.main/BagelFillings/Ham.cs @@ -0,0 +1,8 @@ +namespace exercise.main.BagelFillings; + +public class Ham : BagelFilling +{ + public override string Name() => "Ham"; + public override string Abbreviation() => "FILH"; + public override decimal Cost() => new(0.12); +} \ No newline at end of file diff --git a/exercise.main/BagelFillings/SmokedSalmon.cs b/exercise.main/BagelFillings/SmokedSalmon.cs new file mode 100644 index 00000000..50f68859 --- /dev/null +++ b/exercise.main/BagelFillings/SmokedSalmon.cs @@ -0,0 +1,8 @@ +namespace exercise.main.BagelFillings; + +public class SmokedSalmon : BagelFilling +{ + public override string Name() => "SmokedSalmon"; + public override string Abbreviation() => "FILS"; + public override decimal Cost() => new(0.12); +} \ No newline at end of file diff --git a/exercise.main/Bagels/Bagel.cs b/exercise.main/Bagels/Bagel.cs new file mode 100644 index 00000000..51d5f2ed --- /dev/null +++ b/exercise.main/Bagels/Bagel.cs @@ -0,0 +1,30 @@ +using exercise.main.BagelFillings; + +namespace exercise.main.Bagels; + +public abstract class Bagel +{ + public static string Type => "Bagel"; + public BagelFilling Filling => bagelFilling; + public abstract string Name(); + public abstract string Abbreviation(); + + protected BagelFilling bagelFilling; + protected decimal cost; + + protected Bagel(BagelFilling bagelFilling, decimal cost) + { + this.bagelFilling = bagelFilling; + this.cost = cost; + } + + public void SetFilling(BagelFilling filling) + { + bagelFilling = filling; + } + + public decimal GetTotalCost() + { + return cost + Filling.Cost(); + } +} \ No newline at end of file diff --git a/exercise.main/Bagels/EverythingBagel.cs b/exercise.main/Bagels/EverythingBagel.cs new file mode 100644 index 00000000..07159ab0 --- /dev/null +++ b/exercise.main/Bagels/EverythingBagel.cs @@ -0,0 +1,13 @@ +using exercise.main.BagelFillings; + +namespace exercise.main.Bagels; + +public class EverythingBagel : Bagel +{ + public override string Name() => "Everything"; + public override string Abbreviation() => "BGLP"; + + public EverythingBagel(BagelFilling bagelFilling) : base(bagelFilling, new decimal(0.49)) + { + } +} \ No newline at end of file diff --git a/exercise.main/Bagels/OnionBagel.cs b/exercise.main/Bagels/OnionBagel.cs new file mode 100644 index 00000000..6470d691 --- /dev/null +++ b/exercise.main/Bagels/OnionBagel.cs @@ -0,0 +1,13 @@ +using exercise.main.BagelFillings; + +namespace exercise.main.Bagels; + +public class OnionBagel : Bagel +{ + public override string Name() => "Plain"; + public override string Abbreviation() => "BGLP"; + + public OnionBagel(BagelFilling bagelFilling) : base(bagelFilling, new decimal(0.49)) + { + } +} \ No newline at end of file diff --git a/exercise.main/Bagels/PlainBagel.cs b/exercise.main/Bagels/PlainBagel.cs new file mode 100644 index 00000000..8ca9c2a4 --- /dev/null +++ b/exercise.main/Bagels/PlainBagel.cs @@ -0,0 +1,13 @@ +using exercise.main.BagelFillings; + +namespace exercise.main.Bagels; + +public class PlainBagel : Bagel +{ + public override string Name() => "Plain"; + public override string Abbreviation() => "BGLP"; + + public PlainBagel(BagelFilling bagelFilling) : base(bagelFilling, new decimal(0.39)) + { + } +} \ No newline at end of file diff --git a/exercise.main/Bagels/SesameBagel.cs b/exercise.main/Bagels/SesameBagel.cs new file mode 100644 index 00000000..650ec396 --- /dev/null +++ b/exercise.main/Bagels/SesameBagel.cs @@ -0,0 +1,13 @@ +using exercise.main.BagelFillings; + +namespace exercise.main.Bagels; + +public class SesameBagel : Bagel +{ + public override string Name() => "Sesame"; + public override string Abbreviation() => "BGLP"; + + public SesameBagel(BagelFilling bagelFilling) : base(bagelFilling, new decimal(0.49)) + { + } +} \ No newline at end of file diff --git a/exercise.main/Basket.cs b/exercise.main/Basket.cs new file mode 100644 index 00000000..8d112751 --- /dev/null +++ b/exercise.main/Basket.cs @@ -0,0 +1,53 @@ +using exercise.main.BagelFillings; +using exercise.main.Bagels; + +namespace exercise.main; + +public class Basket +{ + public int Count => _contents.Count; + + private readonly List _contents = new(); + private int _maxCapacity; + + public Basket(int maxCapacity) + { + _maxCapacity = maxCapacity; + } + + public void AddBagel(Bagel bagel) + { + if (_contents.Count < _maxCapacity) + { + _contents.Add(bagel); + } + else + { + Console.WriteLine("Basket is at max capacity!"); + } + } + + public void RemoveBagel(Bagel bagel) + { + if (!_contents.Remove(bagel)) + { + Console.WriteLine("Could not find bagel to remove!"); + } + } + + public void AdjustCapacity(int capacity) + { + _maxCapacity = capacity; + } + + public decimal GetTotalCost() + { + decimal cost = 0; + foreach (var bagel in _contents) + { + cost += bagel.GetTotalCost(); + } + + return cost; + } +} \ No newline at end of file diff --git a/exercise.sln b/exercise.sln index 0efb5453..62890297 100644 --- a/exercise.sln +++ b/exercise.sln @@ -14,6 +14,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution extension3.md = extension3.md extension4.md = extension4.md README.md = README.md + domain_model.md = domain_model.md + csharp-tdd-oop-bobs-bagels.drawio.png = csharp-tdd-oop-bobs-bagels.drawio.png + csharp-tdd-oop-bobs-bagels.drawio.svg = csharp-tdd-oop-bobs-bagels.drawio.svg EndProjectSection EndProject Global diff --git a/exercise.tests/BagelTests.cs b/exercise.tests/BagelTests.cs new file mode 100644 index 00000000..c74c12d0 --- /dev/null +++ b/exercise.tests/BagelTests.cs @@ -0,0 +1,38 @@ +using System.Diagnostics; +using exercise.main.BagelFillings; +using exercise.main.Bagels; + +namespace exercise.tests; + +public class Tests +{ + [Test] + public void SetFillingTest() + { + // Arrange + BagelFilling expected = new Cheese(); + Bagel bagel = new EverythingBagel(new Bacon()); + + // Act + bagel.SetFilling(expected); + + // Assert + Debug.Assert(bagel.Filling == expected); + } + + [Test] + public void GetTotalCostTest() + { + // Arrange + BagelFilling filling = new Cheese(); + Bagel bagel = new EverythingBagel(filling); + + const decimal EXPECTED_TOTAL = (decimal)0.61; + + // Act + decimal totalCost = bagel.GetTotalCost(); + + // Assert + Debug.Assert(totalCost == EXPECTED_TOTAL); + } +} \ No newline at end of file diff --git a/exercise.tests/BasketTests.cs b/exercise.tests/BasketTests.cs new file mode 100644 index 00000000..e30f9dcd --- /dev/null +++ b/exercise.tests/BasketTests.cs @@ -0,0 +1,83 @@ +using System.Diagnostics; +using exercise.main; +using exercise.main.BagelFillings; +using exercise.main.Bagels; + +namespace exercise.tests; + +public class BasketTests +{ + [Test] + public void AddBagelTest() + { + // Arrange + Basket basket = new Basket(1); + Bagel bagel = new EverythingBagel(new Cheese()); + + + // Act + basket.AddBagel(bagel); + basket.AddBagel(bagel); + + // Assert + Debug.Assert(basket.Count == 1); + } + + [Test] + public void RemoveBagelTest() + { + // Arrange + Basket basket = new Basket(2); + Bagel bagel = new EverythingBagel(new Cheese()); + + basket.AddBagel(bagel); + + // Act + basket.RemoveBagel(bagel); + basket.RemoveBagel(bagel); + + // Assert + Debug.Assert(basket.Count == 0); + } + + [Test] + public void AdjustCapacityTest() + { + // Arrange + Basket basket = new Basket(0); + Bagel bagel = new EverythingBagel(new Cheese()); + + basket.AddBagel(bagel); + + // Act + basket.AdjustCapacity(1); + basket.AddBagel(bagel); + + // Assert + Debug.Assert(basket.Count == 1); + } + + [Test] + public void GetTotalCostTest() + { + // Arrange + Basket basket = new Basket(3); + Bagel bagel1 = new EverythingBagel(new Cheese()); + Bagel bagel2 = new OnionBagel(new CreamCheese()); + Bagel bagel3 = new SesameBagel(new Egg()); + + basket.AddBagel(bagel1); + basket.AddBagel(bagel2); + basket.AddBagel(bagel3); + + const decimal EXPECTED_TOTAL = (decimal)1.83; + + // Act + decimal totalCost = basket.GetTotalCost(); + + // Assert + Debug.Assert(totalCost == EXPECTED_TOTAL); + } + + +} \ No newline at end of file diff --git a/exercise.tests/UnitTest1.cs b/exercise.tests/UnitTest1.cs deleted file mode 100644 index 7bdb8968..00000000 --- a/exercise.tests/UnitTest1.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace exercise.tests; - -public class Tests -{ - [SetUp] - public void Setup() - { - } - - [Test] - public void Test1() - { - Assert.Pass(); - } -} \ No newline at end of file diff --git a/exercise.tests/exercise.tests.csproj b/exercise.tests/exercise.tests.csproj index 9fed8e17..a3a97d4f 100644 --- a/exercise.tests/exercise.tests.csproj +++ b/exercise.tests/exercise.tests.csproj @@ -17,4 +17,8 @@ + + + +