diff --git a/.gitignore b/.gitignore index 6c1ac87..07fac84 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ # User-spacific editor config .editorconfig +.vscode # User-specific files *.rsuser diff --git a/MCTG/ConsoleApp/ConsoleApp.csproj b/MCTG/ConsoleApp/ConsoleApp.csproj index c7f3ecd..7e8ef62 100644 --- a/MCTG/ConsoleApp/ConsoleApp.csproj +++ b/MCTG/ConsoleApp/ConsoleApp.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/MCTG/ConsoleApp/Menu/IMenuDisplay.cs b/MCTG/ConsoleApp/Menu/IMenuDisplay.cs new file mode 100644 index 0000000..572082c --- /dev/null +++ b/MCTG/ConsoleApp/Menu/IMenuDisplay.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConsoleApp.Menu +{ + internal interface IMenuDisplay + { + /// + /// Update the menu display in the Console. + /// + void UpdateDisplay(); + + /// + /// Select the next line in the menu + /// + /// The current number of the new selected line + int SelectNextLine(); + + /// + /// Select the previous line in the menu + /// + /// The current number of the new selected line + int SelectPrevioustLine(); + } +} diff --git a/MCTG/ConsoleApp/Menu/SearcherRecipe.cs b/MCTG/ConsoleApp/Menu/SearcherRecipe.cs new file mode 100644 index 0000000..4e17512 --- /dev/null +++ b/MCTG/ConsoleApp/Menu/SearcherRecipe.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; + +using Model; + +namespace ConsoleApp.Menu +{ + /// + /// An utility to find a recipe. + /// + public class SearcherRecipe : SelectMenu + { + #region Attribute + private RecipeCollection _recipeOnSearch; + #endregion + + #region Properties + /// + /// A collection of recipe where the title contain the search string + /// + public RecipeCollection SearchResult { get; private set; } + + /// + /// The search string + /// + public string ResearchStr { get; set; } + #endregion + + /// + /// Constructor of the SearcherRecipe utility. + /// + /// The collection of recipe where to search + public SearcherRecipe(RecipeCollection recipeOnSearch) + { + _recipeOnSearch = recipeOnSearch; + SearchResult = _recipeOnSearch; + ResearchStr = ""; + } + + #region Methodes + /// + /// Launch a search by name request in the collection of Recipe with with a string. + /// + /// The string for search + /// True if the result of the search gave at least 1 element. False otherwise. + public bool ComputeSearch(string researchStr = "") + { + ResearchStr = researchStr; + SearchResult = _recipeOnSearch.ResearchByName(ResearchStr.ToLower()); + _maxLines = SearchResult.Count - 1; + + return SearchResult.Count > 0; + } + + public override void UpdateDisplay() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine("---------------------------------------------------------"); + sb.AppendLine($" Research: {ResearchStr}"); + sb.AppendLine("---------------------------------------------------------"); + for (int i = 0; i < SearchResult.Count; i++) + { + if (i == CurrentLine) + { + CurrentSelected = SearchResult[i]; + sb.Append($">"); + } + sb.AppendLine($" [ {SearchResult[i].Id} ]:\t{SearchResult[i].Title} "); + } + Console.Clear(); + Console.WriteLine(sb); + } + + /// + /// Launch and pilot the search menu. + /// + /// The collection of recipe where to search + /// The recipe selected + public static Recipe? ResearchOn(RecipeCollection recipeOnSearch) + { + SearcherRecipe sr = new SearcherRecipe(recipeOnSearch); + StringBuilder sb = new StringBuilder(); + sr.ComputeSearch(); + sr.UpdateDisplay(); + + ConsoleKeyInfo cki; + + do + { + cki = Console.ReadKey(true); + + switch (cki.Key) + { + case ConsoleKey.UpArrow: + sr.SelectPrevioustLine(); + break; + case ConsoleKey.DownArrow: + sr.SelectNextLine(); + break; + case ConsoleKey.Backspace: + if (sb.Length > 0) + { + sb.Remove(sb.Length - 1, 1); + sr.ComputeSearch(sb.ToString()); + } + break; + default: + sb.Append(cki.KeyChar); + sr.ComputeSearch(sb.ToString()); + break; + } + + sr.UpdateDisplay(); + + } while (cki.Key != ConsoleKey.Enter); + + return sr.CurrentSelected; + } + #endregion + } +} diff --git a/MCTG/ConsoleApp/Menu/SelectMenu.cs b/MCTG/ConsoleApp/Menu/SelectMenu.cs new file mode 100644 index 0000000..0e331c6 --- /dev/null +++ b/MCTG/ConsoleApp/Menu/SelectMenu.cs @@ -0,0 +1,52 @@ +using ConsoleApp; +using Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace ConsoleApp.Menu +{ + /// + /// An abstract class that define the components of a selection-type menu. + /// + /// The return type of the currently selected item + public abstract class SelectMenu : IMenuDisplay + { + protected int _currentLine = 0; + protected int _maxLines = 0; + + /// + /// The currently selected item. + /// + public T? CurrentSelected { get; protected set; } + + /// + /// The current line selected in the menu. + /// + public int CurrentLine + { + get => _currentLine; + protected set + { + _currentLine = value; + if (_currentLine > _maxLines) + { + _currentLine = _maxLines; + } + if (_currentLine < 0) + { + _currentLine = 0; + } + return; + } + } + + public int SelectNextLine() { return ++CurrentLine; } + public int SelectPrevioustLine() { return --CurrentLine; } + + public abstract void UpdateDisplay(); + } +} diff --git a/MCTG/ConsoleApp/Program.cs b/MCTG/ConsoleApp/Program.cs index 773f61b..ac9a1e9 100644 --- a/MCTG/ConsoleApp/Program.cs +++ b/MCTG/ConsoleApp/Program.cs @@ -1,21 +1,29 @@ -// See https://aka.ms/new-console-template for more information - +// See https://aka.ms/new-console-template for more information + using ConsoleApp; -using Model; - - -Console.WriteLine("Hello, World!\n\n"); - - -// TESTS: - -Stub stub = new Stub(); - -List recipes = stub.LoadRecipes(); -List recipeCollections = stub.LoadRecipeCollection(); - -foreach (Recipe r in recipes) - Console.WriteLine(r); - -foreach (RecipeCollection r in recipeCollections) - Console.WriteLine(r); +using ConsoleApp.Menu; +using Model; + +using System.Text; + +Console.WriteLine("Hello, World!\n\n"); + + +// TESTS: + +Stub stub = new Stub(); + +List recipes = stub.LoadRecipes(); +List recipeCollections = stub.LoadRecipeCollection(); + +RecipeCollection? allRecipe = recipeCollections.Find(x => x.Description.Equals("All")); +if (allRecipe == null) + throw new ArgumentException("Load AllRecipe in stub: can't find 'All'."); + +Manager manager = new Manager(allRecipe); + +Recipe? ret = SearcherRecipe.ResearchOn(allRecipe); +Console.WriteLine(ret); + +// press any key to quit +Console.ReadKey(); diff --git a/MCTG/ConsoleApp/Stub.cs b/MCTG/ConsoleApp/Stub.cs deleted file mode 100644 index bb8fa01..0000000 --- a/MCTG/ConsoleApp/Stub.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ConsoleApp -{ - internal struct Stub - { - public List LoadRecipes() - { - List stub = new List(); - stub.AddRange(new[] - { - new Recipe(), - new Recipe("Cookies"), - new Recipe("Cookies", 23), - new Recipe("Cookies", null), - new Recipe("", null), - new Recipe("", 24), - new Recipe("Cookies", 24, - new PreparationStep(1)), - new Recipe("Cookies", 26, - new PreparationStep(1), - new PreparationStep(2, "Faire cuire.")) - }); - return stub; - } - - public List LoadRecipeCollection() - { - List stub = new List(); - stub.AddRange(new[] - { - new RecipeCollection("All", LoadRecipes().ToArray()), - new RecipeCollection("Starters", LoadRecipes().FindAll(x => x.Id.Equals(23)).ToArray()), - new RecipeCollection("Dishies", LoadRecipes().FindAll(x => x.Id.Equals(24)).ToArray()), - new RecipeCollection("Desserts", LoadRecipes().FindAll(x => x.Id.Equals(26)).ToArray()), - }); - return stub; - } - - public List ConstrucList() - { - List Users = new List(); - - User Roger = new User("Roger", "Rabbit", "carotte@mail.fr"); - User Dylan = new User("d", "r", "dr@mail.fr"); - User Val = new User("V", "entin", "Valentin@mail.fr"); - - Users.Add(Roger); - Users.Add(Dylan); - Users.Add(Val); - - return Users; - } - } -} diff --git a/MCTG/ConsoleApp/Stubs/Stub.cs b/MCTG/ConsoleApp/Stubs/Stub.cs new file mode 100644 index 0000000..f116321 --- /dev/null +++ b/MCTG/ConsoleApp/Stubs/Stub.cs @@ -0,0 +1,99 @@ +using Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConsoleApp +{ + internal struct Stub + { + public List LoadRecipes() + { + List stub = new List(); + stub.AddRange(new[] + { + new Recipe(), + new Recipe( + title: "Cookies"), + new Recipe( + title: "Cookies", id: 23), + new Recipe( + title: "Cookies au chocolat", id: null), + new Recipe( + title: "", id: null), + new Recipe( + title: "", id: 24), + new Recipe( + title: "Cookies", id: 24, + preparationSteps: new[]{ + new PreparationStep(1) + }), + new Recipe( + title: "Cookies", id: 26, + preparationSteps: new[]{ + new PreparationStep(1), + new PreparationStep(2, "Faire cuire.") + }), + new Recipe( + title: "Gateau à la crème", + preparationSteps: new[]{ + new PreparationStep(1, "Ajouter les oeufs."), + new PreparationStep(2, "Ajouter la farine."), + new PreparationStep(3, "Mélanger le tout."), + new PreparationStep(4, "Faire cuire 1h10 au four traditionnel.") + }), + new Recipe( + title: "Gateau au chocolat", + preparationSteps: new[]{ + new PreparationStep(1, "Ajouter les oeufs."), + new PreparationStep(2, "Ajouter la farine."), + new PreparationStep(2, "Ajouter 100g de chocolat fondu."), + new PreparationStep(3, "Mélanger le tout."), + new PreparationStep(4, "Faire cuire 45h au four traditionnel.") + }), + new Recipe( + title: "Gateau aux cerises", + preparationSteps: new[]{ + new PreparationStep(1, "Ajouter les oeufs."), + new PreparationStep(2, "Ajouter la farine."), + new PreparationStep(2, "Ajouter des morceaux de fraises découpées en petits carré"), + new PreparationStep(3, "Mélanger le tout."), + new PreparationStep(4, "Faire cuire 30min au four traditionnel.") + }), + }); + return stub; + } + + public List LoadRecipeCollection() + { + List stub = new List(); + stub.AddRange(new[] + { + new RecipeCollection("All", LoadRecipes().ToArray()), + new RecipeCollection("Starters", LoadRecipes().FindAll(x => x.Id.Equals(23)).ToArray()), + new RecipeCollection("Dishies", LoadRecipes().FindAll(x => x.Id.Equals(24)).ToArray()), + new RecipeCollection("Desserts", LoadRecipes().FindAll(x => x.Id.Equals(26)).ToArray()), + }); + return stub; + } + + + public List ConstrucList() + { + List Users = new List(); + + User Roger = new User("Roger", "Rabbit", "carotte@mail.fr"); + User Dylan = new User("d", "r", "dr@mail.fr"); + User Val = new User("V", "entin", "Valentin@mail.fr"); + + Users.Add(Roger); + Users.Add(Dylan); + Users.Add(Val); + + return Users; + } + } +} diff --git a/MCTG/Model/Manager/Manager.cs b/MCTG/Model/Manager/Manager.cs new file mode 100644 index 0000000..5c4a6a7 --- /dev/null +++ b/MCTG/Model/Manager/Manager.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Model +{ + /// + /// Manager of the model. Here is stoked all the recipes, the users, etc... + /// + public class Manager + { + /// + /// A collection of all the recipe loaded in the app. + /// + public RecipeCollection AllRecipes { get; protected set; } + + /// + /// The constructor of the manager. + /// + public Manager() + { + AllRecipes = new RecipeCollection(description: "All Recipes"); + } + + /// + /// The constructor of the manager. + /// + /// A list of loaded recipes + public Manager(RecipeCollection allRecipes) + { + AllRecipes = new RecipeCollection( + description: "All Recipes", + recipes: allRecipes.ToArray()); + } + } +} diff --git a/MCTG/Model/Model.csproj b/MCTG/Model/Model.csproj index cfadb03..a1ed5b3 100644 --- a/MCTG/Model/Model.csproj +++ b/MCTG/Model/Model.csproj @@ -1,4 +1,4 @@ - + net7.0 diff --git a/MCTG/Model/Recipes/RecipeCollection.cs b/MCTG/Model/Recipes/RecipeCollection.cs index 3592bb8..42ff5d8 100644 --- a/MCTG/Model/Recipes/RecipeCollection.cs +++ b/MCTG/Model/Recipes/RecipeCollection.cs @@ -68,6 +68,18 @@ namespace Model return recipe; } + /// + /// Utility to find a recipe by his name. + /// + /// The string for the search + /// A collection of Recipe where their Title contain the string. + public RecipeCollection ResearchByName(string str) + { + return new RecipeCollection( + description: $"Results of the research: {str}", + recipes: _recipes.FindAll(x => x.Title.ToLower().Contains(str.ToLower())).ToArray()); + } + #region IList Methods public int IndexOf(Recipe item) { diff --git a/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs b/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs new file mode 100644 index 0000000..36008b1 --- /dev/null +++ b/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Model; + +namespace Model_UnitTests +{ + public class RecipeCollection_UT + { + [Fact] + public void TestResearchByName() + { + RecipeCollection recipes = new RecipeCollection( + description: "test recipe", + recipes: new[] + { + new Recipe(title: "Gateau à la crème", id: 1), + new Recipe(title: "Gateau au chocolat", id: 2), + new Recipe(title: "Gateau aux cerises", id: 3) + }); + + Assert.Equal(2, recipes.ResearchByName("chocolat").FirstOrDefault().Id); + } + } +}