Repository: alicebob/miniredis (go)

Issue:
ZINTERSTORE does not store values if the destination is used in intersection
Redis behaviour:
```
redis> ZADD zset1 1 "one"
(integer) 1
redis> ZADD zset1 2 "two"
(integer) 1
redis> ZADD zset2 1 "one"
(integer) 1
redis> ZADD zset2 2 "two"
(integer) 1
redis> ZADD zset2 3 "three"
(integer) 1
redis> ZINTERSTORE zset1 2 zset1 zset2 WEIGHTS 2 3
(integer) 2
redis> ZRANGE zset1 0 -1 WITHSCORES
1) "one"
2) "5"
3) "two"
4) "10"
```
miniredis behaviour:
```
redis> ZADD zset1 1 "one"
(integer) 1
redis> ZADD zset1 2 "two"
(integer) 1
redis> ZADD zset2 1 "one"
(integer) 1
redis> ZADD zset2 2 "two"
(integer) 1
redis> ZADD zset2 3 "three"
(integer) 1
redis> ZINTERSTORE zset1 2 zset1 zset2 WEIGHTS 2 3
(integer) 0
redis> ZRANGE zset1 0 -1 WITHSCORES
(empty array)
```
As you can see, the INTERSTORE command does not store the intersected values into the destination `zset1`, if the destination was also used as one of the ZSTORE argumenets.

Pull request description:
fix ZINTERSTORE where target is one of the source sets
fixes #378

Patch:
diff --git a/cmd_sorted_set.go b/cmd_sorted_set.go
index ab943ad..e92c82a 100644
--- a/cmd_sorted_set.go
+++ b/cmd_sorted_set.go
@@ -433,9 +433,6 @@ func (m *Miniredis) makeCmdZinter(store bool) func(c *server.Peer, cmd string, a
 
 		withTx(m, c, func(c *server.Peer, ctx *connCtx) {
 			db := m.db(ctx.selectedDB)
-			if opts.Store {
-				db.del(opts.Destination, true)
-			}
 
 			// We collect everything and remove all keys which turned out not to be
 			// present in every set.
@@ -493,6 +490,7 @@ func (m *Miniredis) makeCmdZinter(store bool) func(c *server.Peer, cmd string, a
 
 			if opts.Store {
 				// ZINTERSTORE mode
+				db.del(opts.Destination, true)
 				db.ssetSet(opts.Destination, sset)
 				c.WriteInt(len(sset))
 				return


Test patch:
diff --git a/integration/sorted_set_test.go b/integration/sorted_set_test.go
index 60cc9c1..79ff45b 100644
--- a/integration/sorted_set_test.go
+++ b/integration/sorted_set_test.go
@@ -854,6 +854,11 @@ func TestZinter(t *testing.T) {
 		c.Do("ZINTERSTORE", "dest", "2", "q1", "q2")
 		c.Do("ZRANGE", "dest", "0", "-1", "withscores")
 
+		// store into self
+		c.Do("ZINTERSTORE", "q1", "2", "q1", "q2")
+		c.Do("ZRANGE", "q1", "0", "-1", "withscores")
+		c.Do("SMEMBERS", "q2")
+
 		// Error cases
 		c.Error("wrong number", "ZINTERSTORE")
 		c.Error("wrong number", "ZINTERSTORE", "h")