Skip to content

Commit 26c1370

Browse files
committed
Add tests
1 parent ef62dd4 commit 26c1370

File tree

2 files changed

+151
-3
lines changed

2 files changed

+151
-3
lines changed

commands_test.go

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2659,7 +2659,6 @@ var _ = Describe("Commands", func() {
26592659
Expect(res).To(Equal([]int64{1, 1, -2}))
26602660
})
26612661

2662-
26632662
It("should HPExpire", Label("hash-expiration", "NonRedisEnterprise"), func() {
26642663
SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
26652664
res, err := client.HPExpire(ctx, "no_such_key", 10*time.Second, "field1", "field2", "field3").Result()
@@ -2812,6 +2811,155 @@ var _ = Describe("Commands", func() {
28122811
Expect(err).NotTo(HaveOccurred())
28132812
Expect(res[0]).To(BeNumerically("~", 10*time.Second.Milliseconds(), 1))
28142813
})
2814+
2815+
It("should HGETDEL", Label("hash", "HGETDEL"), func() {
2816+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2817+
// Setup: create a hash with three fields.
2818+
err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2", "f3", "val3").Err()
2819+
Expect(err).NotTo(HaveOccurred())
2820+
2821+
// Execute HGETDEL on fields f1 and f2.
2822+
res, err := client.HGetDel(ctx, "myhash", "f1", "f2").Result()
2823+
Expect(err).NotTo(HaveOccurred())
2824+
// Expect the returned values for f1 and f2.
2825+
Expect(res).To(Equal([]string{"val1", "val2"}))
2826+
2827+
// Verify that f1 and f2 have been deleted, while f3 remains.
2828+
remaining, err := client.HMGet(ctx, "myhash", "f1", "f2", "f3").Result()
2829+
Expect(err).NotTo(HaveOccurred())
2830+
Expect(remaining[0]).To(BeNil())
2831+
Expect(remaining[1]).To(BeNil())
2832+
Expect(remaining[2]).To(Equal("val3"))
2833+
})
2834+
2835+
It("should return nil responses for HGETDEL on non-existent key", Label("hash", "HGETDEL"), func() {
2836+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2837+
// HGETDEL on a key that does not exist.
2838+
res, err := client.HGetDel(ctx, "nonexistent", "f1", "f2").Result()
2839+
Expect(err).To(BeNil())
2840+
// Depending on your implementation, missing fields may return nil or empty strings.
2841+
// Adjust the expectation accordingly.
2842+
Expect(res).To(Equal([]string{"", ""}))
2843+
})
2844+
2845+
// -----------------------------
2846+
// HGETEX with various TTL options
2847+
// -----------------------------
2848+
It("should HGETEX with EX option", Label("hash", "HGETEX"), func() {
2849+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2850+
// Setup: create a hash.
2851+
err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2").Err()
2852+
Expect(err).NotTo(HaveOccurred())
2853+
2854+
// Call HGETEX with EX option and 60 seconds TTL.
2855+
res, err := client.HGetEXWithArgs(ctx, "myhash", redis.HGetEXExpirationEX, 60, "f1", "f2").Result()
2856+
Expect(err).NotTo(HaveOccurred())
2857+
Expect(res).To(Equal([]string{"val1", "val2"}))
2858+
// Optionally, verify TTL if your implementation exposes it.
2859+
})
2860+
2861+
It("should HGETEX with PERSIST option", Label("hash", "HGETEX"), func() {
2862+
SkipBeforeRedisVersion(8, "requires Redis 8.x")
2863+
// Setup: create a hash.
2864+
err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2").Err()
2865+
Expect(err).NotTo(HaveOccurred())
2866+
2867+
// Call HGETEX with PERSIST (no TTL value needed).
2868+
res, err := client.HGetEXWithArgs(ctx, "myhash", redis.HGetEXExpirationPERSIST, 0, "f1", "f2").Result()
2869+
Expect(err).NotTo(HaveOccurred())
2870+
Expect(res).To(Equal([]string{"val1", "val2"}))
2871+
})
2872+
2873+
It("should HGETEX with EXAT option", Label("hash", "HGETEX"), func() {
2874+
SkipBeforeRedisVersion(8, "requires Redis 8.x")
2875+
// Setup: create a hash.
2876+
err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2").Err()
2877+
Expect(err).NotTo(HaveOccurred())
2878+
2879+
// Set expiration at a specific Unix timestamp (60 seconds from now).
2880+
expireAt := time.Now().Add(60 * time.Second).Unix()
2881+
res, err := client.HGetEXWithArgs(ctx, "myhash", redis.HGetEXExpirationEXAT, expireAt, "f1", "f2").Result()
2882+
Expect(err).NotTo(HaveOccurred())
2883+
Expect(res).To(Equal([]string{"val1", "val2"}))
2884+
})
2885+
2886+
// -----------------------------
2887+
// HSETEX with FNX/FXX options
2888+
// -----------------------------
2889+
It("should HSETEX with FNX condition", Label("hash", "HSETEX"), func() {
2890+
SkipBeforeRedisVersion(8, "requires Redis 8.x")
2891+
// Ensure the key is removed.
2892+
client.Del(ctx, "myhash")
2893+
2894+
// FNX: set field only if it does not exist.
2895+
opt := redis.HSetXOptions{
2896+
Condition: redis.HSetEXFNX,
2897+
ExpirationType: redis.HSetEXExpirationEX,
2898+
ExpirationVal: 60,
2899+
}
2900+
res, err := client.HSetEXWithArgs(ctx, "myhash", &opt, "f1", "val1").Result()
2901+
Expect(err).NotTo(HaveOccurred())
2902+
// Expect the field to be set.
2903+
Expect(res).To(Equal(int64(1)))
2904+
2905+
opt = redis.HSetXOptions{
2906+
Condition: redis.HSetEXFNX,
2907+
ExpirationType: redis.HSetEXExpirationEX,
2908+
ExpirationVal: 60,
2909+
}
2910+
// Attempt to set the same field again with FNX.
2911+
res, err = client.HSetEXWithArgs(ctx, "myhash", &opt, "f1", "val2").Result()
2912+
Expect(err).NotTo(HaveOccurred())
2913+
// Since the field already exists, no update occurs.
2914+
Expect(res).To(Equal(int64(0)))
2915+
})
2916+
2917+
It("should HSETEX with FXX condition", Label("hash", "HSETEX"), func() {
2918+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2919+
// Setup: ensure field f2 exists.
2920+
client.Del(ctx, "myhash")
2921+
err := client.HSet(ctx, "myhash", "f2", "val1").Err()
2922+
Expect(err).NotTo(HaveOccurred())
2923+
2924+
opt := redis.HSetXOptions{
2925+
Condition: redis.HSetEXFXX,
2926+
ExpirationType: redis.HSetEXExpirationEX,
2927+
ExpirationVal: 60,
2928+
}
2929+
// FXX: update field only if it exists.
2930+
res, err := client.HSetEXWithArgs(ctx, "myhash", &opt, "f2", "val2").Result()
2931+
Expect(err).NotTo(HaveOccurred())
2932+
Expect(res).To(Equal(int64(1)))
2933+
opt = redis.HSetXOptions{
2934+
Condition: redis.HSetEXFXX,
2935+
ExpirationType: redis.HSetEXExpirationEX,
2936+
ExpirationVal: 60,
2937+
}
2938+
// FXX on a non-existing field (f3) should not set the field.
2939+
res, err = client.HSetEXWithArgs(ctx, "myhash", &opt, "f3", "val3").Result()
2940+
Expect(err).NotTo(HaveOccurred())
2941+
Expect(res).To(Equal(int64(0)))
2942+
})
2943+
2944+
It("should HSETEX with multiple field operations", Label("hash", "HSETEX"), func() {
2945+
SkipBeforeRedisVersion(8, "requires Redis 8.x")
2946+
// Remove key if it exists.
2947+
client.Del(ctx, "myhash")
2948+
opt := redis.HSetXOptions{
2949+
ExpirationType: redis.HSetEXExpirationEX,
2950+
ExpirationVal: 60,
2951+
}
2952+
// Set multiple fields at once (no condition).
2953+
res, err := client.HSetEXWithArgs(ctx, "myhash", &opt, "f1", "val1", "f2", "val2").Result()
2954+
Expect(err).NotTo(HaveOccurred())
2955+
// Assume 1 indicates all fields were set.
2956+
Expect(res).To(Equal(int64(1)))
2957+
2958+
// Verify that both fields are set.
2959+
values, err := client.HMGet(ctx, "myhash", "f1", "f2").Result()
2960+
Expect(err).NotTo(HaveOccurred())
2961+
Expect(values).To(Equal([]interface{}{"val1", "val2"}))
2962+
})
28152963
})
28162964

28172965
Describe("hyperloglog", func() {

hash_commands.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type HashCmdable interface {
2121
HSet(ctx context.Context, key string, values ...interface{}) *IntCmd
2222
HMSet(ctx context.Context, key string, values ...interface{}) *BoolCmd
2323
HSetEX(ctx context.Context, key string, fieldsAndValues ...string) *IntCmd
24-
HSetEXWithArgs(ctx context.Context, key string, options HSetXOptions, fieldsAndValues ...string) *IntCmd
24+
HSetEXWithArgs(ctx context.Context, key string, options *HSetXOptions, fieldsAndValues ...string) *IntCmd
2525
HSetNX(ctx context.Context, key, field string, value interface{}) *BoolCmd
2626
HScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
2727
HScanNoValues(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd
@@ -545,7 +545,7 @@ func (c cmdable) HSetEX(ctx context.Context, key string, fieldsAndValues ...stri
545545
return cmd
546546
}
547547

548-
func (c cmdable) HSetEXWithArgs(ctx context.Context, key string, options HSetXOptions, fieldsAndValues ...string) *IntCmd {
548+
func (c cmdable) HSetEXWithArgs(ctx context.Context, key string, options *HSetXOptions, fieldsAndValues ...string) *IntCmd {
549549
// Start with the command name and key.
550550
args := []interface{}{"HSETEX", key}
551551
if options.Condition != "" {

0 commit comments

Comments
 (0)