Implemented test for ZLEXCOUNT command handler

This commit is contained in:
Kelvin Clement Mwinuka
2024-02-20 03:39:13 +08:00
parent 6bb3c83758
commit 00c0fb5442
2 changed files with 141 additions and 10 deletions

View File

@@ -255,19 +255,20 @@ func handleZCOUNT(ctx context.Context, cmd []string, server utils.Server, conn *
} }
func handleZLEXCOUNT(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) { func handleZLEXCOUNT(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) {
if len(cmd) != 4 { keys, err := zlexcountKeyFunc(cmd)
return nil, errors.New(utils.WRONG_ARGS_RESPONSE) if err != nil {
return nil, err
} }
key := cmd[1] key := keys[0]
minimum := cmd[2] minimum := cmd[2]
maximum := cmd[3] maximum := cmd[3]
if !server.KeyExists(key) { if !server.KeyExists(key) {
return []byte("+(nil)\r\n\r\n"), nil return []byte(":0\r\n\r\n"), nil
} }
if _, err := server.KeyRLock(ctx, key); err != nil { if _, err = server.KeyRLock(ctx, key); err != nil {
return nil, err return nil, err
} }
defer server.KeyRUnlock(key) defer server.KeyRUnlock(key)
@@ -282,7 +283,7 @@ func handleZLEXCOUNT(ctx context.Context, cmd []string, server utils.Server, con
// Check if all members has the same score // Check if all members has the same score
for i := 0; i < len(members)-2; i++ { for i := 0; i < len(members)-2; i++ {
if members[i].score != members[i+1].score { if members[i].score != members[i+1].score {
return []byte("+(nil)\r\n\r\n"), nil return []byte(":0\r\n\r\n"), nil
} }
} }
@@ -1756,7 +1757,8 @@ The elements are ordered from lowest score to highest score`,
Command: "zlexcount", Command: "zlexcount",
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Description: `(ZLEXCOUNT key min max) Returns the number of elements in within the sorted set within the Description: `(ZLEXCOUNT key min max) Returns the number of elements in within the sorted set within the
lexicographical range between min and max`, lexicographical range between min and max. Returns 0, if the keys does not exist or if all the members do not have
the same score. If the value held at key is not a sorted set, an error is returned`,
Sync: false, Sync: false,
KeyExtractionFunc: zlexcountKeyFunc, KeyExtractionFunc: zlexcountKeyFunc,
HandlerFunc: handleZLEXCOUNT, HandlerFunc: handleZLEXCOUNT,

View File

@@ -271,7 +271,7 @@ func Test_HandleZCARD(t *testing.T) {
tests := []struct { tests := []struct {
preset bool preset bool
presetValue *SortedSet presetValue interface{}
key string key string
command []string command []string
expectedValue *SortedSet expectedValue *SortedSet
@@ -318,6 +318,15 @@ func Test_HandleZCARD(t *testing.T) {
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WRONG_ARGS_RESPONSE), expectedError: errors.New(utils.WRONG_ARGS_RESPONSE),
}, },
{ // 5. Return error when not a sorted set
preset: true,
presetValue: "Default value",
key: "key5",
command: []string{"ZCARD", "key5"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New("value at key5 is not a sorted set"),
},
} }
for _, test := range tests { for _, test := range tests {
@@ -354,7 +363,7 @@ func Test_HandleZCOUNT(t *testing.T) {
tests := []struct { tests := []struct {
preset bool preset bool
presetValue *SortedSet presetValue interface{}
key string key string
command []string command []string
expectedValue *SortedSet expectedValue *SortedSet
@@ -448,6 +457,15 @@ func Test_HandleZCOUNT(t *testing.T) {
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WRONG_ARGS_RESPONSE), expectedError: errors.New(utils.WRONG_ARGS_RESPONSE),
}, },
{ // 8. Throw error when value at the key is not a sorted set
preset: true,
presetValue: "Default value",
key: "key8",
command: []string{"ZCOUNT", "key8", "1", "10"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New("value at key8 is not a sorted set"),
},
} }
for _, test := range tests { for _, test := range tests {
@@ -479,7 +497,118 @@ func Test_HandleZCOUNT(t *testing.T) {
} }
} }
func Test_HandleZLEXCOUNT(t *testing.T) {} func Test_HandleZLEXCOUNT(t *testing.T) {
mockServer := server.NewServer(server.Opts{})
tests := []struct {
preset bool
presetValue interface{}
key string
command []string
expectedValue *SortedSet
expectedResponse int
expectedError error
}{
{ // 1. Get entire count using infinity boundaries
preset: true,
presetValue: NewSortedSet([]MemberParam{
{value: "e", score: Score(1)},
{value: "f", score: Score(1)},
{value: "g", score: Score(1)},
{value: "h", score: Score(1)},
{value: "i", score: Score(1)},
{value: "j", score: Score(1)},
{value: "k", score: Score(1)},
}),
key: "key1",
command: []string{"ZLEXCOUNT", "key1", "f", "j"},
expectedValue: nil,
expectedResponse: 5,
expectedError: nil,
},
{ // 2. Return 0 when the members do not have the same score
preset: true,
presetValue: NewSortedSet([]MemberParam{
{value: "a", score: Score(5.5)},
{value: "b", score: Score(67.77)},
{value: "c", score: Score(10)},
{value: "d", score: Score(1083.13)},
{value: "e", score: Score(11)},
{value: "f", score: Score(math.Inf(-1))},
{value: "g", score: Score(math.Inf(1))},
}),
key: "key2",
command: []string{"ZLEXCOUNT", "key2", "a", "b"},
expectedValue: nil,
expectedResponse: 0,
expectedError: nil,
},
{ // 3. Return 0 when the key does not exist
preset: false,
presetValue: nil,
key: "key3",
command: []string{"ZLEXCOUNT", "key3", "a", "z"},
expectedValue: nil,
expectedResponse: 0,
expectedError: nil,
},
{ // 4. Return error when the value at the key is not a sorted set
preset: true,
presetValue: "Default value",
key: "key4",
command: []string{"ZLEXCOUNT", "key4", "a", "z"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New("value at key4 is not a sorted set"),
},
{ // 5. Command is too short
preset: false,
presetValue: nil,
key: "key5",
command: []string{"ZLEXCOUNT"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New(utils.WRONG_ARGS_RESPONSE),
},
{ // 6. Command too long
preset: false,
presetValue: nil,
key: "key6",
command: []string{"ZLEXCOUNT", "key6", "min", "max", "count"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New(utils.WRONG_ARGS_RESPONSE),
},
}
for _, test := range tests {
if test.preset {
if _, err := mockServer.CreateKeyAndLock(context.Background(), test.key); err != nil {
t.Error(err)
}
mockServer.SetValue(context.Background(), test.key, test.presetValue)
mockServer.KeyUnlock(test.key)
}
res, err := handleZLEXCOUNT(context.Background(), test.command, mockServer, nil)
if test.expectedError != nil {
if err.Error() != test.expectedError.Error() {
t.Errorf("expected error \"%s\", got \"%s\"", test.expectedError.Error(), err.Error())
}
continue
}
if err != nil {
t.Error(err)
}
rd := resp.NewReader(bytes.NewReader(res))
rv, _, err := rd.ReadValue()
if err != nil {
t.Error(err)
}
if rv.Integer() != test.expectedResponse {
t.Errorf("expected response %d at key \"%s\", got %d", test.expectedResponse, test.key, rv.Integer())
}
}
}
func Test_HandleZDIFF(t *testing.T) {} func Test_HandleZDIFF(t *testing.T) {}