miniredis/cmd_geo_test.go
Wojciech Szarański 889458a92e Move create of client in tests to helper function
Removed duplicated code in tests using helper function.

Signed-off-by: Wojciech Szarański <wojciech.szaranski@gmail.com>
2024-03-27 19:55:20 +01:00

422 lines
10 KiB
Go

package miniredis
import (
"testing"
"github.com/alicebob/miniredis/v2/proto"
)
func TestGeoadd(t *testing.T) {
_, c := runWithClient(t)
t.Run("ok", func(t *testing.T) {
must1(t, c, "GEOADD", "Sicily", "13.361389", "38.115556", "Palermo")
must1(t, c, "GEOADD", "Sicily", "15.087269", "37.502669", "Catania")
})
t.Run("failure cases", func(t *testing.T) {
mustDo(t, c,
"GEOADD", "broken", "-190.0", "10.0", "hi",
proto.Error("ERR invalid longitude,latitude pair -190.000000,10.000000"),
)
mustDo(t, c,
"GEOADD", "broken", "190.0", "10.0", "hi",
proto.Error("ERR invalid longitude,latitude pair 190.000000,10.000000"),
)
mustDo(t, c,
"GEOADD", "broken", "10.0", "-86.0", "hi",
proto.Error("ERR invalid longitude,latitude pair 10.000000,-86.000000"),
)
mustDo(t, c,
"GEOADD", "broken", "10.0", "86.0", "hi",
proto.Error("ERR invalid longitude,latitude pair 10.000000,86.000000"),
)
mustDo(t, c,
"GEOADD", "broken", "notafloat", "10.0", "hi",
proto.Error("ERR value is not a valid float"),
)
mustDo(t, c,
"GEOADD", "broken", "10.0", "notafloat", "hi",
proto.Error("ERR value is not a valid float"),
)
})
}
func TestGeopos(t *testing.T) {
s, c := runWithClient(t)
must1(t, c, "GEOADD", "Sicily", "13.361389", "38.115556", "Palermo")
t.Run("ok", func(t *testing.T) {
mustDo(t, c,
"GEOPOS", "Sicily", "Palermo",
proto.Array(
proto.Strings("13.361389", "38.115556"),
),
)
})
t.Run("no location", func(t *testing.T) {
mustDo(t, c,
"GEOPOS", "Sicily", "Corleone",
proto.Array(proto.NilList),
)
})
t.Run("failure cases", func(t *testing.T) {
mustDo(t, c,
"GEOPOS",
proto.Error(errWrongNumber("geopos")),
)
s.Set("foo", "bar")
mustDo(t, c,
"GEOPOS", "foo",
proto.Error(msgWrongType),
)
})
}
// Test GEOADD / GEORADIUS / GEORADIUS_RO
func TestGeo(t *testing.T) {
_, c := runWithClient(t)
must1(t, c, "GEOADD", "Sicily", "13.361389", "38.115556", "Palermo")
must1(t, c, "GEOADD", "Sicily", "15.087269", "37.502669", "Catania")
t.Run("WITHDIST WITHCOORD", func(t *testing.T) {
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "WITHDIST", "WITHCOORD",
proto.Array(
proto.Array(
proto.String("Palermo"),
proto.String("190.4424"),
proto.Strings("13.361389", "38.115556"),
),
proto.Array(
proto.String("Catania"),
proto.String("56.4413"),
proto.Strings("15.087267", "37.502668"),
),
),
)
})
t.Run("WITHCOORD", func(t *testing.T) {
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "WITHCOORD",
proto.Array(
proto.Array(
proto.String("Palermo"),
proto.Strings("13.361389", "38.115556"),
),
proto.Array(
proto.String("Catania"),
proto.Strings("15.087267", "37.502668"),
),
),
)
})
t.Run("WITHDIST", func(t *testing.T) {
// in KM
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "WITHDIST",
proto.Array(
proto.Strings("Palermo", "190.4424"),
proto.Strings("Catania", "56.4413"),
),
)
// in meter
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200000", "m", "WITHDIST",
proto.Array(
proto.Strings("Palermo", "190442.4351"),
proto.Strings("Catania", "56441.2660"),
),
)
})
t.Run("ASC DESC", func(t *testing.T) {
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "ASC",
proto.Strings("Catania", "Palermo"),
)
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "DESC",
proto.Strings("Palermo", "Catania"),
)
})
t.Run("COUNT", func(t *testing.T) {
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "ASC", "COUNT", "1",
proto.Strings("Catania"),
)
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "ASC", "COUNT", "99",
proto.Strings("Catania", "Palermo"),
)
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "COUNT",
proto.Error("ERR syntax error"),
)
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "COUNT", "notanumber",
proto.Error(msgInvalidInt),
)
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km", "COUNT", "-12",
proto.Error("ERR COUNT must be > 0"),
)
})
t.Run("no args", func(t *testing.T) {
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "km",
proto.Strings("Palermo", "Catania"),
)
// Too small radius
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "1", "km",
proto.Array(),
)
// Wrong coords
mustDo(t, c,
"GEORADIUS", "Sicily", "80", "80", "200", "km",
proto.Array(),
)
// Wrong map key
mustDo(t, c,
"GEORADIUS", "Capri", "15", "37", "200", "km",
proto.Array(),
)
// Unsupported/unknown distance unit
mustDo(t, c,
"GEORADIUS", "Sicily", "15", "37", "200", "mm",
proto.Error("ERR wrong number of arguments for 'georadius' command"),
)
// Wrong parameter type
mustDo(t, c,
"GEORADIUS", "Sicily", "abc", "def", "ghi", "m",
proto.Error("ERR wrong number of arguments for 'georadius' command"),
)
})
t.Run("GEORADIUS_RO", func(t *testing.T) {
mustDo(t, c,
"GEORADIUS_RO", "Sicily", "15", "37", "200", "km", "ASC",
proto.Strings("Catania", "Palermo"),
)
mustDo(t, c,
"GEORADIUS_RO", "Sicily", "15", "37", "200", "km", "STORE", "foo",
proto.Error("ERR syntax error"),
)
mustDo(t, c,
"GEORADIUS_RO", "Sicily", "15", "37", "200", "km", "STOREDIST", "foo",
proto.Error("ERR syntax error"),
)
})
}
func TestGeodist(t *testing.T) {
_, c := runWithClient(t)
must1(t, c, "GEOADD", "Sicily", "13.361389", "38.115556", "Palermo")
must1(t, c, "GEOADD", "Sicily", "15.087269", "37.502669", "Catania")
t.Run("no unit", func(t *testing.T) {
mustDo(t, c,
"GEODIST", "Sicily", "Palermo", "Catania",
proto.String("166274.1514"),
)
mustDo(t, c,
"GEODIST", "Sicily", "Palermo", "Catania", "km",
proto.String("166.2742"),
)
})
t.Run("no such key", func(t *testing.T) {
mustNil(t, c, "GEODIST", "nosuch", "nosuch", "nosuch")
mustNil(t, c, "GEODIST", "Sicily", "Palermo", "nosuch")
mustNil(t, c, "GEODIST", "Sicily", "nosuch", "Catania")
})
t.Run("failure cases", func(t *testing.T) {
mustDo(t, c,
"GEODIST",
proto.Error(errWrongNumber("geodist")),
)
mustDo(t, c, "GEODIST", "Sicily",
proto.Error(errWrongNumber("geodist")),
)
mustDo(t, c, "GEODIST", "Sicily", "Palermo",
proto.Error(errWrongNumber("geodist")),
)
mustDo(t, c,
"GEODIST", "Sicily", "Palermo", "Catania", "miles",
proto.Error("ERR unsupported unit provided. please use M, KM, FT, MI"),
)
mustDo(t, c,
"GEODIST", "Sicily", "Palermo", "Catania", "m", "too many",
proto.Error("ERR syntax error"),
)
mustOK(t, c, "SET", "foo", "bar")
mustDo(t, c,
"GEODIST", "foo", "Palermo", "Catania",
proto.Error("WRONGTYPE Operation against a key holding the wrong kind of value"),
)
})
}
// Test GEOADD / GEORADIUSBYMEMBER / GEORADIUSBYMEMBER_RO
func TestGeobymember(t *testing.T) {
_, c := runWithClient(t)
must1(t, c, "GEOADD", "Sicily", "13.361389", "38.115556", "Palermo")
must1(t, c, "GEOADD", "Sicily", "15.087269", "37.502669", "Catania")
t.Run("WITHDIST WITHCOORD", func(t *testing.T) {
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "WITHDIST", "WITHCOORD",
proto.Array(
proto.Array(proto.String("Palermo"), proto.String("0.0000"), proto.Strings("13.361389", "38.115556")),
proto.Array(proto.String("Catania"), proto.String("166.2742"), proto.Strings("15.087267", "37.502668")),
),
)
})
t.Run("WITHCOORD", func(t *testing.T) {
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "WITHCOORD",
proto.Array(
proto.Array(proto.String("Palermo"), proto.Strings("13.361389", "38.115556")),
proto.Array(proto.String("Catania"), proto.Strings("15.087267", "37.502668")),
),
)
})
t.Run("WITHDIST", func(t *testing.T) {
// in km
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "WITHDIST",
proto.Array(
proto.Strings("Palermo", "0.0000"),
proto.Strings("Catania", "166.2742"),
),
)
// in meter
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200000", "m", "WITHDIST",
proto.Array(
proto.Strings("Palermo", "0.0000"),
proto.Strings("Catania", "166274.1514"), // in meter
),
)
})
t.Run("ASC DESC", func(t *testing.T) {
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "ASC",
proto.Strings("Palermo", "Catania"),
)
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Catania", "200", "km", "ASC",
proto.Strings("Catania", "Palermo"),
)
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "DESC",
proto.Strings("Catania", "Palermo"),
)
})
t.Run("COUNT", func(t *testing.T) {
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "ASC", "COUNT", "1",
proto.Strings("Palermo"),
)
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "ASC", "COUNT", "99",
proto.Strings("Palermo", "Catania"),
)
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "COUNT",
proto.Error("ERR syntax error"),
)
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "COUNT", "notanumber",
proto.Error(msgInvalidInt),
)
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km", "COUNT", "-12",
proto.Error("ERR COUNT must be > 0"),
)
})
t.Run("no args", func(t *testing.T) {
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "km",
proto.Strings("Palermo", "Catania"),
)
// Wrong map key
mustNil(t, c, "GEORADIUSBYMEMBER", "Capri", "Palermo", "200", "km")
// Missing member
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "nosuch", "200", "km",
proto.Error("ERR could not decode requested zset member"),
)
// Unsupported/unknown distance unit
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "Palermo", "200", "mm",
proto.Error("ERR wrong number of arguments for 'georadiusbymember' command"),
)
// Wrong parameter type
mustDo(t, c,
"GEORADIUSBYMEMBER", "Sicily", "abc", "def", "ghi", "m",
proto.Error("ERR wrong number of arguments for 'georadiusbymember' command"),
)
})
t.Run("GEORADIUSBYMEMBER_RO", func(t *testing.T) {
mustDo(t, c,
"GEORADIUSBYMEMBER_RO", "Sicily", "Palermo", "200", "km", "ASC",
proto.Strings("Palermo", "Catania"),
)
mustDo(t, c,
"GEORADIUSBYMEMBER_RO", "Sicily", "Palermo", "200", "km", "STORE", "foo",
proto.Error("ERR syntax error"),
)
mustDo(t, c,
"GEORADIUSBYMEMBER_RO", "Sicily", "Palermo", "200", "km", "STOREDIST", "foo",
proto.Error("ERR syntax error"),
)
})
}