From d12b4b67a79af38bfa0f06329f60d5842c2070de Mon Sep 17 00:00:00 2001 From: Lee ByeongJun Date: Wed, 13 Mar 2024 22:48:35 +0900 Subject: [PATCH 1/2] feat(gno.land): add ufmt.Errorf --- examples/gno.land/p/demo/ufmt/ufmt.gno | 38 ++++++++++++++- examples/gno.land/p/demo/ufmt/ufmt_test.gno | 53 ++++++++++++++++++++- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/ufmt/ufmt.gno b/examples/gno.land/p/demo/ufmt/ufmt.gno index 0e6143d6ebd..29871e0b87e 100644 --- a/examples/gno.land/p/demo/ufmt/ufmt.gno +++ b/examples/gno.land/p/demo/ufmt/ufmt.gno @@ -3,7 +3,11 @@ // (hence the name µfmt - micro fmt). package ufmt -import "strconv" +import ( + "bytes" + "io" + "strconv" +) // Sprintf offers similar functionality to Go's fmt.Sprintf, or the sprintf // equivalent available in many languages, including C/C++. @@ -96,3 +100,35 @@ func Sprintf(format string, args ...interface{}) string { } return buf } + +// errMsg implements the error interface. +type errMsg struct { + msg string +} + +// Error defines the requirements of the error interface. +// It functions similarly to Go's errors.New() +func (e *errMsg) Error() string { + return e.msg +} + +// Errorf is a function that mirrors the functionality of fmt.Errorf. +// +// It takes a format string and arguments to create a formatted string, +// then sets this string as the 'msg' field of an errMsg struct and returns a pointer to this struct. +// +// This function operates in a similar manner to Go's fmt.Errorf, +// providing a way to create formatted error messages. +// +// The currently formatted verbs are the following: +// +// %s: places a string value directly. +// If the value implements the interface interface{ String() string }, +// the String() method is called to retrieve the value. +// %d: formats an integer value using package "strconv". +// Currently supports only uint, uint64, int, int64. +// %t: formats a boolean value to "true" or "false". +// %%: outputs a literal %. Does not consume an argument. +func Errorf(format string, args ...interface{}) error { + return &errMsg{Sprintf(format, args...)} +} diff --git a/examples/gno.land/p/demo/ufmt/ufmt_test.gno b/examples/gno.land/p/demo/ufmt/ufmt_test.gno index 07ba76c55b0..d821ba9fc92 100644 --- a/examples/gno.land/p/demo/ufmt/ufmt_test.gno +++ b/examples/gno.land/p/demo/ufmt/ufmt_test.gno @@ -1,7 +1,7 @@ package ufmt import ( - "fmt" + "bytes" "testing" ) @@ -35,7 +35,7 @@ func TestSprintf(t *testing.T) { } for _, tc := range cases { - name := fmt.Sprintf(tc.format, tc.values...) + name := Sprintf(tc.format, tc.values...) t.Run(name, func(t *testing.T) { got := Sprintf(tc.format, tc.values...) if got != tc.expectedOutput { @@ -44,3 +44,52 @@ func TestSprintf(t *testing.T) { }) } } + +func TestErrorf(t *testing.T) { + tests := []struct { + name string + format string + args []interface{} + expected string + }{ + { + name: "simple string", + format: "error: %s", + args: []interface{}{"something went wrong"}, + expected: "error: something went wrong", + }, + { + name: "integer value", + format: "value: %d", + args: []interface{}{42}, + expected: "value: 42", + }, + { + name: "boolean value", + format: "success: %t", + args: []interface{}{true}, + expected: "success: true", + }, + { + name: "multiple values", + format: "error %d: %s (success=%t)", + args: []interface{}{123, "failure occurred", false}, + expected: "error 123: failure occurred (success=false)", + }, + { + name: "literal percent", + format: "literal %%", + args: []interface{}{}, + expected: "literal %", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := Errorf(tt.format, tt.args...) + if err.Error() != tt.expected { + t.Errorf("Errorf(%q, %v) = %q, expected %q", tt.format, tt.args, err.Error(), tt.expected) + } + }) + } +} From a79823de3e3af9c29244d09283462d63ccd9a661 Mon Sep 17 00:00:00 2001 From: Morgan Date: Wed, 13 Mar 2024 22:04:33 +0100 Subject: [PATCH 2/2] Apply suggestions from code review --- examples/gno.land/p/demo/ufmt/ufmt.gno | 6 +----- examples/gno.land/p/demo/ufmt/ufmt_test.gno | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/examples/gno.land/p/demo/ufmt/ufmt.gno b/examples/gno.land/p/demo/ufmt/ufmt.gno index 29871e0b87e..f2917a45b9f 100644 --- a/examples/gno.land/p/demo/ufmt/ufmt.gno +++ b/examples/gno.land/p/demo/ufmt/ufmt.gno @@ -3,11 +3,7 @@ // (hence the name µfmt - micro fmt). package ufmt -import ( - "bytes" - "io" - "strconv" -) +import "strconv" // Sprintf offers similar functionality to Go's fmt.Sprintf, or the sprintf // equivalent available in many languages, including C/C++. diff --git a/examples/gno.land/p/demo/ufmt/ufmt_test.gno b/examples/gno.land/p/demo/ufmt/ufmt_test.gno index d821ba9fc92..be2fdb8bd73 100644 --- a/examples/gno.land/p/demo/ufmt/ufmt_test.gno +++ b/examples/gno.land/p/demo/ufmt/ufmt_test.gno @@ -1,7 +1,7 @@ package ufmt import ( - "bytes" + "fmt" "testing" ) @@ -35,7 +35,7 @@ func TestSprintf(t *testing.T) { } for _, tc := range cases { - name := Sprintf(tc.format, tc.values...) + name := fmt.Sprintf(tc.format, tc.values...) t.Run(name, func(t *testing.T) { got := Sprintf(tc.format, tc.values...) if got != tc.expectedOutput {