From c872dfb15881031cff4db6aa893fe221a4f16cf1 Mon Sep 17 00:00:00 2001 From: 18-F-cali Date: Thu, 12 Aug 2021 11:02:23 +0530 Subject: [PATCH 1/9] 1. Changed time fields to store as UTC. 2. If DueDate is not given we show empty in ouput. --- src/EasyList/DataModels/Todo.cs | 15 +++++++++++++-- src/EasyList/ParseAdd.cs | 4 ++-- src/EasyList/TodoMenu.cs | 25 +++++++++++++++---------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/EasyList/DataModels/Todo.cs b/src/EasyList/DataModels/Todo.cs index ce07ff8..fc27dda 100644 --- a/src/EasyList/DataModels/Todo.cs +++ b/src/EasyList/DataModels/Todo.cs @@ -18,8 +18,19 @@ public class Todo public string Label { get; set; } public string? Description { get; set; } public TodoPriority Priority { get; set; } = TodoPriority.Low; - public DateTimeOffset CreatedDate { get; } = DateTimeOffset.Now; - public DateTimeOffset? DueDate { get; set;} + + private DateTimeOffset _createdDate; + public DateTimeOffset CreatedDate + { + get => _createdDate.ToLocalTime(); + private init => _createdDate = DateTimeOffset.UtcNow; + } + public DateTimeOffset? _dueDate; + public DateTimeOffset? DueDate + { + get => _dueDate?.ToLocalTime(); + set => _dueDate = value?.ToUniversalTime(); + } public TodoStatus Status { get; set; } = TodoStatus.InProgress; [BsonCtor] public Todo(string label, string? description = null, DateTimeOffset? dueDate = null, TodoPriority priority = TodoPriority.Low) diff --git a/src/EasyList/ParseAdd.cs b/src/EasyList/ParseAdd.cs index c59ad59..e1d0d52 100644 --- a/src/EasyList/ParseAdd.cs +++ b/src/EasyList/ParseAdd.cs @@ -52,13 +52,13 @@ public static Dictionary Parse(string[] args) } string label = GetData("add", args, positions).ToString().Trim(); string? description = positions.ContainsKey("-d") ? GetData("-d", args, positions).ToString() : string.Empty; - DateTimeOffset dueDate = positions.ContainsKey("-t") ? DateTimeOffset.Parse(GetData("-t", args, positions).ToString()) : DateTimeOffset.MaxValue; + DateTimeOffset? dueDate = positions.ContainsKey("-t") ? DateTimeOffset.Parse(GetData("-t", args, positions).ToString()) : null; TodoPriority priority = positions.ContainsKey("-p") ? Enum.Parse(GetData("-p", args, positions).ToString().ToUpper()) : TodoPriority.Low; return new Dictionary { {"label" ,label }, {"description",description }, - {"duedate",dueDate.ToString() }, + {"duedate",dueDate.ToString() ?? string.Empty }, {"priority",priority.ToString() } }; } diff --git a/src/EasyList/TodoMenu.cs b/src/EasyList/TodoMenu.cs index bf0a546..3c66750 100644 --- a/src/EasyList/TodoMenu.cs +++ b/src/EasyList/TodoMenu.cs @@ -17,11 +17,13 @@ private static IEnumerable ValidateAdd(Dictionary input) { yield return "Label cannot be empty"; } - - if (DateTimeOffset.Parse(input["duedate"]) < DateTime.UtcNow) - { - yield return "Due date cannot be in the past"; - } + if (DateTimeOffset.TryParse(input["duedate"], out DateTimeOffset tempDate)) + { + if (tempDate < DateTime.UtcNow) + { + yield return "Due date cannot be in the past"; + } + } } private static bool Validate(TODOMENU command, Dictionary input) @@ -60,11 +62,14 @@ public static void Run() var parsedAdd = ParseAdd.Parse(inputAdd?.Split() ?? Array.Empty()); if (Validate(action, parsedAdd)) - { - var newTodo = new Todo(parsedAdd["label"], - parsedAdd["description"], - DateTimeOffset.Parse(parsedAdd["duedate"]), - Enum.Parse(parsedAdd["priority"])); + { + var newTodo = new Todo() + { + Label = parsedAdd["label"], + Description = parsedAdd["description"], + DueDate = DateTimeOffset.TryParse(parsedAdd["duedate"], out DateTimeOffset tempDate) ? tempDate : null, + Priority = Enum.Parse(parsedAdd["priority"]) + }; _todoService.AddTodo(newTodo); } From 5d7c6dba177cd66cb917173fec45d927075a7f69 Mon Sep 17 00:00:00 2001 From: 18-F-cali Date: Thu, 12 Aug 2021 11:06:25 +0530 Subject: [PATCH 2/9] Added "Quit" option to Input Menu. --- src/EasyList/Enums/TodoMenuOptions.cs | 3 ++- src/EasyList/TodoMenu.cs | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/EasyList/Enums/TodoMenuOptions.cs b/src/EasyList/Enums/TodoMenuOptions.cs index e29131e..b2c5826 100644 --- a/src/EasyList/Enums/TodoMenuOptions.cs +++ b/src/EasyList/Enums/TodoMenuOptions.cs @@ -6,6 +6,7 @@ public enum TODOMENU Delete, View, MarkAsDone, - ListAll + ListAll, + Quit } } \ No newline at end of file diff --git a/src/EasyList/TodoMenu.cs b/src/EasyList/TodoMenu.cs index 3c66750..599487d 100644 --- a/src/EasyList/TodoMenu.cs +++ b/src/EasyList/TodoMenu.cs @@ -129,6 +129,10 @@ public static void Run() var inputList = Prompt.Select("Select List Order: ", defaultValue: TodoOrder.CreateDate); _todoService.DisplayAllTodo(inputList); break; + case TODOMENU.Quit: + Console.WriteLine("Exiting..."); + Environment.Exit(Environment.ExitCode = 0); + break; } Console.ReadLine(); From 9f9589c4da7515f32e2ced9347bb56bc02ecd419 Mon Sep 17 00:00:00 2001 From: 18-F-cali Date: Thu, 12 Aug 2021 11:23:06 +0530 Subject: [PATCH 3/9] Changed output Table Format to MarkDown. --- src/EasyList.Tests/EasyList.Tests.csproj | 22 ++++++++++++++++++++++ src/EasyList.Tests/UnitTest1.cs | 13 +++++++++++++ src/EasyList.sln | 6 ++++++ src/EasyList/TodoServiceDB.cs | 2 +- src/EasyList/TodoServiceInMemory.cs | 2 +- 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/EasyList.Tests/EasyList.Tests.csproj create mode 100644 src/EasyList.Tests/UnitTest1.cs diff --git a/src/EasyList.Tests/EasyList.Tests.csproj b/src/EasyList.Tests/EasyList.Tests.csproj new file mode 100644 index 0000000..cc7744a --- /dev/null +++ b/src/EasyList.Tests/EasyList.Tests.csproj @@ -0,0 +1,22 @@ + + + + net5.0 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + diff --git a/src/EasyList.Tests/UnitTest1.cs b/src/EasyList.Tests/UnitTest1.cs new file mode 100644 index 0000000..e84c870 --- /dev/null +++ b/src/EasyList.Tests/UnitTest1.cs @@ -0,0 +1,13 @@ +using Xunit; + +namespace EasyList.Tests +{ + public class UnitTest1 + { + [Fact] + public void Test1() + { + + } + } +} diff --git a/src/EasyList.sln b/src/EasyList.sln index 63bf226..9cfe5f3 100644 --- a/src/EasyList.sln +++ b/src/EasyList.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.31410.357 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyList", "EasyList\EasyList.csproj", "{F5D8EF10-BEB6-4929-B488-49DE9A3AE3D2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyList.Tests", "EasyList.Tests\EasyList.Tests.csproj", "{872B7AFD-69A1-42F2-80BB-6AFF53E9C7BE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {F5D8EF10-BEB6-4929-B488-49DE9A3AE3D2}.Debug|Any CPU.Build.0 = Debug|Any CPU {F5D8EF10-BEB6-4929-B488-49DE9A3AE3D2}.Release|Any CPU.ActiveCfg = Release|Any CPU {F5D8EF10-BEB6-4929-B488-49DE9A3AE3D2}.Release|Any CPU.Build.0 = Release|Any CPU + {872B7AFD-69A1-42F2-80BB-6AFF53E9C7BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {872B7AFD-69A1-42F2-80BB-6AFF53E9C7BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {872B7AFD-69A1-42F2-80BB-6AFF53E9C7BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {872B7AFD-69A1-42F2-80BB-6AFF53E9C7BE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/EasyList/TodoServiceDB.cs b/src/EasyList/TodoServiceDB.cs index 09f3afc..101d9e5 100644 --- a/src/EasyList/TodoServiceDB.cs +++ b/src/EasyList/TodoServiceDB.cs @@ -47,7 +47,7 @@ public void DisplayAllTodo(TodoOrder todoOrder) ConsoleTable .From(_todoRepository.GetAllTodo(todoOrder)) .Configure(o => o.NumberAlignment = Alignment.Right) - .Write(Format.Alternative); + .Write(Format.MarkDown); } diff --git a/src/EasyList/TodoServiceInMemory.cs b/src/EasyList/TodoServiceInMemory.cs index 7f9043d..a74891d 100644 --- a/src/EasyList/TodoServiceInMemory.cs +++ b/src/EasyList/TodoServiceInMemory.cs @@ -45,7 +45,7 @@ public void DisplayAllTodo(TodoOrder todoOrder) ConsoleTable .From(_todoRepository.GetAllTodo(todoOrder)) .Configure(o => o.NumberAlignment = Alignment.Right) - .Write(Format.Alternative); + .Write(Format.MarkDown); } From b75304ddb0c99a1ef02af0a87e11c0dca6a00be3 Mon Sep 17 00:00:00 2001 From: 18-F-cali Date: Thu, 12 Aug 2021 22:38:00 +0530 Subject: [PATCH 4/9] Implemented Update Commands. Refactored Validate Commands. --- src/EasyList/Enums/TodoMenuOptions.cs | 1 + src/EasyList/Enums/TodoUpdate.cs | 10 +++ src/EasyList/Interfaces/ITodoService.cs | 1 + src/EasyList/Program.cs | 7 +- src/EasyList/TodoMenu.cs | 109 ++++++++---------------- src/EasyList/TodoServiceDB.cs | 56 +++++++++++- src/EasyList/TodoServiceInMemory.cs | 53 +++++++++++- src/EasyList/Validate.cs | 76 +++++++++++++++++ 8 files changed, 238 insertions(+), 75 deletions(-) create mode 100644 src/EasyList/Enums/TodoUpdate.cs create mode 100644 src/EasyList/Validate.cs diff --git a/src/EasyList/Enums/TodoMenuOptions.cs b/src/EasyList/Enums/TodoMenuOptions.cs index b2c5826..bcb58aa 100644 --- a/src/EasyList/Enums/TodoMenuOptions.cs +++ b/src/EasyList/Enums/TodoMenuOptions.cs @@ -7,6 +7,7 @@ public enum TODOMENU View, MarkAsDone, ListAll, + Update, Quit } } \ No newline at end of file diff --git a/src/EasyList/Enums/TodoUpdate.cs b/src/EasyList/Enums/TodoUpdate.cs new file mode 100644 index 0000000..401b523 --- /dev/null +++ b/src/EasyList/Enums/TodoUpdate.cs @@ -0,0 +1,10 @@ +namespace EasyList +{ + public enum TodoUpdate + { + Label, + Description, + Priority, + DueDate + } +} \ No newline at end of file diff --git a/src/EasyList/Interfaces/ITodoService.cs b/src/EasyList/Interfaces/ITodoService.cs index d657901..c630c38 100644 --- a/src/EasyList/Interfaces/ITodoService.cs +++ b/src/EasyList/Interfaces/ITodoService.cs @@ -11,5 +11,6 @@ internal interface ITodoService void DisplayAllTodo(TodoOrder todoOrder); Todo? GetTodoByID(int id); void MarkTodoAsDone(Todo todo); + void UpdateTodo(Todo todo, TodoUpdate command); } } \ No newline at end of file diff --git a/src/EasyList/Program.cs b/src/EasyList/Program.cs index 7e06e05..a44c91a 100644 --- a/src/EasyList/Program.cs +++ b/src/EasyList/Program.cs @@ -1,7 +1,12 @@ -namespace EasyList +using EasyList.Factories; +using EasyList.Interfaces; + +namespace EasyList { class Program { + public static ITodoService _todoService = Factory.CreateTodoServiceDB(); + public static void Main(string[] args) { if(args.Length > 1) diff --git a/src/EasyList/TodoMenu.cs b/src/EasyList/TodoMenu.cs index 599487d..e556865 100644 --- a/src/EasyList/TodoMenu.cs +++ b/src/EasyList/TodoMenu.cs @@ -11,46 +11,11 @@ namespace EasyList { public class TodoMenu { - private static IEnumerable ValidateAdd(Dictionary input) - { - if (string.IsNullOrWhiteSpace(input["label"])) - { - yield return "Label cannot be empty"; - } - if (DateTimeOffset.TryParse(input["duedate"], out DateTimeOffset tempDate)) - { - if (tempDate < DateTime.UtcNow) - { - yield return "Due date cannot be in the past"; - } - } - } - - private static bool Validate(TODOMENU command, Dictionary input) - { - var errors = command switch { - TODOMENU.Add => ValidateAdd(input), - // register the rest of the options that need to be validated here - _ => throw new InvalidOperationException($"No validator exists for {command}"), - }; - - if (errors.Any()) - { - Console.WriteLine("The input has the following errors:"); - foreach (var error in errors) - { - Console.WriteLine("\t"+error); - } - - return false; - } - - return true; - } + public static void Run() { - ITodoService _todoService = Factory.CreateTodoServiceDB(); + while(true) { var action = Prompt.Select("Welcome to EasyList!"); @@ -61,7 +26,9 @@ public static void Run() var inputAdd = Prompt.Input("Enter TODO "); var parsedAdd = ParseAdd.Parse(inputAdd?.Split() ?? Array.Empty()); - if (Validate(action, parsedAdd)) + Validate.Add(parsedAdd); + + if (!Validate.TodoErrors()) { var newTodo = new Todo() { @@ -70,64 +37,62 @@ public static void Run() DueDate = DateTimeOffset.TryParse(parsedAdd["duedate"], out DateTimeOffset tempDate) ? tempDate : null, Priority = Enum.Parse(parsedAdd["priority"]) }; - _todoService.AddTodo(newTodo); + Program._todoService.AddTodo(newTodo); } - break; case TODOMENU.Delete: - var inputDelete = Prompt.Input("Enter TODO ID(s) "); - foreach (var item in inputDelete.Split()) + var inputDelete = Prompt.Input>("Enter TODO ID(s) "); + + var validDeleteList = Validate.MultipleIds(inputDelete); + + if (!Validate.TodoErrors()) { - var todoItem = _todoService.GetTodoByID(int.Parse(item)); - if(todoItem != null) - { - Console.WriteLine($"Deleted: {todoItem.Label}"); - _todoService.DeleteTodo(todoItem); - } - else + foreach (var todoDelete in validDeleteList) { - Console.WriteLine($"Todo Id: {item} Not Found."); - Console.WriteLine("Try Again."); - } - + Program._todoService.DeleteTodo(todoDelete); + } } break; case TODOMENU.View: var inputView = Prompt.Input("Enter TODO ID "); - var todo = _todoService.GetTodoByID(inputView); - if(todo != null) - { - _todoService.DisplayTodo(todo); - } - else + + var todoView = Validate.Id(inputView); + + if(!Validate.TodoErrors()) { - Console.WriteLine($"Todo Id: {inputView} Not Found."); + Program._todoService.DisplayTodo(todoView!); } break; case TODOMENU.MarkAsDone: - var inputDone = Prompt.Input("Enter TODO ID(s) "); - foreach (var item in inputDone.Split()) + var inputDone = Prompt.Input>("Enter TODO ID(s) "); + + var validTodoList = Validate.MultipleIds(inputDone); + + if (!Validate.TodoErrors()) { - var todoItem = _todoService.GetTodoByID(int.Parse(item)); - if(todoItem != null) - { - Console.WriteLine($"Completed:{todoItem.Label}."); - _todoService.MarkTodoAsDone(todoItem); - } - else + foreach (var todoDelete in validTodoList) { - Console.WriteLine($"Todo Id: {item} Not Found."); - Console.WriteLine("Try Again."); + Program._todoService.MarkTodoAsDone(todoDelete); } } break; + case TODOMENU.Update: + var inputUpdateAction = Prompt.Select("Select Update Action"); + var inputUpdate = Prompt.Input("Enter the ID to Update"); + var validTodo = Validate.Id(inputUpdate); + + if (!Validate.TodoErrors()) + { + Program._todoService.UpdateTodo(validTodo!, inputUpdateAction); + } + break; case TODOMENU.ListAll: var inputList = Prompt.Select("Select List Order: ", defaultValue: TodoOrder.CreateDate); - _todoService.DisplayAllTodo(inputList); + Program._todoService.DisplayAllTodo(inputList); break; case TODOMENU.Quit: Console.WriteLine("Exiting..."); diff --git a/src/EasyList/TodoServiceDB.cs b/src/EasyList/TodoServiceDB.cs index 101d9e5..daa4b75 100644 --- a/src/EasyList/TodoServiceDB.cs +++ b/src/EasyList/TodoServiceDB.cs @@ -4,6 +4,7 @@ using EasyList.Enums; using EasyList.Factories; using EasyList.Interfaces; +using Sharprompt; namespace EasyList { @@ -50,6 +51,59 @@ public void DisplayAllTodo(TodoOrder todoOrder) .Write(Format.MarkDown); } - + public void UpdateTodo(Todo todo, TodoUpdate command) + { + switch (command) + { + case TodoUpdate.Label: + { + Console.WriteLine("Enter the New Label: "); + string? newLabel = Console.ReadLine(); + if (Validate.Label(newLabel)) + { + if (!Validate.TodoErrors()) + { + todo.Label = newLabel!; + } + } + _todoRepository.UpdateTodo(todo); + break; + } + + case TodoUpdate.Description: + { + Console.WriteLine("Enter the New Description: "); + string? newDescription = Console.ReadLine(); + if (!string.IsNullOrWhiteSpace(newDescription)) + { + todo.Description = newDescription; + } + _todoRepository.UpdateTodo(todo); + break; + } + + case TodoUpdate.Priority: + { + todo.Priority = Prompt.Select("Select new Priority."); ; + _todoRepository.UpdateTodo(todo); + break; + } + + case TodoUpdate.DueDate: + { + Console.WriteLine("Enter the New Due Date: "); + string? newDueDate = Console.ReadLine(); + if(Validate.DueDate(newDueDate)) + { + if (!Validate.TodoErrors()) + { + todo.DueDate = DateTimeOffset.Parse(newDueDate!); + } + } + _todoRepository.UpdateTodo(todo); + break; + } + } + } } } \ No newline at end of file diff --git a/src/EasyList/TodoServiceInMemory.cs b/src/EasyList/TodoServiceInMemory.cs index a74891d..764e0a9 100644 --- a/src/EasyList/TodoServiceInMemory.cs +++ b/src/EasyList/TodoServiceInMemory.cs @@ -4,6 +4,7 @@ using EasyList.Enums; using EasyList.Factories; using EasyList.Interfaces; +using Sharprompt; namespace EasyList { @@ -48,6 +49,56 @@ public void DisplayAllTodo(TodoOrder todoOrder) .Write(Format.MarkDown); } - + public void UpdateTodo(Todo todo, TodoUpdate command) + { + switch (command) + { + case TodoUpdate.Label: + { + Console.WriteLine("Enter the New Label: "); + string? newLabel = Console.ReadLine(); + if (Validate.Label(newLabel)) + { + if (!Validate.TodoErrors()) + { + todo.Label = newLabel!; + } + } + break; + } + + case TodoUpdate.Description: + { + Console.WriteLine("Enter the New Description: "); + string? newDescription = Console.ReadLine(); + if (!string.IsNullOrWhiteSpace(newDescription)) + { + todo.Description = newDescription; + } + break; + } + + case TodoUpdate.Priority: + { + var newPriority = Prompt.Select("Select new Priority."); + todo.Priority = newPriority; + break; + } + + case TodoUpdate.DueDate: + { + Console.WriteLine("Enter the New Due Date: "); + string? newDueDate = Console.ReadLine(); + if (Validate.DueDate(newDueDate)) + { + if (!Validate.TodoErrors()) + { + todo.DueDate = DateTimeOffset.Parse(newDueDate!); + } + } + break; + } + } + } } } \ No newline at end of file diff --git a/src/EasyList/Validate.cs b/src/EasyList/Validate.cs new file mode 100644 index 0000000..00e5790 --- /dev/null +++ b/src/EasyList/Validate.cs @@ -0,0 +1,76 @@ +using EasyList; +using EasyList.DataModels; +using System; +using System.Collections.Generic; +using System.Linq; + +public static class Validate +{ + static List errors = new List(); + public static bool TodoErrors() + { + if (errors.Any()) + { + Console.WriteLine("The input has the following errors:"); + foreach (var error in errors) + { + Console.WriteLine("\t" + error); + } + + return true; + } + return false; + } + public static void Add(Dictionary input) + { + Label(input["label"]); + DueDate(input["duedate"]); + } + + public static bool DueDate(string? input) + { + if (DateTimeOffset.TryParse(input, out DateTimeOffset tempDate)) + { + if (tempDate < DateTime.UtcNow) + { + errors.Add("Due date cannot be in the past"); + return false; + } + } + return true; + } + + public static bool Label(string? input) + { + if (string.IsNullOrWhiteSpace(input)) + { + errors.Add("Label cannot be empty"); + return false; + } + return true; + } + + public static IEnumerable MultipleIds(IEnumerable todoIdList) + { + var validTodoList = new List(); + foreach (var todoId in todoIdList) + { + Todo? tempTodo = Id(todoId); + if (tempTodo != null) + { + validTodoList.Add(tempTodo); + } + } + return validTodoList; + } + + public static Todo? Id(int todoId) + { + Todo? todoView = Program._todoService.GetTodoByID(todoId); + if (todoView == null) + { + errors.Add($"Invalid Id #{todoId}"); + } + return todoView; + } +} From 2f07ce304cb426edab23c1bd5ceccebdff2bf8d0 Mon Sep 17 00:00:00 2001 From: 18-F-cali Date: Thu, 12 Aug 2021 22:38:00 +0530 Subject: [PATCH 5/9] Implemented Update Commands. Refactored Validate Commands. --- src/EasyList/Enums/TodoMenuOptions.cs | 1 + src/EasyList/Enums/TodoUpdate.cs | 10 +++ src/EasyList/Interfaces/ITodoService.cs | 1 + src/EasyList/Program.cs | 7 +- src/EasyList/TodoMenu.cs | 109 ++++++++---------------- src/EasyList/TodoServiceDB.cs | 56 +++++++++++- src/EasyList/TodoServiceInMemory.cs | 53 +++++++++++- src/EasyList/Utility.cs | 16 ++++ src/EasyList/Validate.cs | 76 +++++++++++++++++ 9 files changed, 254 insertions(+), 75 deletions(-) create mode 100644 src/EasyList/Enums/TodoUpdate.cs create mode 100644 src/EasyList/Utility.cs create mode 100644 src/EasyList/Validate.cs diff --git a/src/EasyList/Enums/TodoMenuOptions.cs b/src/EasyList/Enums/TodoMenuOptions.cs index b2c5826..bcb58aa 100644 --- a/src/EasyList/Enums/TodoMenuOptions.cs +++ b/src/EasyList/Enums/TodoMenuOptions.cs @@ -7,6 +7,7 @@ public enum TODOMENU View, MarkAsDone, ListAll, + Update, Quit } } \ No newline at end of file diff --git a/src/EasyList/Enums/TodoUpdate.cs b/src/EasyList/Enums/TodoUpdate.cs new file mode 100644 index 0000000..401b523 --- /dev/null +++ b/src/EasyList/Enums/TodoUpdate.cs @@ -0,0 +1,10 @@ +namespace EasyList +{ + public enum TodoUpdate + { + Label, + Description, + Priority, + DueDate + } +} \ No newline at end of file diff --git a/src/EasyList/Interfaces/ITodoService.cs b/src/EasyList/Interfaces/ITodoService.cs index d657901..c630c38 100644 --- a/src/EasyList/Interfaces/ITodoService.cs +++ b/src/EasyList/Interfaces/ITodoService.cs @@ -11,5 +11,6 @@ internal interface ITodoService void DisplayAllTodo(TodoOrder todoOrder); Todo? GetTodoByID(int id); void MarkTodoAsDone(Todo todo); + void UpdateTodo(Todo todo, TodoUpdate command); } } \ No newline at end of file diff --git a/src/EasyList/Program.cs b/src/EasyList/Program.cs index 7e06e05..a44c91a 100644 --- a/src/EasyList/Program.cs +++ b/src/EasyList/Program.cs @@ -1,7 +1,12 @@ -namespace EasyList +using EasyList.Factories; +using EasyList.Interfaces; + +namespace EasyList { class Program { + public static ITodoService _todoService = Factory.CreateTodoServiceDB(); + public static void Main(string[] args) { if(args.Length > 1) diff --git a/src/EasyList/TodoMenu.cs b/src/EasyList/TodoMenu.cs index 599487d..1586f90 100644 --- a/src/EasyList/TodoMenu.cs +++ b/src/EasyList/TodoMenu.cs @@ -11,46 +11,11 @@ namespace EasyList { public class TodoMenu { - private static IEnumerable ValidateAdd(Dictionary input) - { - if (string.IsNullOrWhiteSpace(input["label"])) - { - yield return "Label cannot be empty"; - } - if (DateTimeOffset.TryParse(input["duedate"], out DateTimeOffset tempDate)) - { - if (tempDate < DateTime.UtcNow) - { - yield return "Due date cannot be in the past"; - } - } - } - - private static bool Validate(TODOMENU command, Dictionary input) - { - var errors = command switch { - TODOMENU.Add => ValidateAdd(input), - // register the rest of the options that need to be validated here - _ => throw new InvalidOperationException($"No validator exists for {command}"), - }; - - if (errors.Any()) - { - Console.WriteLine("The input has the following errors:"); - foreach (var error in errors) - { - Console.WriteLine("\t"+error); - } - - return false; - } - - return true; - } + public static void Run() { - ITodoService _todoService = Factory.CreateTodoServiceDB(); + while(true) { var action = Prompt.Select("Welcome to EasyList!"); @@ -61,7 +26,9 @@ public static void Run() var inputAdd = Prompt.Input("Enter TODO "); var parsedAdd = ParseAdd.Parse(inputAdd?.Split() ?? Array.Empty()); - if (Validate(action, parsedAdd)) + Validate.Add(parsedAdd); + + if (!Validate.TodoErrors()) { var newTodo = new Todo() { @@ -70,64 +37,62 @@ public static void Run() DueDate = DateTimeOffset.TryParse(parsedAdd["duedate"], out DateTimeOffset tempDate) ? tempDate : null, Priority = Enum.Parse(parsedAdd["priority"]) }; - _todoService.AddTodo(newTodo); + Program._todoService.AddTodo(newTodo); } - break; case TODOMENU.Delete: - var inputDelete = Prompt.Input("Enter TODO ID(s) "); - foreach (var item in inputDelete.Split()) + var inputDelete = Prompt.Input("Enter TODO ID(s) ").Split(); + + var validDeleteList = Validate.MultipleIds(inputDelete.ToIntIds()); + + if (!Validate.TodoErrors()) { - var todoItem = _todoService.GetTodoByID(int.Parse(item)); - if(todoItem != null) - { - Console.WriteLine($"Deleted: {todoItem.Label}"); - _todoService.DeleteTodo(todoItem); - } - else + foreach (var todoDelete in validDeleteList) { - Console.WriteLine($"Todo Id: {item} Not Found."); - Console.WriteLine("Try Again."); - } - + Program._todoService.DeleteTodo(todoDelete); + } } break; case TODOMENU.View: var inputView = Prompt.Input("Enter TODO ID "); - var todo = _todoService.GetTodoByID(inputView); - if(todo != null) - { - _todoService.DisplayTodo(todo); - } - else + + var todoView = Validate.Id(inputView); + + if(!Validate.TodoErrors()) { - Console.WriteLine($"Todo Id: {inputView} Not Found."); + Program._todoService.DisplayTodo(todoView!); } break; case TODOMENU.MarkAsDone: - var inputDone = Prompt.Input("Enter TODO ID(s) "); - foreach (var item in inputDone.Split()) + var inputDone = Prompt.Input("Enter TODO ID(s) ").Split(); + + var validTodoList = Validate.MultipleIds(inputDone.ToIntIds()); + + if (!Validate.TodoErrors()) { - var todoItem = _todoService.GetTodoByID(int.Parse(item)); - if(todoItem != null) - { - Console.WriteLine($"Completed:{todoItem.Label}."); - _todoService.MarkTodoAsDone(todoItem); - } - else + foreach (var todoDelete in validTodoList) { - Console.WriteLine($"Todo Id: {item} Not Found."); - Console.WriteLine("Try Again."); + Program._todoService.MarkTodoAsDone(todoDelete); } } break; + case TODOMENU.Update: + var inputUpdateAction = Prompt.Select("Select Update Action"); + var inputUpdate = Prompt.Input("Enter the ID to Update"); + var validTodo = Validate.Id(inputUpdate); + + if (!Validate.TodoErrors()) + { + Program._todoService.UpdateTodo(validTodo!, inputUpdateAction); + } + break; case TODOMENU.ListAll: var inputList = Prompt.Select("Select List Order: ", defaultValue: TodoOrder.CreateDate); - _todoService.DisplayAllTodo(inputList); + Program._todoService.DisplayAllTodo(inputList); break; case TODOMENU.Quit: Console.WriteLine("Exiting..."); diff --git a/src/EasyList/TodoServiceDB.cs b/src/EasyList/TodoServiceDB.cs index 101d9e5..daa4b75 100644 --- a/src/EasyList/TodoServiceDB.cs +++ b/src/EasyList/TodoServiceDB.cs @@ -4,6 +4,7 @@ using EasyList.Enums; using EasyList.Factories; using EasyList.Interfaces; +using Sharprompt; namespace EasyList { @@ -50,6 +51,59 @@ public void DisplayAllTodo(TodoOrder todoOrder) .Write(Format.MarkDown); } - + public void UpdateTodo(Todo todo, TodoUpdate command) + { + switch (command) + { + case TodoUpdate.Label: + { + Console.WriteLine("Enter the New Label: "); + string? newLabel = Console.ReadLine(); + if (Validate.Label(newLabel)) + { + if (!Validate.TodoErrors()) + { + todo.Label = newLabel!; + } + } + _todoRepository.UpdateTodo(todo); + break; + } + + case TodoUpdate.Description: + { + Console.WriteLine("Enter the New Description: "); + string? newDescription = Console.ReadLine(); + if (!string.IsNullOrWhiteSpace(newDescription)) + { + todo.Description = newDescription; + } + _todoRepository.UpdateTodo(todo); + break; + } + + case TodoUpdate.Priority: + { + todo.Priority = Prompt.Select("Select new Priority."); ; + _todoRepository.UpdateTodo(todo); + break; + } + + case TodoUpdate.DueDate: + { + Console.WriteLine("Enter the New Due Date: "); + string? newDueDate = Console.ReadLine(); + if(Validate.DueDate(newDueDate)) + { + if (!Validate.TodoErrors()) + { + todo.DueDate = DateTimeOffset.Parse(newDueDate!); + } + } + _todoRepository.UpdateTodo(todo); + break; + } + } + } } } \ No newline at end of file diff --git a/src/EasyList/TodoServiceInMemory.cs b/src/EasyList/TodoServiceInMemory.cs index a74891d..764e0a9 100644 --- a/src/EasyList/TodoServiceInMemory.cs +++ b/src/EasyList/TodoServiceInMemory.cs @@ -4,6 +4,7 @@ using EasyList.Enums; using EasyList.Factories; using EasyList.Interfaces; +using Sharprompt; namespace EasyList { @@ -48,6 +49,56 @@ public void DisplayAllTodo(TodoOrder todoOrder) .Write(Format.MarkDown); } - + public void UpdateTodo(Todo todo, TodoUpdate command) + { + switch (command) + { + case TodoUpdate.Label: + { + Console.WriteLine("Enter the New Label: "); + string? newLabel = Console.ReadLine(); + if (Validate.Label(newLabel)) + { + if (!Validate.TodoErrors()) + { + todo.Label = newLabel!; + } + } + break; + } + + case TodoUpdate.Description: + { + Console.WriteLine("Enter the New Description: "); + string? newDescription = Console.ReadLine(); + if (!string.IsNullOrWhiteSpace(newDescription)) + { + todo.Description = newDescription; + } + break; + } + + case TodoUpdate.Priority: + { + var newPriority = Prompt.Select("Select new Priority."); + todo.Priority = newPriority; + break; + } + + case TodoUpdate.DueDate: + { + Console.WriteLine("Enter the New Due Date: "); + string? newDueDate = Console.ReadLine(); + if (Validate.DueDate(newDueDate)) + { + if (!Validate.TodoErrors()) + { + todo.DueDate = DateTimeOffset.Parse(newDueDate!); + } + } + break; + } + } + } } } \ No newline at end of file diff --git a/src/EasyList/Utility.cs b/src/EasyList/Utility.cs new file mode 100644 index 0000000..b6cd873 --- /dev/null +++ b/src/EasyList/Utility.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +public static class Utility +{ + public static IEnumerable ToIntIds(this string[] input) + { + foreach (var item in input) + { + if (int.TryParse(item, out int num)) + { + yield return num; + } + } + } +} diff --git a/src/EasyList/Validate.cs b/src/EasyList/Validate.cs new file mode 100644 index 0000000..00e5790 --- /dev/null +++ b/src/EasyList/Validate.cs @@ -0,0 +1,76 @@ +using EasyList; +using EasyList.DataModels; +using System; +using System.Collections.Generic; +using System.Linq; + +public static class Validate +{ + static List errors = new List(); + public static bool TodoErrors() + { + if (errors.Any()) + { + Console.WriteLine("The input has the following errors:"); + foreach (var error in errors) + { + Console.WriteLine("\t" + error); + } + + return true; + } + return false; + } + public static void Add(Dictionary input) + { + Label(input["label"]); + DueDate(input["duedate"]); + } + + public static bool DueDate(string? input) + { + if (DateTimeOffset.TryParse(input, out DateTimeOffset tempDate)) + { + if (tempDate < DateTime.UtcNow) + { + errors.Add("Due date cannot be in the past"); + return false; + } + } + return true; + } + + public static bool Label(string? input) + { + if (string.IsNullOrWhiteSpace(input)) + { + errors.Add("Label cannot be empty"); + return false; + } + return true; + } + + public static IEnumerable MultipleIds(IEnumerable todoIdList) + { + var validTodoList = new List(); + foreach (var todoId in todoIdList) + { + Todo? tempTodo = Id(todoId); + if (tempTodo != null) + { + validTodoList.Add(tempTodo); + } + } + return validTodoList; + } + + public static Todo? Id(int todoId) + { + Todo? todoView = Program._todoService.GetTodoByID(todoId); + if (todoView == null) + { + errors.Add($"Invalid Id #{todoId}"); + } + return todoView; + } +} From 479f61085a758832115e08c1972937cbc844b577 Mon Sep 17 00:00:00 2001 From: 18-F-cali <63421973+18-F-cali@users.noreply.github.com> Date: Fri, 13 Aug 2021 22:23:56 +0530 Subject: [PATCH 6/9] Delete EasyList.Tests.csproj --- src/EasyList.Tests/EasyList.Tests.csproj | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/EasyList.Tests/EasyList.Tests.csproj diff --git a/src/EasyList.Tests/EasyList.Tests.csproj b/src/EasyList.Tests/EasyList.Tests.csproj deleted file mode 100644 index cc7744a..0000000 --- a/src/EasyList.Tests/EasyList.Tests.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - net5.0 - - false - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - From 0f1c464893e052ce933deb96a41853ab77fe2c4f Mon Sep 17 00:00:00 2001 From: 18-F-cali <63421973+18-F-cali@users.noreply.github.com> Date: Fri, 13 Aug 2021 22:24:10 +0530 Subject: [PATCH 7/9] Delete UnitTest1.cs --- src/EasyList.Tests/UnitTest1.cs | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/EasyList.Tests/UnitTest1.cs diff --git a/src/EasyList.Tests/UnitTest1.cs b/src/EasyList.Tests/UnitTest1.cs deleted file mode 100644 index e84c870..0000000 --- a/src/EasyList.Tests/UnitTest1.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Xunit; - -namespace EasyList.Tests -{ - public class UnitTest1 - { - [Fact] - public void Test1() - { - - } - } -} From 9cf2a9accc36b16f0c8ac363798c2808eeaede88 Mon Sep 17 00:00:00 2001 From: 18-F-cali Date: Sun, 15 Aug 2021 13:24:58 +0530 Subject: [PATCH 8/9] changed _todoService to TodoService property. --- src/EasyList/Program.cs | 2 +- src/EasyList/TodoMenu.cs | 12 ++++++------ src/EasyList/Validate.cs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/EasyList/Program.cs b/src/EasyList/Program.cs index a44c91a..6e9ecc7 100644 --- a/src/EasyList/Program.cs +++ b/src/EasyList/Program.cs @@ -5,7 +5,7 @@ namespace EasyList { class Program { - public static ITodoService _todoService = Factory.CreateTodoServiceDB(); + public static ITodoService TodoService => Factory.CreateTodoServiceDB(); public static void Main(string[] args) { diff --git a/src/EasyList/TodoMenu.cs b/src/EasyList/TodoMenu.cs index ca3097e..b3cef28 100644 --- a/src/EasyList/TodoMenu.cs +++ b/src/EasyList/TodoMenu.cs @@ -35,7 +35,7 @@ public static void Run() DueDate = DateTimeOffset.TryParse(parsedAdd["duedate"], out DateTimeOffset tempDate) ? tempDate : null, Priority = Enum.Parse(parsedAdd["priority"]) }; - Program._todoService.AddTodo(newTodo); + Program.TodoService.AddTodo(newTodo); } break; @@ -48,7 +48,7 @@ public static void Run() { foreach (var todoDelete in validDeleteList) { - Program._todoService.DeleteTodo(todoDelete); + Program.TodoService.DeleteTodo(todoDelete); } } break; @@ -60,7 +60,7 @@ public static void Run() if(!Validate.TodoErrors()) { - Program._todoService.DisplayTodo(todoView!); + Program.TodoService.DisplayTodo(todoView!); } break; @@ -73,7 +73,7 @@ public static void Run() { foreach (var todoDelete in validTodoList) { - Program._todoService.MarkTodoAsDone(todoDelete); + Program.TodoService.MarkTodoAsDone(todoDelete); } } break; @@ -85,12 +85,12 @@ public static void Run() if (!Validate.TodoErrors()) { - Program._todoService.UpdateTodo(validTodo!, inputUpdateAction); + Program.TodoService.UpdateTodo(validTodo!, inputUpdateAction); } break; case TODOMENU.ListAll: var inputList = Prompt.Select("Select List Order: ", defaultValue: TodoOrder.CreateDate); - Program._todoService.DisplayAllTodo(inputList); + Program.TodoService.DisplayAllTodo(inputList); break; case TODOMENU.Quit: Console.WriteLine("Exiting..."); diff --git a/src/EasyList/Validate.cs b/src/EasyList/Validate.cs index 00e5790..23fb1e8 100644 --- a/src/EasyList/Validate.cs +++ b/src/EasyList/Validate.cs @@ -66,7 +66,7 @@ public static IEnumerable MultipleIds(IEnumerable todoIdList) public static Todo? Id(int todoId) { - Todo? todoView = Program._todoService.GetTodoByID(todoId); + Todo? todoView = Program.TodoService.GetTodoByID(todoId); if (todoView == null) { errors.Add($"Invalid Id #{todoId}"); From 936a3c2532cdd5cc48a4a7603a8fadc060098ab1 Mon Sep 17 00:00:00 2001 From: 18-F-cali Date: Thu, 19 Aug 2021 18:45:13 +0530 Subject: [PATCH 9/9] Updated Validation Logic --- src/EasyList/ParseAdd.cs | 2 +- src/EasyList/TodoMenu.cs | 107 ++++++++++--------- src/EasyList/TodoServiceDB.cs | 27 +++-- src/EasyList/TodoServiceInMemory.cs | 22 ++-- src/EasyList/Utility.cs | 13 ++- src/EasyList/Validate.cs | 155 +++++++++++++++++++--------- 6 files changed, 193 insertions(+), 133 deletions(-) diff --git a/src/EasyList/ParseAdd.cs b/src/EasyList/ParseAdd.cs index eeeeec1..8f36748 100644 --- a/src/EasyList/ParseAdd.cs +++ b/src/EasyList/ParseAdd.cs @@ -54,7 +54,7 @@ public static Dictionary Parse(string[] args) string label = GetData("add", args, positions) ?? string.Empty; string description = GetData("-d", args, positions) ?? string.Empty; string dueDate = GetData("-t", args, positions) ?? string.Empty; - string priority = GetData("-p", args, positions) ?? "${TodoPriority.Low}"; + string priority = GetData("-p", args, positions) ?? $"{TodoPriority.Low}"; return new Dictionary { {"label" ,label }, diff --git a/src/EasyList/TodoMenu.cs b/src/EasyList/TodoMenu.cs index b3cef28..8b82bcc 100644 --- a/src/EasyList/TodoMenu.cs +++ b/src/EasyList/TodoMenu.cs @@ -1,52 +1,48 @@ using EasyList.DataModels; using EasyList.Enums; -using EasyList.Factories; -using EasyList.Interfaces; using Sharprompt; using System; using System.Collections.Generic; -using System.Linq; namespace EasyList { public class TodoMenu { + public static void Run() { - - while(true) + var _todoValidate = new Validate(); + while (true) { var action = Prompt.Select("Welcome to EasyList!"); //Refactor this such that adding new should not modify this input layer switch (action) { + case TODOMENU.Add: - var inputAdd = Prompt.Input("Enter TODO "); - var parsedAdd = ParseAdd.Parse(inputAdd?.Split() ?? Array.Empty()); - - Validate.Add(parsedAdd); - - if (!Validate.TodoErrors()) { - var newTodo = new Todo() + var inputAdd = Prompt.Input("Enter TODO "); + var parsedAdd = ParseAdd.Parse(inputAdd?.Split() ?? Array.Empty()); + + if (_todoValidate.IsAddValid(parsedAdd)) { - Label = parsedAdd["label"], - Description = parsedAdd["description"], - DueDate = DateTimeOffset.TryParse(parsedAdd["duedate"], out DateTimeOffset tempDate) ? tempDate : null, - Priority = Enum.Parse(parsedAdd["priority"]) - }; - Program.TodoService.AddTodo(newTodo); + var newTodo = new Todo() + { + Label = parsedAdd["label"], + Description = parsedAdd["description"], + DueDate = DateTimeOffset.TryParse(parsedAdd["duedate"], out DateTimeOffset tempDate) ? tempDate : null, + Priority = Enum.Parse(parsedAdd["priority"]) + }; + Program.TodoService.AddTodo(newTodo); + } + break; } - break; - case TODOMENU.Delete: var inputDelete = Prompt.Input("Enter TODO ID(s) ").Split(); - - var validDeleteList = Validate.MultipleIds(inputDelete.ToIntIds()); - if (!Validate.TodoErrors()) + if (_todoValidate.IsDeleteValid(inputDelete,out List todoDeleteList)) { - foreach (var todoDelete in validDeleteList) + foreach (var todoDelete in todoDeleteList) { Program.TodoService.DeleteTodo(todoDelete); } @@ -54,48 +50,51 @@ public static void Run() break; case TODOMENU.View: - var inputView = Prompt.Input("Enter TODO ID "); - - var todoView = Validate.Id(inputView); - - if(!Validate.TodoErrors()) { - Program.TodoService.DisplayTodo(todoView!); + var inputView = Prompt.Input("Enter TODO ID "); + + if (_todoValidate.IsReadValid(inputView, out Todo validTodo)) + { + Program.TodoService.DisplayTodo(validTodo); + } + break; } - break; - case TODOMENU.MarkAsDone: - var inputDone = Prompt.Input("Enter TODO ID(s) ").Split(); - - var validTodoList = Validate.MultipleIds(inputDone.ToIntIds()); - - if (!Validate.TodoErrors()) { - foreach (var todoDelete in validTodoList) + var inputDone = Prompt.Input("Enter TODO ID(s) ").Split(); + + if (_todoValidate.CanMarkAsDone(inputDone, out List doneTodoList)) { - Program.TodoService.MarkTodoAsDone(todoDelete); + foreach (var doneTodo in doneTodoList) + { + Program.TodoService.MarkTodoAsDone(doneTodo); + } } + break; } - break; case TODOMENU.Update: - var inputUpdateAction = Prompt.Select("Select Update Action"); - var inputUpdate = Prompt.Input("Enter the ID to Update"); - - var validTodo = Validate.Id(inputUpdate); - - if (!Validate.TodoErrors()) { - Program.TodoService.UpdateTodo(validTodo!, inputUpdateAction); + var inputUpdateAction = Prompt.Select("Select Update Action"); + var inputUpdate = Prompt.Input("Enter the ID to Update"); + + if (_todoValidate.IsReadValid(inputUpdate, out Todo validTodo)) + { + Program.TodoService.UpdateTodo(validTodo, inputUpdateAction); + } + break; } - break; case TODOMENU.ListAll: - var inputList = Prompt.Select("Select List Order: ", defaultValue: TodoOrder.CreateDate); - Program.TodoService.DisplayAllTodo(inputList); - break; + { + var inputList = Prompt.Select("Select List Order: ", defaultValue: TodoOrder.CreateDate); + Program.TodoService.DisplayAllTodo(inputList); + break; + } case TODOMENU.Quit: - Console.WriteLine("Exiting..."); - Environment.Exit(Environment.ExitCode = 0); - break; + { + Console.WriteLine("Exiting..."); + Environment.Exit(Environment.ExitCode = 0); + break; + } } Console.ReadLine(); diff --git a/src/EasyList/TodoServiceDB.cs b/src/EasyList/TodoServiceDB.cs index daa4b75..4d5bf87 100644 --- a/src/EasyList/TodoServiceDB.cs +++ b/src/EasyList/TodoServiceDB.cs @@ -53,20 +53,19 @@ public void DisplayAllTodo(TodoOrder todoOrder) public void UpdateTodo(Todo todo, TodoUpdate command) { + var _todoValidate = new Validate(); switch (command) { case TodoUpdate.Label: { Console.WriteLine("Enter the New Label: "); string? newLabel = Console.ReadLine(); - if (Validate.Label(newLabel)) + if (_todoValidate.IsLabelValid(newLabel)) { - if (!Validate.TodoErrors()) - { - todo.Label = newLabel!; - } + todo.Label = newLabel; + _todoRepository.UpdateTodo(todo); + Console.WriteLine("Label Updated Sucessfully."); } - _todoRepository.UpdateTodo(todo); break; } @@ -74,11 +73,12 @@ public void UpdateTodo(Todo todo, TodoUpdate command) { Console.WriteLine("Enter the New Description: "); string? newDescription = Console.ReadLine(); - if (!string.IsNullOrWhiteSpace(newDescription)) + if (_todoValidate.IsUpdateDescriptionValid(newDescription)) { todo.Description = newDescription; + _todoRepository.UpdateTodo(todo); + Console.WriteLine("Description Updated Sucessfully."); } - _todoRepository.UpdateTodo(todo); break; } @@ -93,14 +93,13 @@ public void UpdateTodo(Todo todo, TodoUpdate command) { Console.WriteLine("Enter the New Due Date: "); string? newDueDate = Console.ReadLine(); - if(Validate.DueDate(newDueDate)) + if(_todoValidate.IsDueDateValid(newDueDate)) { - if (!Validate.TodoErrors()) - { - todo.DueDate = DateTimeOffset.Parse(newDueDate!); - } + + todo.DueDate = DateTimeOffset.Parse(newDueDate!); + _todoRepository.UpdateTodo(todo); + Console.WriteLine("Due Date Updated Sucessfully."); } - _todoRepository.UpdateTodo(todo); break; } } diff --git a/src/EasyList/TodoServiceInMemory.cs b/src/EasyList/TodoServiceInMemory.cs index 764e0a9..d4646c1 100644 --- a/src/EasyList/TodoServiceInMemory.cs +++ b/src/EasyList/TodoServiceInMemory.cs @@ -51,18 +51,18 @@ public void DisplayAllTodo(TodoOrder todoOrder) public void UpdateTodo(Todo todo, TodoUpdate command) { + var _todoValidate = new Validate(); switch (command) { case TodoUpdate.Label: { Console.WriteLine("Enter the New Label: "); string? newLabel = Console.ReadLine(); - if (Validate.Label(newLabel)) + if (_todoValidate.IsLabelValid(newLabel)) { - if (!Validate.TodoErrors()) - { - todo.Label = newLabel!; - } + todo.Label = newLabel!; + Console.WriteLine("Label Updated Sucessfully."); + } break; } @@ -71,9 +71,10 @@ public void UpdateTodo(Todo todo, TodoUpdate command) { Console.WriteLine("Enter the New Description: "); string? newDescription = Console.ReadLine(); - if (!string.IsNullOrWhiteSpace(newDescription)) + if (_todoValidate.IsUpdateDescriptionValid(newDescription)) { todo.Description = newDescription; + Console.WriteLine("Description Updated Sucessfully."); } break; } @@ -89,12 +90,11 @@ public void UpdateTodo(Todo todo, TodoUpdate command) { Console.WriteLine("Enter the New Due Date: "); string? newDueDate = Console.ReadLine(); - if (Validate.DueDate(newDueDate)) + if (_todoValidate.IsDueDateValid(newDueDate)) { - if (!Validate.TodoErrors()) - { - todo.DueDate = DateTimeOffset.Parse(newDueDate!); - } + + todo.DueDate = DateTimeOffset.Parse(newDueDate!); + Console.WriteLine("Due Date Updated Sucessfully."); } break; } diff --git a/src/EasyList/Utility.cs b/src/EasyList/Utility.cs index b6cd873..0ee3498 100644 --- a/src/EasyList/Utility.cs +++ b/src/EasyList/Utility.cs @@ -1,15 +1,18 @@ using System; using System.Collections.Generic; -public static class Utility +namespace EasyList { - public static IEnumerable ToIntIds(this string[] input) + public static class Utility { - foreach (var item in input) + public static IEnumerable ToIntIds(this string[] input) { - if (int.TryParse(item, out int num)) + foreach (var item in input) { - yield return num; + if (int.TryParse(item, out int num)) + { + yield return num; + } } } } diff --git a/src/EasyList/Validate.cs b/src/EasyList/Validate.cs index 23fb1e8..dd9faf7 100644 --- a/src/EasyList/Validate.cs +++ b/src/EasyList/Validate.cs @@ -1,76 +1,135 @@ using EasyList; using EasyList.DataModels; +using Sharprompt; using System; using System.Collections.Generic; using System.Linq; +using System.Threading; -public static class Validate +namespace EasyList { - static List errors = new List(); - public static bool TodoErrors() - { - if (errors.Any()) + public class Validate + { + private static bool IsErrorFree(IEnumerable errors) { - Console.WriteLine("The input has the following errors:"); - foreach (var error in errors) + if (errors.Any()) { - Console.WriteLine("\t" + error); - } + Console.WriteLine("The input has the following errors:"); + foreach (var error in errors) + { + Console.WriteLine($"\t{error}"); + } + return false; + } return true; } - return false; - } - public static void Add(Dictionary input) - { - Label(input["label"]); - DueDate(input["duedate"]); - } - - public static bool DueDate(string? input) - { - if (DateTimeOffset.TryParse(input, out DateTimeOffset tempDate)) + + private void ValidateDueDate(string? input, List errors) { - if (tempDate < DateTime.UtcNow) + if (!string.IsNullOrEmpty(input)) { - errors.Add("Due date cannot be in the past"); - return false; + if (DateTimeOffset.TryParse(input, out DateTimeOffset tempDate)) + { + //do better + if (tempDate < DateTime.UtcNow) + { + errors.Add("Due date cannot be in the past"); + } + return; + } + errors.Add("Couldn't Parse Due Date."); } + } - return true; - } - public static bool Label(string? input) - { - if (string.IsNullOrWhiteSpace(input)) + private void ValidateLabel(string? input, List errors) { - errors.Add("Label cannot be empty"); - return false; + if (string.IsNullOrWhiteSpace(input)) + { + errors.Add("Label cannot be empty"); + } } - return true; - } - public static IEnumerable MultipleIds(IEnumerable todoIdList) - { - var validTodoList = new List(); - foreach (var todoId in todoIdList) + public bool IsAddValid(Dictionary toAdd) + { + var errors = new List(); + ValidateLabel(toAdd["label"], errors); + ValidateDueDate(toAdd["duedate"], errors); + + return IsErrorFree(errors); + } + + public bool IsDeleteValid(IEnumerable inputDelete, out List validTodos) + { + validTodos = new List(); + return ValidateMultipleIDs(inputDelete,validTodos); + } + private bool ValidateId(string todoId, List errors,ref Todo? _todo) + { + if (!int.TryParse(todoId, out int validId)) + { + errors.Add($"Couldn't Parse {todoId}"); + return false; + } + _todo = Program.TodoService.GetTodoByID(validId); + if (_todo == null) + { + errors.Add($"Invalid Id #{validId}"); + return false; + } + return true; + } + private bool ValidateMultipleIDs(IEnumerable inputDelete, List validTodos) { - Todo? tempTodo = Id(todoId); - if (tempTodo != null) + var errors = new List(); + foreach (var todoId in inputDelete) + { + Todo? _todo = null; + if (ValidateId(todoId,errors,ref _todo)) + { + validTodos.Add(_todo!); + } + } + if (IsErrorFree(errors)) { - validTodoList.Add(tempTodo); + return true; } + Console.Clear(); + var choice = Prompt.Confirm("Continue with Valid Ids ? "); + Thread.Sleep(1500); + return choice; } - return validTodoList; - } - public static Todo? Id(int todoId) - { - Todo? todoView = Program.TodoService.GetTodoByID(todoId); - if (todoView == null) + public bool CanMarkAsDone(IEnumerable inputUpdate, out List validTodos) { - errors.Add($"Invalid Id #{todoId}"); + validTodos = new List(); + return ValidateMultipleIDs(inputUpdate,validTodos); } - return todoView; + public bool IsReadValid(string todoID,out Todo validTodo) + { + var errors = new List(); + validTodo = null; + ValidateId(todoID, errors,ref validTodo); + return IsErrorFree(errors); + } + + public bool IsLabelValid(string label) + { + var errors = new List(); + ValidateLabel(label, errors); + return IsErrorFree(errors); + } + public bool IsDueDateValid(string dueDate) + { + var errors = new List(); + ValidateDueDate(dueDate, errors); + return IsErrorFree(errors); + } + public bool IsUpdateDescriptionValid(string description) + { + return string.IsNullOrWhiteSpace(description); + } + } -} +} \ No newline at end of file