From bfce4e914bee4971cfcf93f858b99bdd627dd714 Mon Sep 17 00:00:00 2001 From: MalekLahbib Date: Thu, 21 Mar 2024 18:23:37 +0100 Subject: [PATCH 1/7] added todolist pckg and realm --- examples/gno.land/p/demo/todolist/gno.mod | 6 + .../gno.land/p/demo/todolist/todolist.gno | 68 +++++++ .../p/demo/todolist/todolist_test.gno | 51 +++++ examples/gno.land/r/demo/todolist/gno.mod | 7 + .../gno.land/r/demo/todolist/todolist.gno | 188 ++++++++++++++++++ 5 files changed, 320 insertions(+) create mode 100644 examples/gno.land/p/demo/todolist/gno.mod create mode 100644 examples/gno.land/p/demo/todolist/todolist.gno create mode 100644 examples/gno.land/p/demo/todolist/todolist_test.gno create mode 100644 examples/gno.land/r/demo/todolist/gno.mod create mode 100644 examples/gno.land/r/demo/todolist/todolist.gno diff --git a/examples/gno.land/p/demo/todolist/gno.mod b/examples/gno.land/p/demo/todolist/gno.mod new file mode 100644 index 00000000000..ffd0ed437e1 --- /dev/null +++ b/examples/gno.land/p/demo/todolist/gno.mod @@ -0,0 +1,6 @@ +module gno.land/p/demo/todolist + +require ( + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest +) diff --git a/examples/gno.land/p/demo/todolist/todolist.gno b/examples/gno.land/p/demo/todolist/todolist.gno new file mode 100644 index 00000000000..5bde86896bc --- /dev/null +++ b/examples/gno.land/p/demo/todolist/todolist.gno @@ -0,0 +1,68 @@ +package todolist + +import ( + "std" + "strconv" + + "gno.land/p/demo/avl" + "gno.land/p/demo/ufmt" +) + +type TodoList struct { + Title string + Tasks avl.Tree + Owner std.Address +} + +type Task struct { + Title string + Done bool +} + +func NewTodoList(title string) *TodoList { + return &TodoList{ + Title: title, + Tasks: avl.Tree{}, + Owner: std.GetOrigCaller(), + } +} + +func NewTask(title string) *Task { + return &Task{ + Title: title, + Done: false, + } +} + +func (tl *TodoList) AddTask(id int, task *Task) { + tl.Tasks.Set(strconv.Itoa(id), task) +} + +func ToggleTaskStatus(task *Task) { + task.Done = !task.Done +} + +func (tl *TodoList) RemoveTask(taskId string) { + tl.Tasks.Remove(taskId) +} + +func (tl *TodoList) GetTasks() []*Task { + tasks := make([]*Task, 0, tl.Tasks.Size()) + tl.Tasks.Iterate("", "", func(key string, value interface{}) bool { + tasks = append(tasks, value.(*Task)) + return false + }) + return tasks +} + +func (tl *TodoList) String() string { + return ufmt.Sprintf("TodoList{Title: %q, Tasks: %v, Owner: %v}", tl.Title, tl.GetTasks(), tl.Owner) +} + +func (tl *TodoList) GetTodolistOwner() std.Address { + return tl.Owner +} + +func (tl *TodoList) GetTodolistTitle() string { + return tl.Title +} diff --git a/examples/gno.land/p/demo/todolist/todolist_test.gno b/examples/gno.land/p/demo/todolist/todolist_test.gno new file mode 100644 index 00000000000..3193892bc28 --- /dev/null +++ b/examples/gno.land/p/demo/todolist/todolist_test.gno @@ -0,0 +1,51 @@ +package todolist + +import ( + "testing" + + "gno.land/p/demo/avl" +) + +func TestTodolistNew(t *testing.T) { + newtl := &TodoList{ + Title: "new todolist", + Tasks: avl.Tree{}, + } + tl := NewTodoList("new todolist") + if tl.Title != newtl.Title { + t.Fatalf("title is not good") + } + if tl.Tasks != newtl.Tasks { + t.Fatalf("tasks not good") + } + + // test new task + newtask := &Task{ + Title: "new task", + Done: false, + } + nt := NewTask("new task") + if nt.Title != newtask.Title { + t.Fatalf("title is not good") + } + if nt.Done != newtask.Done { + t.Fatalf("done is not good") + } + + // test add a task + id := tl.Tasks.Size() + tl.AddTask(id, nt) + if tl.Tasks.Size() != 1 { + t.Fatalf("task not added") + } + + // test ToggleTaskStatus + task, exists := tl.Tasks.Get("0") + if !exists { + t.Fatalf("task not found") + } + ToggleTaskStatus(task.(*Task)) + if task.(*Task).Done != true { + t.Fatalf("task not toggled") + } +} diff --git a/examples/gno.land/r/demo/todolist/gno.mod b/examples/gno.land/r/demo/todolist/gno.mod new file mode 100644 index 00000000000..e23286a1402 --- /dev/null +++ b/examples/gno.land/r/demo/todolist/gno.mod @@ -0,0 +1,7 @@ +module gno.land/r/demo/todolist + +require ( + gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/todolist v0.0.0-latest + gno.land/p/demo/ufmt v0.0.0-latest +) diff --git a/examples/gno.land/r/demo/todolist/todolist.gno b/examples/gno.land/r/demo/todolist/todolist.gno new file mode 100644 index 00000000000..b4ab5df3e82 --- /dev/null +++ b/examples/gno.land/r/demo/todolist/todolist.gno @@ -0,0 +1,188 @@ +package todolist + +import ( + "bytes" + "std" + "strconv" + + "gno.land/p/demo/avl" + "gno.land/p/demo/todolist" + "gno.land/p/demo/ufmt" +) + +// State variables +var ( + todolistTree *avl.Tree + tlid int +) + +// Constructor +func init() { + todolistTree = avl.NewTree() +} + +func NewTodolist(title string) (int, string) { + // Get user who sent the transaction + txSender := std.GetOrigCaller() + + tl := todolist.NewTodoList(title) + // Update AVL tree with new state + success := todolistTree.Set(strconv.Itoa(tlid), tl) + tlid++ + return tlid-1, "created successfully" +} + +func AddTask(todolistID int, title string) string { + // Get user who sent the transaction + txSender := std.GetOrigCaller() + + // Get Todolist from AVL tree + tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) + if !ok { + return "Todolist not found" + } + + // get the number of tasks in the todolist + id := tl.(*todolist.TodoList).Tasks.Size() + + // create the task + task := todolist.NewTask(title) + + // Cast raw data from tree into Todolist struct + tl.(*todolist.TodoList).AddTask(id, task) + + return "task added successfully" +} + +func ToggleTaskStatus(todolistID int, taskID int) string { + // Get user who sent the transaction + // txSender := std.GetOrigCaller() + + // Get Todolist from AVL tree + tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) + if !ok { + return "Todolist not found" + } + + // Get the task from the todolist + task, ok := tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) + if !ok { + return "Task not found" + } + + // Change the status of the task + todolist.ToggleTaskStatus(task.(*todolist.Task)) + + return "task status changed successfully" +} + +func RemoveTask(todolistID int, taskID int) string { + // Get user who sent the transaction + // txSender := std.GetOrigCaller() + + // Get Todolist from AVL tree + tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) + if !ok { + return "Todolist not found" + } + + // Get the task from the todolist + task, ok := tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) + if !ok { + return "Task not found" + } + + // Change the status of the task + tl.(*todolist.TodoList).RemoveTask(strconv.Itoa(taskID)) + + return "task status changed successfully" +} + +func RemoveTodoList(todolistID int) string { + // Get user who sent the transaction + // txSender := std.GetOrigCaller() + + // Get Todolist from AVL tree + _, ok := todolistTree.Get(strconv.Itoa(todolistID)) + if !ok { + return "Todolist not found" + } + + // Remove the todolist + todolistTree.Remove(strconv.Itoa(todolistID)) + + return "Todolist removed successfully" +} + +func Render(path string) string { + if path == "" { + return renderHomepage() + } + + return "unknown page" +} + +func renderHomepage() string { + // Define empty buffer + var b bytes.Buffer + + b.WriteString("# Welcome to ToDolist\n\n") + + // If no todolists have been created + if todolistTree.Size() == 0 { + b.WriteString("### No todolists available currently!") + return b.String() + } + + // Iterate through AVL tree + todolistTree.Iterate("", "", func(key string, value interface{}) bool { + // cast raw data from tree into Todolist struct + tl := value.(*todolist.TodoList) + + // Add Todolist name + b.WriteString( + ufmt.Sprintf( + "## Todolist #%s: %s\n", + key, // Todolist ID + tl.GetTodolistTitle(), + ), + ) + + // Add Todolist owner + b.WriteString( + ufmt.Sprintf( + "#### Todolist owner : %s\n", + tl.GetTodolistOwner(), + ), + ) + + // List all todos that are currently Todolisted + if todos := tl.GetTasks(); len(todos) > 0 { + b.WriteString( + ufmt.Sprintf("Currently Todo tasks: %d\n\n", len(todos)), + ) + + for index, todo := range todos { + b.WriteString( + ufmt.Sprintf("#%d - %s ", index, todo.Title), + ) + if todo.Done { + b.WriteString( + "โ˜‘\n\n", + ) + } else { + b.WriteString( + "โ˜\n\n", + ) + } + } + } else { + b.WriteString("No tasks in this list currently\n") + } + + b.WriteString("\n") + return false + }) + + return b.String() +} From 49af02464d69b38d0aaeccf83158f667fbb53668 Mon Sep 17 00:00:00 2001 From: MalekLahbib Date: Fri, 22 Mar 2024 15:30:11 +0100 Subject: [PATCH 2/7] feat: Added todolist pkg and realm --- examples/gno.land/r/demo/todolist/todolist.gno | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/gno.land/r/demo/todolist/todolist.gno b/examples/gno.land/r/demo/todolist/todolist.gno index b4ab5df3e82..964d1e81377 100644 --- a/examples/gno.land/r/demo/todolist/todolist.gno +++ b/examples/gno.land/r/demo/todolist/todolist.gno @@ -2,7 +2,6 @@ package todolist import ( "bytes" - "std" "strconv" "gno.land/p/demo/avl" @@ -13,7 +12,7 @@ import ( // State variables var ( todolistTree *avl.Tree - tlid int + tlid int ) // Constructor @@ -23,18 +22,18 @@ func init() { func NewTodolist(title string) (int, string) { // Get user who sent the transaction - txSender := std.GetOrigCaller() + // txSender := std.GetOrigCaller() tl := todolist.NewTodoList(title) // Update AVL tree with new state - success := todolistTree.Set(strconv.Itoa(tlid), tl) + _ := todolistTree.Set(strconv.Itoa(tlid), tl) tlid++ - return tlid-1, "created successfully" + return tlid - 1, "created successfully" } func AddTask(todolistID int, title string) string { // Get user who sent the transaction - txSender := std.GetOrigCaller() + // txSender := std.GetOrigCaller() // Get Todolist from AVL tree tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) @@ -87,7 +86,7 @@ func RemoveTask(todolistID int, taskID int) string { } // Get the task from the todolist - task, ok := tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) + _, ok := tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) if !ok { return "Task not found" } From 5896691c9e10ca7ef6b7300a9e83e761abcbe1ab Mon Sep 17 00:00:00 2001 From: MalekLahbib Date: Fri, 22 Mar 2024 15:36:27 +0100 Subject: [PATCH 3/7] feat: Added todolist pkg and realm --- examples/gno.land/r/demo/todolist/todolist.gno | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/examples/gno.land/r/demo/todolist/todolist.gno b/examples/gno.land/r/demo/todolist/todolist.gno index 964d1e81377..c772055f51c 100644 --- a/examples/gno.land/r/demo/todolist/todolist.gno +++ b/examples/gno.land/r/demo/todolist/todolist.gno @@ -21,20 +21,15 @@ func init() { } func NewTodolist(title string) (int, string) { - // Get user who sent the transaction - // txSender := std.GetOrigCaller() - + // Create new Todolist tl := todolist.NewTodoList(title) // Update AVL tree with new state - _ := todolistTree.Set(strconv.Itoa(tlid), tl) + todolistTree.Set(strconv.Itoa(tlid), tl) tlid++ return tlid - 1, "created successfully" } func AddTask(todolistID int, title string) string { - // Get user who sent the transaction - // txSender := std.GetOrigCaller() - // Get Todolist from AVL tree tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) if !ok { @@ -54,9 +49,6 @@ func AddTask(todolistID int, title string) string { } func ToggleTaskStatus(todolistID int, taskID int) string { - // Get user who sent the transaction - // txSender := std.GetOrigCaller() - // Get Todolist from AVL tree tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) if !ok { From 049a77c584a04e3d03cb7afcac7bb860bc468dc5 Mon Sep 17 00:00:00 2001 From: MalekLahbib Date: Fri, 22 Mar 2024 15:43:02 +0100 Subject: [PATCH 4/7] feat: Added todolist pkg and realm --- examples/gno.land/r/demo/todolist/todolist.gno | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/r/demo/todolist/todolist.gno b/examples/gno.land/r/demo/todolist/todolist.gno index c772055f51c..1b309d87aca 100644 --- a/examples/gno.land/r/demo/todolist/todolist.gno +++ b/examples/gno.land/r/demo/todolist/todolist.gno @@ -56,8 +56,8 @@ func ToggleTaskStatus(todolistID int, taskID int) string { } // Get the task from the todolist - task, ok := tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) - if !ok { + task, found := tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) + if !found { return "Task not found" } @@ -78,7 +78,7 @@ func RemoveTask(todolistID int, taskID int) string { } // Get the task from the todolist - _, ok := tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) + _, ok = tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) if !ok { return "Task not found" } From 9df557d9f4b4e4c17db5b1525c1eaabcbc55237e Mon Sep 17 00:00:00 2001 From: MalekLahbib Date: Mon, 25 Mar 2024 11:05:02 +0100 Subject: [PATCH 5/7] fix: ufmt multi-byte fix. --- examples/gno.land/p/demo/ufmt/ufmt.gno | 18 ++++++++++-------- examples/gno.land/p/demo/ufmt/ufmt_test.gno | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/examples/gno.land/p/demo/ufmt/ufmt.gno b/examples/gno.land/p/demo/ufmt/ufmt.gno index 970fac2eccc..daf8bb11ab1 100644 --- a/examples/gno.land/p/demo/ufmt/ufmt.gno +++ b/examples/gno.land/p/demo/ufmt/ufmt.gno @@ -21,24 +21,26 @@ import "strconv" // %t: formats a boolean value to "true" or "false". // %%: outputs a literal %. Does not consume an argument. func Sprintf(format string, args ...interface{}) string { - end := len(format) + // we use runes to handle multi-byte characters + sTor := []rune(format) + end := len(sTor) argNum := 0 argLen := len(args) buf := "" for i := 0; i < end; { isLast := i == end-1 - c := format[i] + c := string(sTor[i]) - if isLast || c != '%' { + if isLast || c != "%" { // we don't check for invalid format like a one ending with "%" buf += string(c) i++ continue } - verb := format[i+1] - if verb == '%' { + verb := string(sTor[i+1]) + if verb == "%" { buf += "%" i += 2 continue @@ -51,7 +53,7 @@ func Sprintf(format string, args ...interface{}) string { argNum++ switch verb { - case 's': + case "s": switch v := arg.(type) { case interface{ String() string }: buf += v.String() @@ -60,7 +62,7 @@ func Sprintf(format string, args ...interface{}) string { default: buf += "(unhandled)" } - case 'd': + case "d": switch v := arg.(type) { case int: buf += strconv.Itoa(v) @@ -85,7 +87,7 @@ func Sprintf(format string, args ...interface{}) string { default: buf += "(unhandled)" } - case 't': + case "t": switch v := arg.(type) { case bool: if v { diff --git a/examples/gno.land/p/demo/ufmt/ufmt_test.gno b/examples/gno.land/p/demo/ufmt/ufmt_test.gno index b9b02ec8af5..d60ccbb3e3e 100644 --- a/examples/gno.land/p/demo/ufmt/ufmt_test.gno +++ b/examples/gno.land/p/demo/ufmt/ufmt_test.gno @@ -38,6 +38,7 @@ func TestSprintf(t *testing.T) { {"no args", nil, "no args"}, {"finish with %", nil, "finish with %"}, {"stringer [%s]", []interface{}{stringer{}}, "stringer [I'm a stringer]"}, + {"Hello, World! ๐Ÿ˜Š", nil, "Hello, World! ๐Ÿ˜Š"}, } for _, tc := range cases { From 327c5553fa2d6762dfb7026bf169c380a7112a20 Mon Sep 17 00:00:00 2001 From: Malek Lahbib <111009238+MalekLahbib@users.noreply.github.com> Date: Thu, 4 Apr 2024 18:01:56 +0200 Subject: [PATCH 6/7] fix: ufmt doesn't display unicode emojis and others --- examples/gno.land/p/demo/todolist/gno.mod | 6 - .../gno.land/p/demo/todolist/todolist.gno | 68 ------- .../p/demo/todolist/todolist_test.gno | 51 ----- examples/gno.land/r/demo/todolist/gno.mod | 7 - .../gno.land/r/demo/todolist/todolist.gno | 179 ------------------ 5 files changed, 311 deletions(-) delete mode 100644 examples/gno.land/p/demo/todolist/gno.mod delete mode 100644 examples/gno.land/p/demo/todolist/todolist.gno delete mode 100644 examples/gno.land/p/demo/todolist/todolist_test.gno delete mode 100644 examples/gno.land/r/demo/todolist/gno.mod delete mode 100644 examples/gno.land/r/demo/todolist/todolist.gno diff --git a/examples/gno.land/p/demo/todolist/gno.mod b/examples/gno.land/p/demo/todolist/gno.mod deleted file mode 100644 index ffd0ed437e1..00000000000 --- a/examples/gno.land/p/demo/todolist/gno.mod +++ /dev/null @@ -1,6 +0,0 @@ -module gno.land/p/demo/todolist - -require ( - gno.land/p/demo/avl v0.0.0-latest - gno.land/p/demo/ufmt v0.0.0-latest -) diff --git a/examples/gno.land/p/demo/todolist/todolist.gno b/examples/gno.land/p/demo/todolist/todolist.gno deleted file mode 100644 index 5bde86896bc..00000000000 --- a/examples/gno.land/p/demo/todolist/todolist.gno +++ /dev/null @@ -1,68 +0,0 @@ -package todolist - -import ( - "std" - "strconv" - - "gno.land/p/demo/avl" - "gno.land/p/demo/ufmt" -) - -type TodoList struct { - Title string - Tasks avl.Tree - Owner std.Address -} - -type Task struct { - Title string - Done bool -} - -func NewTodoList(title string) *TodoList { - return &TodoList{ - Title: title, - Tasks: avl.Tree{}, - Owner: std.GetOrigCaller(), - } -} - -func NewTask(title string) *Task { - return &Task{ - Title: title, - Done: false, - } -} - -func (tl *TodoList) AddTask(id int, task *Task) { - tl.Tasks.Set(strconv.Itoa(id), task) -} - -func ToggleTaskStatus(task *Task) { - task.Done = !task.Done -} - -func (tl *TodoList) RemoveTask(taskId string) { - tl.Tasks.Remove(taskId) -} - -func (tl *TodoList) GetTasks() []*Task { - tasks := make([]*Task, 0, tl.Tasks.Size()) - tl.Tasks.Iterate("", "", func(key string, value interface{}) bool { - tasks = append(tasks, value.(*Task)) - return false - }) - return tasks -} - -func (tl *TodoList) String() string { - return ufmt.Sprintf("TodoList{Title: %q, Tasks: %v, Owner: %v}", tl.Title, tl.GetTasks(), tl.Owner) -} - -func (tl *TodoList) GetTodolistOwner() std.Address { - return tl.Owner -} - -func (tl *TodoList) GetTodolistTitle() string { - return tl.Title -} diff --git a/examples/gno.land/p/demo/todolist/todolist_test.gno b/examples/gno.land/p/demo/todolist/todolist_test.gno deleted file mode 100644 index 3193892bc28..00000000000 --- a/examples/gno.land/p/demo/todolist/todolist_test.gno +++ /dev/null @@ -1,51 +0,0 @@ -package todolist - -import ( - "testing" - - "gno.land/p/demo/avl" -) - -func TestTodolistNew(t *testing.T) { - newtl := &TodoList{ - Title: "new todolist", - Tasks: avl.Tree{}, - } - tl := NewTodoList("new todolist") - if tl.Title != newtl.Title { - t.Fatalf("title is not good") - } - if tl.Tasks != newtl.Tasks { - t.Fatalf("tasks not good") - } - - // test new task - newtask := &Task{ - Title: "new task", - Done: false, - } - nt := NewTask("new task") - if nt.Title != newtask.Title { - t.Fatalf("title is not good") - } - if nt.Done != newtask.Done { - t.Fatalf("done is not good") - } - - // test add a task - id := tl.Tasks.Size() - tl.AddTask(id, nt) - if tl.Tasks.Size() != 1 { - t.Fatalf("task not added") - } - - // test ToggleTaskStatus - task, exists := tl.Tasks.Get("0") - if !exists { - t.Fatalf("task not found") - } - ToggleTaskStatus(task.(*Task)) - if task.(*Task).Done != true { - t.Fatalf("task not toggled") - } -} diff --git a/examples/gno.land/r/demo/todolist/gno.mod b/examples/gno.land/r/demo/todolist/gno.mod deleted file mode 100644 index e23286a1402..00000000000 --- a/examples/gno.land/r/demo/todolist/gno.mod +++ /dev/null @@ -1,7 +0,0 @@ -module gno.land/r/demo/todolist - -require ( - gno.land/p/demo/avl v0.0.0-latest - gno.land/p/demo/todolist v0.0.0-latest - gno.land/p/demo/ufmt v0.0.0-latest -) diff --git a/examples/gno.land/r/demo/todolist/todolist.gno b/examples/gno.land/r/demo/todolist/todolist.gno deleted file mode 100644 index 1b309d87aca..00000000000 --- a/examples/gno.land/r/demo/todolist/todolist.gno +++ /dev/null @@ -1,179 +0,0 @@ -package todolist - -import ( - "bytes" - "strconv" - - "gno.land/p/demo/avl" - "gno.land/p/demo/todolist" - "gno.land/p/demo/ufmt" -) - -// State variables -var ( - todolistTree *avl.Tree - tlid int -) - -// Constructor -func init() { - todolistTree = avl.NewTree() -} - -func NewTodolist(title string) (int, string) { - // Create new Todolist - tl := todolist.NewTodoList(title) - // Update AVL tree with new state - todolistTree.Set(strconv.Itoa(tlid), tl) - tlid++ - return tlid - 1, "created successfully" -} - -func AddTask(todolistID int, title string) string { - // Get Todolist from AVL tree - tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) - if !ok { - return "Todolist not found" - } - - // get the number of tasks in the todolist - id := tl.(*todolist.TodoList).Tasks.Size() - - // create the task - task := todolist.NewTask(title) - - // Cast raw data from tree into Todolist struct - tl.(*todolist.TodoList).AddTask(id, task) - - return "task added successfully" -} - -func ToggleTaskStatus(todolistID int, taskID int) string { - // Get Todolist from AVL tree - tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) - if !ok { - return "Todolist not found" - } - - // Get the task from the todolist - task, found := tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) - if !found { - return "Task not found" - } - - // Change the status of the task - todolist.ToggleTaskStatus(task.(*todolist.Task)) - - return "task status changed successfully" -} - -func RemoveTask(todolistID int, taskID int) string { - // Get user who sent the transaction - // txSender := std.GetOrigCaller() - - // Get Todolist from AVL tree - tl, ok := todolistTree.Get(strconv.Itoa(todolistID)) - if !ok { - return "Todolist not found" - } - - // Get the task from the todolist - _, ok = tl.(*todolist.TodoList).Tasks.Get(strconv.Itoa(taskID)) - if !ok { - return "Task not found" - } - - // Change the status of the task - tl.(*todolist.TodoList).RemoveTask(strconv.Itoa(taskID)) - - return "task status changed successfully" -} - -func RemoveTodoList(todolistID int) string { - // Get user who sent the transaction - // txSender := std.GetOrigCaller() - - // Get Todolist from AVL tree - _, ok := todolistTree.Get(strconv.Itoa(todolistID)) - if !ok { - return "Todolist not found" - } - - // Remove the todolist - todolistTree.Remove(strconv.Itoa(todolistID)) - - return "Todolist removed successfully" -} - -func Render(path string) string { - if path == "" { - return renderHomepage() - } - - return "unknown page" -} - -func renderHomepage() string { - // Define empty buffer - var b bytes.Buffer - - b.WriteString("# Welcome to ToDolist\n\n") - - // If no todolists have been created - if todolistTree.Size() == 0 { - b.WriteString("### No todolists available currently!") - return b.String() - } - - // Iterate through AVL tree - todolistTree.Iterate("", "", func(key string, value interface{}) bool { - // cast raw data from tree into Todolist struct - tl := value.(*todolist.TodoList) - - // Add Todolist name - b.WriteString( - ufmt.Sprintf( - "## Todolist #%s: %s\n", - key, // Todolist ID - tl.GetTodolistTitle(), - ), - ) - - // Add Todolist owner - b.WriteString( - ufmt.Sprintf( - "#### Todolist owner : %s\n", - tl.GetTodolistOwner(), - ), - ) - - // List all todos that are currently Todolisted - if todos := tl.GetTasks(); len(todos) > 0 { - b.WriteString( - ufmt.Sprintf("Currently Todo tasks: %d\n\n", len(todos)), - ) - - for index, todo := range todos { - b.WriteString( - ufmt.Sprintf("#%d - %s ", index, todo.Title), - ) - if todo.Done { - b.WriteString( - "โ˜‘\n\n", - ) - } else { - b.WriteString( - "โ˜\n\n", - ) - } - } - } else { - b.WriteString("No tasks in this list currently\n") - } - - b.WriteString("\n") - return false - }) - - return b.String() -} From 398805a1fb5deb3691b51f97fbce1aed72b03379 Mon Sep 17 00:00:00 2001 From: Malek Lahbib <111009238+MalekLahbib@users.noreply.github.com> Date: Sat, 6 Apr 2024 15:04:07 +0200 Subject: [PATCH 7/7] adding other tests as suggested by @notJoon --- examples/gno.land/p/demo/ufmt/ufmt_test.gno | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/gno.land/p/demo/ufmt/ufmt_test.gno b/examples/gno.land/p/demo/ufmt/ufmt_test.gno index 1d9994e08bf..94d32372d30 100644 --- a/examples/gno.land/p/demo/ufmt/ufmt_test.gno +++ b/examples/gno.land/p/demo/ufmt/ufmt_test.gno @@ -38,7 +38,9 @@ func TestSprintf(t *testing.T) { {"no args", nil, "no args"}, {"finish with %", nil, "finish with %"}, {"stringer [%s]", []interface{}{stringer{}}, "stringer [I'm a stringer]"}, + {"รข", nil, "รข"}, {"Hello, World! ๐Ÿ˜Š", nil, "Hello, World! ๐Ÿ˜Š"}, + {"unicode formatting: %s", []interface{}{"๐Ÿ˜Š"}, "unicode formatting: ๐Ÿ˜Š"}, } for _, tc := range cases {