Merge pull request 'Ajout d'un menu de recherche de recettes' (#35) from feature/33-research-recipes into dev-model
continuous-integration/drone/push Build is passing Details

Reviewed-on: #35
pull/28/head
Alexandre AGOSTINHO 2 years ago
commit 46bcde4319

1
.gitignore vendored

@ -6,6 +6,7 @@
# User-spacific editor config # User-spacific editor config
.editorconfig .editorconfig
.vscode
# User-specific files # User-specific files
*.rsuser *.rsuser

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>

@ -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
{
/// <summary>
/// Update the menu display in the Console.
/// </summary>
void UpdateDisplay();
/// <summary>
/// Select the next line in the menu
/// </summary>
/// <returns>The current number of the new selected line</returns>
int SelectNextLine();
/// <summary>
/// Select the previous line in the menu
/// </summary>
/// <returns>The current number of the new selected line</returns>
int SelectPrevioustLine();
}
}

@ -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
{
/// <summary>
/// An utility to find a recipe.
/// </summary>
public class SearcherRecipe : SelectMenu<Recipe>
{
#region Attribute
private RecipeCollection _recipeOnSearch;
#endregion
#region Properties
/// <summary>
/// A collection of recipe where the title contain the search string
/// </summary>
public RecipeCollection SearchResult { get; private set; }
/// <summary>
/// The search string
/// </summary>
public string ResearchStr { get; set; }
#endregion
/// <summary>
/// Constructor of the SearcherRecipe utility.
/// </summary>
/// <param name="recipeOnSearch">The collection of recipe where to search</param>
public SearcherRecipe(RecipeCollection recipeOnSearch)
{
_recipeOnSearch = recipeOnSearch;
SearchResult = _recipeOnSearch;
ResearchStr = "";
}
#region Methodes
/// <summary>
/// Launch a search by name request in the collection of Recipe with with a string.
/// </summary>
/// <param name="researchStr">The string for search</param>
/// <returns>True if the result of the search gave at least 1 element. False otherwise.</returns>
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);
}
/// <summary>
/// Launch and pilot the search menu.
/// </summary>
/// <param name="recipeOnSearch">The collection of recipe where to search</param>
/// <returns>The recipe selected</returns>
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
}
}

@ -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
{
/// <summary>
/// An abstract class that define the components of a selection-type menu.
/// </summary>
/// <typeparam name="T">The return type of the currently selected item</typeparam>
public abstract class SelectMenu<T> : IMenuDisplay
{
protected int _currentLine = 0;
protected int _maxLines = 0;
/// <summary>
/// The currently selected item.
/// </summary>
public T? CurrentSelected { get; protected set; }
/// <summary>
/// The current line selected in the menu.
/// </summary>
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();
}
}

@ -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 ConsoleApp;
using Model; using ConsoleApp.Menu;
using Model;
Console.WriteLine("Hello, World!\n\n"); using System.Text;
Console.WriteLine("Hello, World!\n\n");
// TESTS:
Stub stub = new Stub(); // TESTS:
List<Recipe> recipes = stub.LoadRecipes(); Stub stub = new Stub();
List<RecipeCollection> recipeCollections = stub.LoadRecipeCollection();
List<Recipe> recipes = stub.LoadRecipes();
foreach (Recipe r in recipes) List<RecipeCollection> recipeCollections = stub.LoadRecipeCollection();
Console.WriteLine(r);
RecipeCollection? allRecipe = recipeCollections.Find(x => x.Description.Equals("All"));
foreach (RecipeCollection r in recipeCollections) if (allRecipe == null)
Console.WriteLine(r); 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();

@ -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<Recipe> LoadRecipes()
{
List<Recipe> stub = new List<Recipe>();
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<RecipeCollection> LoadRecipeCollection()
{
List<RecipeCollection> stub = new List<RecipeCollection>();
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<User> ConstrucList()
{
List<User> Users = new List<User>();
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;
}
}
}

@ -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<Recipe> LoadRecipes()
{
List<Recipe> stub = new List<Recipe>();
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<RecipeCollection> LoadRecipeCollection()
{
List<RecipeCollection> stub = new List<RecipeCollection>();
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<User> ConstrucList()
{
List<User> Users = new List<User>();
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;
}
}
}

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model
{
/// <summary>
/// Manager of the model. Here is stoked all the recipes, the users, etc...
/// </summary>
public class Manager
{
/// <summary>
/// A collection of all the recipe loaded in the app.
/// </summary>
public RecipeCollection AllRecipes { get; protected set; }
/// <summary>
/// The constructor of the manager.
/// </summary>
public Manager()
{
AllRecipes = new RecipeCollection(description: "All Recipes");
}
/// <summary>
/// The constructor of the manager.
/// </summary>
/// <param name="allRecipes">A list of loaded recipes</param>
public Manager(RecipeCollection allRecipes)
{
AllRecipes = new RecipeCollection(
description: "All Recipes",
recipes: allRecipes.ToArray());
}
}
}

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>

@ -68,6 +68,18 @@ namespace Model
return recipe; return recipe;
} }
/// <summary>
/// Utility to find a recipe by his name.
/// </summary>
/// <param name="str">The string for the search</param>
/// <returns>A collection of Recipe where their Title contain the string.</returns>
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 #region IList Methods
public int IndexOf(Recipe item) public int IndexOf(Recipe item)
{ {

@ -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);
}
}
}
Loading…
Cancel
Save