From 0549bcc745aa7ed8934da0720e1072953c1acd9c Mon Sep 17 00:00:00 2001 From: Kelvin Clement Mwinuka Date: Sun, 16 Jul 2023 01:28:26 +0800 Subject: [PATCH] Added tests for SET, GET, and MGET commands --- server/plugins/commands/setget/setget.go | 32 ++++------ server/plugins/commands/setget/setget_test.go | 59 +++++++++++++++++++ utils/mock.go | 14 ++--- 3 files changed, 77 insertions(+), 28 deletions(-) create mode 100644 server/plugins/commands/setget/setget_test.go diff --git a/server/plugins/commands/setget/setget.go b/server/plugins/commands/setget/setget.go index 3f66c9f..0090143 100644 --- a/server/plugins/commands/setget/setget.go +++ b/server/plugins/commands/setget/setget.go @@ -3,7 +3,6 @@ package main import ( "bufio" "fmt" - "strconv" "strings" "github.com/kelvinmwinuka/memstore/utils" @@ -67,15 +66,22 @@ func handleGet(cmd []string, s Server, conn *bufio.Writer) { case string: conn.Write([]byte(fmt.Sprintf("+%s\r\n\n", value))) case float64: - conn.Write([]byte(fmt.Sprintf("+%f\r\n\n", value))) + s := strings.TrimRight(fmt.Sprintf("%f", value), "0") + conn.Write([]byte(fmt.Sprintf("+%s\r\n\n", s))) case int: - conn.Write([]byte(fmt.Sprintf("+%d\r\n\n", value))) + conn.Write([]byte(fmt.Sprintf(":%d\r\n\n", value))) } conn.Flush() } func handleMGet(cmd []string, s Server, conn *bufio.Writer) { + if len(cmd) < 2 { + conn.Write([]byte("-Error wrong number of args for MGET command\r\n\n")) + conn.Flush() + return + } + vals := []string{} s.Lock() @@ -87,7 +93,7 @@ func handleMGet(cmd []string, s Server, conn *bufio.Writer) { case string: vals = append(vals, fmt.Sprintf("%s", s.GetData(key))) case float64: - vals = append(vals, fmt.Sprintf("%f", s.GetData(key))) + vals = append(vals, strings.TrimRight(fmt.Sprintf("%f", s.GetData(key)), "0")) case int: vals = append(vals, fmt.Sprintf("%d", s.GetData(key))) } @@ -110,26 +116,10 @@ func handleSet(cmd []string, s Server, conn *bufio.Writer) { default: conn.Write([]byte("-Error wrong number of args for SET command\r\n\n")) conn.Flush() - case x > 3: - s.Lock() - s.SetData(cmd[1], strings.Join(cmd[2:], " ")) - s.Unlock() - conn.Write([]byte("+OK\r\n")) case x == 3: - val, err := strconv.ParseFloat(cmd[2], 32) - s.Lock() - - if err != nil { - s.SetData(cmd[1], cmd[2]) - } else if !utils.IsInteger(val) { - s.SetData(cmd[1], val) - } else { - s.SetData(cmd[1], int(val)) - } - + s.SetData(cmd[1], utils.AdaptType(cmd[2])) s.Unlock() - conn.Write([]byte("+OK\r\n\n")) conn.Flush() } diff --git a/server/plugins/commands/setget/setget_test.go b/server/plugins/commands/setget/setget_test.go new file mode 100644 index 0000000..b17b0df --- /dev/null +++ b/server/plugins/commands/setget/setget_test.go @@ -0,0 +1,59 @@ +package main + +import ( + "bufio" + "strings" + "sync" + "testing" + + "github.com/kelvinmwinuka/memstore/utils" +) + +const ( + OK = "+OK\r\n\n" +) + +func TestHandleCommand(t *testing.T) { + server := utils.MockServer{ + Data: utils.MockData{ + Mu: sync.Mutex{}, + Data: make(map[string]interface{}), + }, + } + + cw := utils.CustomWriter{} + writer := bufio.NewWriter(&cw) + + tests := []struct { + cmd []string + expected string + }{ + // SET test cases + {[]string{"set", "key1", "value1"}, OK}, + {[]string{"set", "key2", "30"}, OK}, + {[]string{"set", "key3", "3.142"}, OK}, + {[]string{"set", "key4", "part1", "part2", "part3"}, "-Error wrong number of args for SET command\r\n\n"}, + {[]string{"set"}, "-Error wrong number of args for SET command\r\n\n"}, + + // GET test cases + {[]string{"get", "key1"}, "+value1\r\n\n"}, + {[]string{"get", "key2"}, ":30\r\n\n"}, + {[]string{"get", "key3"}, "+3.142\r\n\n"}, + {[]string{"get", "key4"}, "+nil\r\n\n"}, + {[]string{"get"}, "-Error wrong number of args for GET command\r\n\n"}, + {[]string{"get", "key1", "key2"}, "-Error wrong number of args for GET command\r\n\n"}, + + // MGET test cases + {[]string{"mget", "key1", "key2", "key3", "key4"}, "*4\r\n$6\r\nvalue1\r\n$2\r\n30\r\n$5\r\n3.142\r\n$3\r\nnil\r\n\n"}, + {[]string{"mget", "key5", "key6"}, "*2\r\n$3\r\nnil\r\n$3\r\nnil\r\n\n"}, + {[]string{"mget"}, "-Error wrong number of args for MGET command\r\n\n"}, + } + + for _, tt := range tests { + cw.Buf.Reset() + Plugin.HandleCommand(tt.cmd, &server, writer) + if tt.expected != cw.Buf.String() { + t.Errorf("Expected %s, Got %s", strings.TrimSpace(tt.expected), strings.TrimSpace(cw.Buf.String())) + } + } +} diff --git a/utils/mock.go b/utils/mock.go index 78ad178..0fc1c0d 100644 --- a/utils/mock.go +++ b/utils/mock.go @@ -26,26 +26,26 @@ func (cw *CustomWriter) Write(p []byte) (int, error) { } type MockData struct { - mu sync.Mutex - data map[string]interface{} + Mu sync.Mutex + Data map[string]interface{} } type MockServer struct { - data MockData + Data MockData } func (server *MockServer) Lock() { - server.data.mu.Lock() + server.Data.Mu.Lock() } func (server *MockServer) Unlock() { - server.data.mu.Unlock() + server.Data.Mu.Unlock() } func (server *MockServer) GetData(key string) interface{} { - return server.data.data[key] + return server.Data.Data[key] } func (server *MockServer) SetData(key string, value interface{}) { - server.data.data[key] = value + server.Data.Data[key] = value }