diff --git a/go/api/options/zcount_options.go b/go/api/options/zcount_options.go index 6e4d811190..1a79e8d9e9 100644 --- a/go/api/options/zcount_options.go +++ b/go/api/options/zcount_options.go @@ -44,7 +44,7 @@ type ScoreBoundary struct { } func NewScoreBoundaryBuilder() *ScoreBoundary { - return &ScoreBoundary{} + return &ScoreBoundary{isInclusive: true} } func (scoreBoundary *ScoreBoundary) SetBound(bound float64) *ScoreBoundary { diff --git a/go/api/sorted_set_commands.go b/go/api/sorted_set_commands.go index 50bb6f97ef..e77664390b 100644 --- a/go/api/sorted_set_commands.go +++ b/go/api/sorted_set_commands.go @@ -263,19 +263,31 @@ type SortedSetCommands interface { // [blocking commands]: https://github.com/valkey-io/valkey-glide/wiki/General-Concepts#blocking-commands BZPopMin(keys []string, timeoutSecs float64) (Result[KeyWithMemberAndScore], error) - // Returns the number of members in the sorted set stored at `key` with scores between `minScore` and `maxScore`. + // Returns the number of members in the sorted set stored at `key` with scores between `min` and `max` score. // // See [valkey.io] for details. // // Parameters: // key - The key of the set. - // minScore - The minimum score to count from. Can be positive/negative infinity, or specific score and inclusivity. - // maxScore - The maximum score to count up to. Can be positive/negative infinity, or specific score and inclusivity. + // rangeOptions - Contains `min` and `max` score. `min` contains the minimum score to count from. + // `max` contains the maximum score to count up to. Can be positive/negative infinity, or + // specific score and inclusivity. // // Return value: - // Result[int64] - The number of members in the specified score range. + // Result[int64] - The number of members in the specified score range. // // Example: + // key1 := uuid.NewString() + // membersScores := map[string]float64{"one": 1.0, "two": 2.0, "three": 3.0 } + // zAddResult, err := client.ZAdd(key1, membersScores) + // zCountRange := options.NewZCountRangeBuilder() + // zCountRange.SetMin(options.NewInfScoreBoundBuilder().SetValue(options.NegativeInfinity)) + // zCountRange.SetMax(options.NewInfScoreBoundBuilder().SetValue(options.PositiveInfinity)) + // zCountResult, err := client.ZCount(key1, zCountRange) + // if err!= nil { + // // Print err + // } + // fmt.Println(zCountResult.Value()) // Output: 3 // // [valkey.io]: https://valkey.io/commands/zcount/ ZCount(key string, rangeOptions *options.ZCountRange) (Result[int64], error) diff --git a/go/integTest/shared_commands_test.go b/go/integTest/shared_commands_test.go index c3b5a8c4cd..478cec6b3b 100644 --- a/go/integTest/shared_commands_test.go +++ b/go/integTest/shared_commands_test.go @@ -4488,7 +4488,7 @@ func (suite *GlideTestSuite) TestPersist() { func (suite *GlideTestSuite) TestZCount() { suite.runWithDefaultClients(func(client api.BaseClient) { key1 := uuid.NewString() - // key2 := uuid.NewString() + key2 := uuid.NewString() membersScores := map[string]float64{ "one": 1.0, "two": 2.0, @@ -4499,45 +4499,60 @@ func (suite *GlideTestSuite) TestZCount() { assert.Nil(t, err) assert.Equal(t, int64(3), res1.Value()) + // In range negative to positive infinity. zCountRange := options.NewZCountRangeBuilder() zCountRange.SetMin(options.NewInfScoreBoundBuilder().SetValue(options.NegativeInfinity)) zCountRange.SetMax(options.NewInfScoreBoundBuilder().SetValue(options.PositiveInfinity)) zCountResult, err := client.ZCount(key1, zCountRange) assert.Nil(t, err) assert.Equal(t, int64(3), zCountResult.Value()) + zCountRange = options.NewZCountRangeBuilder() + zCountRange.SetMin(options.NewScoreBoundaryBuilder().SetBound(math.Inf(-1))) + zCountRange.SetMax(options.NewScoreBoundaryBuilder().SetBound(math.Inf(+1))) + zCountResult, err = client.ZCount(key1, zCountRange) + assert.Nil(t, err) + assert.Equal(t, int64(3), zCountResult.Value()) + + // In range 1 (exclusive) to 3 (inclusive) + zCountRange = options.NewZCountRangeBuilder() + zCountRange.SetMin(options.NewScoreBoundaryBuilder().SetBound(1).SetIsInclusive(false)) + zCountRange.SetMax(options.NewScoreBoundaryBuilder().SetBound(3).SetIsInclusive(true)) + zCountResult, err = client.ZCount(key1, zCountRange) + assert.Nil(t, err) + assert.Equal(t, int64(2), zCountResult.Value()) + + // In range negative infinity to 3 (inclusive) + zCountRange = options.NewZCountRangeBuilder() + zCountRange.SetMin(options.NewInfScoreBoundBuilder().SetValue(options.NegativeInfinity)) + zCountRange.SetMax(options.NewScoreBoundaryBuilder().SetBound(3).SetIsInclusive(true)) + zCountResult, err = client.ZCount(key1, zCountRange) + assert.Nil(t, err) + assert.Equal(t, int64(3), zCountResult.Value()) + + // Incorrect range start > end + zCountRange = options.NewZCountRangeBuilder() + zCountRange.SetMin(options.NewInfScoreBoundBuilder().SetValue(options.PositiveInfinity)) + zCountRange.SetMax(options.NewScoreBoundaryBuilder().SetBound(3).SetIsInclusive(true)) + zCountResult, err = client.ZCount(key1, zCountRange) + assert.Nil(t, err) + assert.Equal(t, int64(0), zCountResult.Value()) + + // Non-existing key + zCountRange = options.NewZCountRangeBuilder() + zCountRange.SetMin(options.NewInfScoreBoundBuilder().SetValue(options.NegativeInfinity)) + zCountRange.SetMax(options.NewInfScoreBoundBuilder().SetValue(options.PositiveInfinity)) + zCountResult, err = client.ZCount("non_existing_key", zCountRange) + assert.Nil(t, err) + assert.Equal(t, int64(0), zCountResult.Value()) + + // Key exists, but it is not a set + setResult, err := client.Set(key2, "value") + assert.Equal(t, setResult.Value(), "OK") + zCountRange = options.NewZCountRangeBuilder() + zCountRange.SetMin(options.NewInfScoreBoundBuilder().SetValue(options.NegativeInfinity)) + zCountRange.SetMax(options.NewInfScoreBoundBuilder().SetValue(options.PositiveInfinity)) + zCountResult, err = client.ZCount(key2, zCountRange) + assert.NotNil(t, err) + assert.IsType(suite.T(), &api.RequestError{}, err) }) } - -// String key1 = UUID.randomUUID().toString(); -// String key2 = UUID.randomUUID().toString(); -// Map membersScores = Map.of("one", 1.0, "two", 2.0, "three", 3.0); -// assertEquals(3, client.zadd(key1, membersScores).get()); - -// // In range negative to positive infinity. -// assertEquals(3, client.zcount(key1, NEGATIVE_INFINITY, POSITIVE_INFINITY).get()); -/////////----Done -// assertEquals( -// 3, -// client -// .zcount( -// key1, -// new ScoreBoundary(Double.NEGATIVE_INFINITY), -// new ScoreBoundary(Double.POSITIVE_INFINITY)) -// .get()); -// // In range 1 (exclusive) to 3 (inclusive) -// assertEquals( -// 2, client.zcount(key1, new ScoreBoundary(1, false), new ScoreBoundary(3, true)).get()); -// // In range negative infinity to 3 (inclusive) -// assertEquals(3, client.zcount(key1, NEGATIVE_INFINITY, new ScoreBoundary(3, true)).get()); -// // Incorrect range start > end -// assertEquals(0, client.zcount(key1, POSITIVE_INFINITY, new ScoreBoundary(3, true)).get()); -// // Non-existing key -// assertEquals(0, client.zcount("non_existing_key", NEGATIVE_INFINITY, POSITIVE_INFINITY).get()); - -// // Key exists, but it is not a set -// assertEquals(OK, client.set(key2, "value").get()); -// ExecutionException executionException = -// assertThrows( -// ExecutionException.class, -// () -> client.zcount(key2, NEGATIVE_INFINITY, POSITIVE_INFINITY).get()); -// assertInstanceOf(RequestException.class, executionException.getCause());